go websocket server 开启压缩内存占用高的问题

2023-05-13 10:36:59 +08:00
 Nazz

很多普通开发者, 甚至库的作者, 没有意识到 flate 算法内存占用过高的问题, 一个压缩器, 占用内存超过了 640KB !!!

package main

import (
	"compress/flate"
	"unsafe"
)

func main() {
	writer, _ := flate.NewWriter(nil, flate.BestSpeed)
	println(unsafe.Sizeof(*writer))
}

// output: 656648

我测试了一下三个 websocket package, 10000 连接, 开启压缩, 10s 广播一次, 结果如下

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
  18563 caster    20   0 1340732 225504   4000 S   0.0   5.6  16:15.86 gws-linux-amd64
  18542 caster    20   0 1469756 351172   4912 S   0.0   8.8  25:17.99 gorilla-linux-a
  30294 caster    20   0 4791548   1.7g    880 S   0.0  44.6   0:07.33 nhooyr-linux-am

nhooyr降低到开 5000 连接才能正常测试

1724 次点击
所在节点    Go 编程语言
10 条回复
raw0xff
2023-05-13 11:39:11 +08:00
求问这一万个连接是怎么测试的?虚拟机? docker ?什么工具?
Nazz
2023-05-13 11:47:16 +08:00
@raw0xff 虚拟机, 工具是自己写的 https://go.dev/play/p/EUC4J0XY3Mr
Nazz
2023-05-13 11:48:35 +08:00
@raw0xff 在这个库的基础上改了点代码 https://github.com/lxzan/wsbench
1423
2023-05-13 13:04:56 +08:00
websocket server 客户端直连?一般不是还有一个 http/https 网关吗,压缩放在网关上应该会有所不同?
或者 caddy 这种,给 http 开压缩也会有类似问题吗
lankunblue
2023-05-13 13:10:31 +08:00
@1423 同样好奇
Nazz
2023-05-13 13:39:30 +08:00
@raw0xff
@1423 这个问题是有解的,http 的流行度比 ws 高一个数量级,一般不会有问题。网关只会在握手阶段解析 http header ,websocket frame 的压缩它是不管的
Nazz
2023-05-13 13:49:09 +08:00
@1423 网关解析完整的 ws 协议并压缩帧也可以做到,性能上会差一些,具体要看文档
Nazz
2023-05-13 13:56:53 +08:00
@lankunblue websocket 压缩的问题比较突出,nhooyr 的内存占用是其他两个的 5-8 倍,gorilla 也有相关 issue ,不知道要怎么复现。
mikespook
2023-05-14 09:19:20 +08:00
这个应该算是一个老问题了 https://github.com/golang/go/issues/32371
Nazz
2023-05-14 09:25:29 +08:00
@mikespook issue 太多了看不过来😂
`nhooyr/websocket`的作者意识到了这个问题, 然而他没去解决

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

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

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

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

© 2021 V2EX