有必要在海量长连接场景使用第三方网络库吗?

查看 117|回复 8
作者:Nazz   
环境是 go1.20, 测了一下 6w websocket 连接, 每 10s 收发一条消息, 我发现第三方网络库内存占用可能会低一些, 但是 CPU 占用率上没表现出优势. 使用 std net, 如果活跃连接不多, 即使有海量连接也不会明显提高 CPU 占用率.

占用, 连接, CPU, 海量

lesismal   
6w 不算海量,连接数几十万上百万甚至两百万,差别就大了。
正常的业务也不至于每个连接上都是压测的场景、很高交互频率,普通业务的交互频率,逻辑代码本身需要的 cpu 不至于那么极端所以用标准库,这种逻辑代码本身的 cpu 需求也是够用。优化主要是为了:
1. 节省内存总量从而降低硬件总成本:一般中厂的业务量,比如 500w 连接数,用标准库单硬件 4/8c 8-16g ,稳定起见,单个节点处理 10-20w 连接,要部署 25-50 个节点。如果用其他方案,相同配置单个节点可以处理 100w 连接数,则5个节点就够用了。这是中厂业务,如果大厂、云基础设施,在线数、节点数量可比这大的多,能省下的成本也是不小。
2. 控制协程数量,降低调度成本:虽然 go 的调度很优秀了,但是比如百万个协程毕竟还是太多了
3. 控制对象数量,降低 gc 造成的 cpu 压力。上面说了,普通交互频率的逻辑代码 cpu 需求压力不大,但是对象数量巨大、gc 本身的消耗就很大,偶尔请求高一秒 stw 可能就比较明显了,还容易 cpu 尖刺
多数人需要处理的业务量级都不是特别大的,所以就用标准库足够了。
真正有大需求的,还是需要搞搞的。
Nazz
OP
  
@lesismal 六万也不少了,大部分公司都没这么多在线用户,标准网络库够用了,大厂才需要极端优化. 我测了好几个网络库, nbio 的内存占用是最优秀的,gws 内存占用比较高,看堆内存是因为读写都使用了 bufio.
Nazz
OP
  
性能要求非常高直接就上 c++/rust 了.
lesismal   
@Nazz 我最近都在琢磨,要不要单独弄个库,然后把 openssl cgo 弄到 nbio 里用,还有 nodejs 那个 c 的 httpparser 也弄进来,这样性能和内存都能再优化一波,并且如果不考虑兼容标准库 http 的话,性能也能做更大优化,但就不是 pure go 了。
需要不少工作量,我有点懒得动 :joy:
lesismal   
@Nazz c++/rust 性能强,但开发效率太低了,所以我才会有 #4 的想法,性能与开发效率兼得、性能和消耗的损失更小
Nazz
OP
  
@lesismal 没必要吧,cgo 性能损失很大,而且线上一般会用 nginx 做 tls
Nazz
OP
  
@Nazz 而且很多 gopher 会尽量避免使用依赖 cgo 的库,cgo 会给交叉编译带来麻烦,不能在 alpine 里运行
lesismal   
@Nazz 不涉及 syscall ,只是 buffer 传递、解析回调 /回传,这点跨语言栈之间的小结构体字段拷贝开销应该不会很大( buffer 强转避免大段 buffer 的跨语言栈拷贝)
您需要登录后才可以回帖 登录 | 立即注册

返回顶部