跳转到主内容
极星编程网:以代码为星,赴技术山海!

为什么物联网长连接项目建议将count进程数设置为CPU核心数?

物联网长连接应采用事件驱动而非多进程模型;NioEventLoopGroup线程数默认设为2×CPU核心数,以平衡I/O等待与事件处理,避免CPU闲置。 因为长连接项目本质是I/O密集型,但“count进程数”设为CPU核心数,通常意味着你误用了进程模型去扛连接,而不是用事件驱动——这个配置本身就有问题,得先分清场景。 别把Netty的NioEventLoopGroup线程数和“count进程数”混为一谈 物联网长连接(如MQTT、CoAP、自定义TCP心跳)几乎全是I/O密集型:线程大部分时间在等网络数据到达,而非计算。这时候用多进程(比如用fork起多个worker进程)是低效的,尤其当连接数上万时,每个进程都带完整内存上下文,开销爆炸。 真正该关注的是:
NioEventLoopGroup
中
eventLoop
线程数,不是系统级进程数。它的默认值是
2 * CPU核心数
,原因很实在: 一个线程在等网络包时会阻塞在
epoll_wait
或
kqueue
,此时CPU空闲 另一个线程正好可以处理已就绪的读写事件,避免CPU闲置 乘以2是经验值,平衡了等待与处理,不是拍脑袋定的 如果你真在用多进程(比如Go的goroutine + fork,或Python的multiprocessing) 那“设为CPU核心数”只在极少数情况下合理: 每个进程内部是单线程+阻塞IO(比如老式PHP-FPM模型),且连接数不高( 你在做CPU密集型预处理(如解密、协议解析)并希望每个进程独占一个物理核 你明确禁用了超线程,且确认每个进程绑定到独立物理核(用
taskset
或
sched_setaffinity
) 否则,盲目设成CPU核心数只会导致: 连接数增长时,新连接排队等待accept,延迟飙升 进程间无法共享连接状态,心跳/重连逻辑变复杂 内存占用翻倍(每个进程都要加载TLS证书、协议栈、缓冲区) 真实项目里更常见的错误配置 很多团队看到“CPU核心数”就无脑套用,结果踩坑: 用Java写Netty服务,却把
NioEventLoopGroup(4)
硬编码成
Runtime.getRuntime().availableProcessors()
——在16核机器上只跑4个eventLoop,吞吐直接砍掉60% 用Node.js跑MQTT Broker,没调
UV_THREADPOOL_SIZE
,大量
fs.read
或
crypto.pbkdf2
阻塞主线程,导致ping响应超时 在MTK安卓主板上启多个Java进程处理4G模块AT指令,结果串口资源被抢占,
IOException: Device or resource busy
频发 关键不在“设多少”,而在“谁在等、等什么、能不能并发处理”。长连接的瓶颈从来不是CPU算力,而是内核socket队列长度、TIME_WAIT回收速度、以及应用层如何批量处理就绪事件——这些比纠结“进程数=核心数”重要得多。

相关文章