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

2023-04-09 10:48:49 +08:00
 Nazz

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

2511 次点击
所在节点    程序员
30 条回复
lesismal
2023-04-09 11:36:36 +08:00
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
2023-04-09 12:08:47 +08:00
@lesismal 六万也不少了,大部分公司都没这么多在线用户,标准网络库够用了,大厂才需要极端优化. 我测了好几个网络库, nbio 的内存占用是最优秀的,gws 内存占用比较高,看堆内存是因为读写都使用了 bufio.
Nazz
2023-04-09 12:15:37 +08:00
性能要求非常高直接就上 c++/rust 了.
lesismal
2023-04-09 12:56:22 +08:00
@Nazz 我最近都在琢磨,要不要单独弄个库,然后把 openssl cgo 弄到 nbio 里用,还有 nodejs 那个 c 的 httpparser 也弄进来,这样性能和内存都能再优化一波,并且如果不考虑兼容标准库 http 的话,性能也能做更大优化,但就不是 pure go 了。
需要不少工作量,我有点懒得动 :joy:
lesismal
2023-04-09 12:57:34 +08:00
@Nazz c++/rust 性能强,但开发效率太低了,所以我才会有 #4 的想法,性能与开发效率兼得、性能和消耗的损失更小
Nazz
2023-04-09 13:04:53 +08:00
@lesismal 没必要吧,cgo 性能损失很大,而且线上一般会用 nginx 做 tls
Nazz
2023-04-09 13:11:25 +08:00
@Nazz 而且很多 gopher 会尽量避免使用依赖 cgo 的库,cgo 会给交叉编译带来麻烦,不能在 alpine 里运行
lesismal
2023-04-09 13:16:26 +08:00
@Nazz 不涉及 syscall ,只是 buffer 传递、解析回调 /回传,这点跨语言栈之间的小结构体字段拷贝开销应该不会很大( buffer 强转避免大段 buffer 的跨语言栈拷贝)
lesismal
2023-04-09 13:52:08 +08:00
@Nazz cgo 以前只是用、没做过压测。刚试了下,确实拉垮,这下好了,我不用再惦记 #4 这事了 :joy:
Nazz
2023-04-09 14:15:45 +08:00
@lesismal 我也不用惦记着换网络库了, 标准库足够优秀.
godymho
2023-04-09 14:25:33 +08:00
@Nazz alpine 就是个大冤种镜像啊,需要的东西加完体积里面就上去了
Nazz
2023-04-09 14:28:54 +08:00
@godymho 一般只需要加时区.
artnowben
2023-04-09 21:11:54 +08:00
必要性不大,6K QPS 不算高,如果压力大了,可以先用四层负载均衡,后面带几个服务器,现在服务器的成本并不高,还是人力成本高。
四层负载均衡可以用:DPVS
四层负载均衡的性能测试可以用:dperf https://github.com/baidu/dperf
liuxu
2023-04-09 22:53:45 +08:00
这种情况不用 rust 来整,是真的徒增烦恼了,go 整完后面还是要用 rust 重构的
opengps
2023-04-10 07:48:23 +08:00
处理到位就行 ,没必要区分是否第三方
Nazz
2023-04-10 08:23:05 +08:00
@opengps 标准库能满足需求就没必要用第三方
Nazz
2023-04-10 08:25:48 +08:00
@opengps 毫无疑问标准网络库更加成熟稳定,更好的跨平台支持
opengps
2023-04-10 09:13:30 +08:00
@Nazz #16 看起来你已经有了答案,用第三方其实唯一需要判断的就是你是否信得过第三方
Nazz
2023-04-10 09:30:56 +08:00
@opengps 主要是我以前认知陷入了误区, 以为协程越多 CPU 使用率越高, 标准库撑不了多少连接.
opengps
2023-04-10 10:40:45 +08:00
@Nazz #19 不过有一点认知你还需要继续深入理解下:多连接容易造成启动成本耗时很大。
所以即使级单机做到了 6 万连接,实际依然建议低于一定的数值,我之前做的系统是按照每台 2 核 4G 机器承载 2 万连接的指标规划的。4 层负载均衡是做 tcp 长连接业务不可避免的选择。注意配合改好软件架构

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/930943

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX