V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
ashiamd
V2EX  ›  问与答

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

  •  
  •   ashiamd · 2020-03-24 05:02:54 +08:00 · 3383 次点击
    这是一个创建于 1690 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近搞 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 条回复    2020-03-25 07:53:50 +08:00
    PDX
        1
    PDX  
       2020-03-24 07:56:32 +08:00 via iPhone   ❤️ 1
    *2 就可以,关键还是别阻塞线程。
    MoHen9
        2
    MoHen9  
       2020-03-24 08:00:10 +08:00 via Android   ❤️ 1
    channel 是绑定到某个线程上的,一般 UDP
    MoHen9
        3
    MoHen9  
       2020-03-24 08:09:23 +08:00 via Android   ❤️ 2
    channel 是绑定到某个线程上的,UDP 是无连接状态,一个绑定端口只有一个 channel,所以只有一个线程,TCP 是一个连接一个线程,多个连接可以复用同一个线程。

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

    是不是单纯的我自己的代码可能逻辑有错?还是 UDP 需要考虑内网映射问题等?
    ashiamd
        5
    ashiamd  
    OP
       2020-03-24 18:46:14 +08:00
    @ashiamd 好像涉及 UDP 打洞问题?之前我好像就是 UDP 卡在那个问题上,才转的 TCP
    MoHen9
        6
    MoHen9  
       2020-03-24 20:28:19 +08:00   ❤️ 1
    @ashiamd 你的问题解决了吗?我觉得 Linux 可以收到 UDP 包,多半不是 NAT 的问题,我遇到过 docker 版本太低,导致 netty 收不到数据的问题,还有 spring 使用不当,把 netty 给阻塞住的问题,以及 netty 的 options 参数传的不对导致的问题,如果你还没有解决,可以传个 demo 到云盘或 github,我帮你看看
    ashiamd
        7
    ashiamd  
    OP
       2020-03-25 02:56:29 +08:00
    @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
        8
    ashiamd  
    OP
       2020-03-25 02:58:05 +08:00
    @ashiamd 我这里就先简单测试了下,因为以前有次用 UDP 莫名收不到包。最近对 docker 和 linux 了解比较多了,所以找出问题倒是很快了。
    ashiamd
        9
    ashiamd  
    OP
       2020-03-25 03:01:41 +08:00
    @ashiamd 我这里主要是想要后面做一个聊天室类型的东西,暂时打算先把群聊做出来就好了。私聊的话暂不考虑(而且私聊 P1<--->P2 其实不一定非得 P2P,直接服务器把 P1 的内容获取后再发送给 P2 也不是不行,就是比较折中了。但是实际私聊如果附带一些复杂操作,也不可能真的让 P1 直接和 P2 发包就完了,还是得服务器加工一些数据啥的,那还不如直接服务器发送给 P2 得了。)
    MoHen9
        10
    MoHen9  
       2020-03-25 07:53:50 +08:00 via Android   ❤️ 1
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2674 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 91ms · UTC 15:02 · PVG 23:02 · LAX 07:02 · JFK 10:02
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.