ashiamd
V2EX  ›  问与答

想问个 Netty 的 EventLoopGroup 的 nThread 参数设置,线程数要配置多少才合适?

  •  
  •   ashiamd · Mar 24, 2020 · 4581 views
    This topic created in 2421 days ago, the information mentioned may be changed or developed.

    最近搞 netty 开发。由于是新手,之前没注意 EventLoopGroup 的 nThread 设定。之前都是直接 new NioEventLoopGroup()。 据说 EventLoopGroup 默认 nThread 为 CPU 内核数量 * 2 ; boss 线程组(管理连接监听的)一般只要 1 线程(或者也直接默认 CPU2 ),work 则使用默认 CPU2 就行。

    但是看到网上有个人 netty 代码里面用了各种高级 java 特性啥的,咋一看感觉高大上,然后发现他 boss 的 nThread 为 CPU 数量,work 则为 CPU*10,childChannel 的 EventLoopGroup 则是 handler 数量。

    上述设置有什么好处吗??我自己本地跑他这个代码(忘记哪里找的了),偷懒没用专业工具啥的。至少 1s 内同一个用户发送 3-4 次数据给服务器,和服务器交互,打印了 当前线程的 name,没看出来有用到多余的 Thread,一直用的同一个。感觉设置那么多线程有点迷惑行为的样子。但是自己比较菜,不敢下定论,望高手指点一下

    10 replies  •  2020-03-25 07:53:50 +08:00
    PDX
    PDX
    Mar 24, 2020 via iPhone❤️1
    1
    *2 就可以,关键还是别阻塞线程。
    MoHen9
    MoHen9
    Mar 24, 2020 via Android❤️1
    2
    channel 是绑定到某个线程上的,一般 UDP
    MoHen9
    MoHen9
    Mar 24, 2020 via Android❤️2
    3
    channel 是绑定到某个线程上的,UDP 是无连接状态,一个绑定端口只有一个 channel,所以只有一个线程,TCP 是一个连接一个线程,多个连接可以复用同一个线程。

    可以参考这个博客系列,学习一下源码:​aHR0cHMlM0EvL3NlZ21lbnRmYXVsdC5jb20vYS8xMTkwMDAwMDA3NDAzODczJTIzYXJ0aWNsZUhlYWRlcjI
    ashiamd
    ashiamd
    OP
    Mar 24, 2020
    4
    @MoHen9 之前有试过用 UDP 实现交互。但是本地 UDP 服务端和客户端可以交互。
    如果服务端放到远程服务器,客户端发包到远程服务器用 linux 指令可以检测到,但是服务器代码却没有读到这个包的样子。
    问一下如果用 UDP,是不是能像 TCP 一样获取到用户的通讯 IP,需不需要考虑什么客户端网络的 NAT 等问题?
    之前是 远程 linux 抓包有抓到客户端的包,但是程序却没收到?如果服务端放本地就可以在程序中收到客户端的 UDP 包。

    是不是单纯的我自己的代码可能逻辑有错?还是 UDP 需要考虑内网映射问题等?
    ashiamd
    ashiamd
    OP
    Mar 24, 2020
    5
    @ashiamd 好像涉及 UDP 打洞问题?之前我好像就是 UDP 卡在那个问题上,才转的 TCP
    MoHen9
    MoHen9
    Mar 24, 2020❤️1
    6
    @ashiamd 你的问题解决了吗?我觉得 Linux 可以收到 UDP 包,多半不是 NAT 的问题,我遇到过 docker 版本太低,导致 netty 收不到数据的问题,还有 spring 使用不当,把 netty 给阻塞住的问题,以及 netty 的 options 参数传的不对导致的问题,如果你还没有解决,可以传个 demo 到云盘或 github,我帮你看看
    ashiamd
    ashiamd
    OP
    Mar 25, 2020
    7
    @MoHen9 谢谢老哥,晚上看了点 UDP 的打洞文章等,了解了一下理论。然后把之前的 UDP 的丢服务器跑了一下。后面发现是 docker 用的网桥,UDP 包没有被转发到 docker 网桥网络里面,所以我就 docker-compose 指定了 network_mode: host 使用 host 模式,直接获取到服务器网卡 eth0 的 udp 包(监听发现抓到的 UDP 包都发到服务器的默认网卡 eth0 上了)。
    然后我本地 UDPclient 请求服务器,发现同一个 client 每次访问服务器的 IP 都是我家连接的宽带运营商的 IP,PORT 也一直是同一个。我用 4 个 Client 则 4 个 Client 的 NAT 的 IP 一样,就是端口不大一样,但是这个端口值没变动过就是了。

    4 个 client 定时每 3 秒发送 UDP 包-> server,然后 server 把这 4 个 client 的 IP 和 port 记录了,每次收到 UDP 包,就发送一段内容给服务器 HashMap 记录的所有 client (这里开 4 个 client ),也就是 4 个 client 每 3s 都会发送一个 UDP 包,接受到 4 个回复包(包括自己的这次)。

    其实我这里没有 P2P 的话,好像打不打洞的问题根本就不用考虑,毕竟服务器是公网 IP 。

    谢谢老哥了。话说老哥,可以把你前面提到的 “博客系列”重发一下链接吗?好像我这里看到就是一串普通的字符串“aHR0cHMlM0EvL3NlZ21lbnRmYXVsdC5jb20vYS8xMTkwMDAwMDA3NDAzODczJTIzYXJ0aWNsZUhlYWRlcjI”?
    ashiamd
    ashiamd
    OP
    Mar 25, 2020
    8
    @ashiamd 我这里就先简单测试了下,因为以前有次用 UDP 莫名收不到包。最近对 docker 和 linux 了解比较多了,所以找出问题倒是很快了。
    ashiamd
    ashiamd
    OP
    Mar 25, 2020
    9
    @ashiamd 我这里主要是想要后面做一个聊天室类型的东西,暂时打算先把群聊做出来就好了。私聊的话暂不考虑(而且私聊 P1<--->P2 其实不一定非得 P2P,直接服务器把 P1 的内容获取后再发送给 P2 也不是不行,就是比较折中了。但是实际私聊如果附带一些复杂操作,也不可能真的让 P1 直接和 P2 发包就完了,还是得服务器加工一些数据啥的,那还不如直接服务器发送给 P2 得了。)
    MoHen9
    MoHen9
    Mar 25, 2020 via Android❤️1
    10
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   4566 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 41ms · UTC 02:49 · PVG 10:49 · LAX 18:49 · JFK 21:49
    ♥ Do have faith in what you're doing.