Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

使用 go 1.24 编译 wasm 插件验证 #1768

Open
hanxiantao opened this issue Feb 15, 2025 · 8 comments
Open

使用 go 1.24 编译 wasm 插件验证 #1768

hanxiantao opened this issue Feb 15, 2025 · 8 comments
Assignees

Comments

@hanxiantao
Copy link
Collaborator

Why do you need it?

go 1.24 已发布,初步验证下原生 go 编译 wasm 插件的能力

https://github.com/proxy-wasm/proxy-wasm-go-sdk

How could it be?

Other related information

@hanxiantao
Copy link
Collaborator Author

验证方式

对 tinygo 和 go 1.24 编译的 Wasm 插件进行压测,分别设置并发数为 1、2、5,压测时长设定为 5 分钟,对比二者在各项性能指标上的表现。压测所使用的机器配置为 2C2G

本次验证使用 proxy-wasm-go-sdk 中提供的 http_body 示例

使用的 Envoy 版本如下:

tinygo go 1.24
Envoy 版本 higress/gateway:2.0.6 Envoy v1.33.0

这里 tinygo 的使用的是 higress 的 proxy-wasm-go-sdk,两者验证使用的 Envoy 版本也不一致,对验证结果会有一定影响,这里只作为初步验证使用

相关脚本

docker-compose.yaml

version: '3.7'
services:
  envoy:
    image: envoyproxy/envoy:v1.33.0
    entrypoint: /usr/local/bin/envoy
    command: -c /etc/envoy/envoy.yaml --component-log-level wasm:error
    networks:
      - wasmtest
    ports:
      - "18000:18000"
    volumes:
      - ./envoy.yaml:/etc/envoy/envoy.yaml
      - ./main.wasm:/etc/envoy/main.wasm
networks:
  wasmtest: {}

envoy.yaml 配置文件中 ./examples/http_body/main.wasm 替换为 /etc/envoy/main.wasm

编译命令:make build.example name=http_body

使用 wrk 进行压测,put_request.lua 脚本

request = function()
    return wrk.format("PUT", "/", {
        ["buffer-operation"] = "prepend",
        ["Connection"] = "keep-alive",
        ["Content-Type"] = "application/x-www-form-urlencoded"
    }, "[initial body]")
end

编译后 Wasm 文件大小对比

编译工具 编译后的 wasm 文件大小
tinygo 637.05 kB
go 1.24 2457.91 kB

go 1.24 编译后的文件大小为 2457.91 kB,约为 tinygo 编译后文件大小的四倍,体积较大

压测数据

并发数1

tinygo:

# wrk -t1 -c1 -d300s -s put_request.lua http://localhost:18000
Running 5m test @ http://localhost:18000
  1 threads and 1 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   685.49us  259.93us  10.37ms   99.43%
    Req/Sec     1.46k    32.06     1.51k    82.40%
  436637 requests in 5.00m, 112.85MB read
Requests/sec:   1455.32
Transfer/sec:    385.15KB

go 1.24:

# wrk -t1 -c1 -d300s -s put_request.lua http://localhost:18000
Running 5m test @ http://localhost:18000
  1 threads and 1 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   722.29us  260.41us   9.65ms   99.34%
    Req/Sec     1.39k    34.48     1.55k    89.70%
  414189 requests in 5.00m, 74.66MB read
Requests/sec:   1380.53
Transfer/sec:    254.81KB

tinygo 的平均延迟为 685.49us,go 1.24 为 722.29us,tinygo 的延迟略低

并发数2

tinygo:

# wrk -t2 -c2 -d300s -s put_request.lua http://localhost:18000
Running 5m test @ http://localhost:18000
  2 threads and 2 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     1.17ms  272.25us  11.38ms   99.37%
    Req/Sec     0.86k    23.94     0.97k    89.35%
  512374 requests in 5.00m, 132.42MB read
Requests/sec:   1707.73
Transfer/sec:    451.95KB

go 1.24:

# wrk -t2 -c2 -d300s -s put_request.lua http://localhost:18000
Running 5m test @ http://localhost:18000
  2 threads and 2 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     1.20ms  268.92us  10.90ms   99.39%
    Req/Sec   839.24     15.70     0.86k    91.81%
  501220 requests in 5.00m, 90.34MB read
Requests/sec:   1670.35
Transfer/sec:    308.30KB

tinygo 的平均延迟为 1.17ms,go 1.24 为 1.20ms,tinygo 的延迟仍稍低

并发数5

tinygo:

# wrk -t5 -c5 -d300s -s put_request.lua http://localhost:18000
Running 5m test @ http://localhost:18000
  5 threads and 5 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     1.84ms  288.03us  10.45ms   99.37%
    Req/Sec   544.61      9.80   560.00     91.39%
  813193 requests in 5.00m, 210.17MB read
Requests/sec:   2709.89
Transfer/sec:    717.17KB

go 1.24:

# wrk -t5 -c5 -d300s -s put_request.lua http://localhost:18000
Running 5m test @ http://localhost:18000
  5 threads and 5 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     2.33ms  338.20us  16.08ms   98.17%
    Req/Sec   430.95     13.37   505.00     90.18%
  643710 requests in 5.00m, 116.03MB read
Requests/sec:   2145.02
Transfer/sec:    395.91KB

tinygo 的平均延迟为 1.84ms,go 1.24 为 2.33ms,tinygo 的延迟优势更为明显

结论

综合来看,无论是在编译后的文件大小,还是在不同并发数下的性能指标(平均延迟、每秒请求数、每秒传输量)上,tinygo 编译的 Wasm 插件在本次压测中都表现出了一定优势

@hanxiantao hanxiantao self-assigned this Feb 15, 2025
@johnlanni
Copy link
Collaborator

可以再看下这个case,在插件里读取后端响应的随机字符的body,看看用go1.24是否不再有内存泄露问题:wasilibs/nottinygc#46

@pepesi
Copy link
Contributor

pepesi commented Feb 17, 2025

从这个情况看,我宁愿牺牲这点性能换取稳定😁

@pepesi
Copy link
Contributor

pepesi commented Feb 17, 2025

是否会存在过渡版本,让用户决策选择tinygo还是 golang原生版本的?

@hanxiantao
Copy link
Collaborator Author

是否会存在过渡版本,让用户决策选择tinygo还是 golang原生版本的?

这个可能还没这么快,等我这边有时间先验证下内存泄漏的问题,后面还涉及 higress proxy-wasm-go-sdk 升级,Envoy 端需要做一些改造。具体的计划等验证完再讨论下

@hanxiantao
Copy link
Collaborator Author

对比了下 wasilibs/nottinygc#46 提到的非 ASCII 响应体的场景,持续请求了 10 多个小时,使用 tinygo 和 go 1.24 编译 wasm 插件都未出现明显的内存泄漏情况

使用 tinygo 编译 wasm 插件

3月2日:

Image

3月3日:

Image

使用 go 1.24 编译 wasm 插件

3月2日:

Image

3月3日:

Image

@johnlanni
Copy link
Collaborator

可以用大一点的body试试,比如10mb,另外看上去这个case go1.24的性能反而更好?

@hanxiantao
Copy link
Collaborator Author

可以用大一点的body试试,比如10mb,另外看上去这个case go1.24的性能反而更好?

内存这个我再调大 body 试下,我目前用的 mac 上的 docker desktop,如果屏幕关掉容器会重启

这个 case 对比性能的话可能还是存在一定误差,因为用的 envoy 不是一个版本

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants