V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
Nazz
V2EX  ›  Go 编程语言

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

  •  
  •   Nazz · 354 天前 · 1568 次点击
    这是一个创建于 354 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

    10 条回复    2023-05-14 09:25:29 +08:00
    raw0xff
        1
    raw0xff  
       354 天前
    求问这一万个连接是怎么测试的?虚拟机? docker ?什么工具?
    Nazz
        2
    Nazz  
    OP
       354 天前
    @raw0xff 虚拟机, 工具是自己写的 https://go.dev/play/p/EUC4J0XY3Mr
    Nazz
        3
    Nazz  
    OP
       354 天前
    @raw0xff 在这个库的基础上改了点代码 https://github.com/lxzan/wsbench
    1423
        4
    1423  
       354 天前
    websocket server 客户端直连?一般不是还有一个 http/https 网关吗,压缩放在网关上应该会有所不同?
    或者 caddy 这种,给 http 开压缩也会有类似问题吗
    lankunblue
        5
    lankunblue  
       354 天前
    @1423 同样好奇
    Nazz
        6
    Nazz  
    OP
       354 天前 via Android
    @raw0xff
    @1423 这个问题是有解的,http 的流行度比 ws 高一个数量级,一般不会有问题。网关只会在握手阶段解析 http header ,websocket frame 的压缩它是不管的
    Nazz
        7
    Nazz  
    OP
       354 天前 via Android
    @1423 网关解析完整的 ws 协议并压缩帧也可以做到,性能上会差一些,具体要看文档
    Nazz
        8
    Nazz  
    OP
       354 天前 via Android
    @lankunblue websocket 压缩的问题比较突出,nhooyr 的内存占用是其他两个的 5-8 倍,gorilla 也有相关 issue ,不知道要怎么复现。
    mikespook
        9
    mikespook  
       353 天前
    这个应该算是一个老问题了 https://github.com/golang/go/issues/32371
    Nazz
        10
    Nazz  
    OP
       353 天前
    @mikespook issue 太多了看不过来😂
    `nhooyr/websocket`的作者意识到了这个问题, 然而他没去解决
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1976 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 01:05 · PVG 09:05 · LAX 18:05 · JFK 21:05
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.