Golang Go语言中 websocket server 开启压缩内存占用高的问题

很多普通开发者, 甚至库的作者, 没有意识到 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 连接才能正常测试


Golang Go语言中 websocket server 开启压缩内存占用高的问题

更多关于Golang Go语言中 websocket server 开启压缩内存占用高的问题的实战教程也可以访问 https://www.itying.com/category-94-b0.html

11 回复

求问这一万个连接是怎么测试的?虚拟机? docker ?什么工具?

更多关于Golang Go语言中 websocket server 开启压缩内存占用高的问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


虚拟机, 工具是自己写的 https://go.dev/play/p/EUC4J0XY3Mr

在这个库的基础上改了点代码 https://github.com/lxzan/wsbench

websocket server 客户端直连?一般不是还有一个 http/https 网关吗,压缩放在网关上应该会有所不同?
或者 caddy 这种,给 http 开压缩也会有类似问题吗

同样好奇


这个问题是有解的,http 的流行度比 ws 高一个数量级,一般不会有问题。网关只会在握手阶段解析 http header ,websocket frame 的压缩它是不管的

网关解析完整的 ws 协议并压缩帧也可以做到,性能上会差一些,具体要看文档

websocket 压缩的问题比较突出,nhooyr 的内存占用是其他两个的 5-8 倍,gorilla 也有相关 issue ,不知道要怎么复现。

这个应该算是一个老问题了 https://github.com/golang/go/issues/32371

issue 太多了看不过来😂
nhooyr/websocket的作者意识到了这个问题, 然而他没去解决

在Golang中使用WebSocket服务器时,开启压缩功能确实可能会增加内存占用,这主要是因为压缩算法需要额外的内存来进行数据块的存储和处理。针对这一问题,可以考虑以下几个方向进行优化:

  1. 压缩级别调整:WebSocket的压缩通常使用Per-Message Deflate扩展,它允许配置压缩级别。降低压缩级别可以减少内存占用,但可能会增加传输的数据量。根据实际需求权衡压缩率和内存使用。

  2. 内存池使用:实现自定义的内存池来管理压缩和解压缩过程中所需的内存。这可以有效减少内存分配和回收的开销,提高内存使用效率。

  3. 流量控制:通过流量控制机制限制同时处理的WebSocket连接数或消息大小,避免内存过度消耗。

  4. 优化数据处理:检查并优化WebSocket消息处理逻辑,确保在处理压缩数据时不会造成不必要的内存泄漏或过度分配。

  5. 监控与调优:使用Go的pprof等工具监控内存使用情况,定位内存占用高的代码段,并针对性地进行优化。

  6. 硬件升级:如果以上方法仍不能满足需求,考虑增加服务器内存或采用更高规格的硬件资源。

总之,处理WebSocket压缩带来的内存占用问题需要从多个角度综合考虑,通过合理的配置和优化,可以在保证性能的同时有效控制内存使用。

回到顶部