性能壓測對比:Golang vs Lua vs Was

本文將提供一個經典網關鑑權(basic auth)的性能壓測數據,希望能給大家一些參考。

需要說明的是,性能壓測是一門很深的學問,也是跟場景強相關的,不僅僅跟被壓測的場景有關,甚至跟運行時的系統環境也強相關。

本文並不旨在提供一個簡單粗暴的結論,也不希望通過極端場景來帶節奏,而是希望通過一個常見場景的數據,給大家一些相對客觀的體感,以及一些定性上的參考。

1 壓測場景

本次壓測,選了兩個插件場景,作爲對比來體現不同方案的性能消耗點

  1. Passthrough

    插件裏什麼事情也不做,目的是體現插件框架的基礎開銷

  2. Basic auth 鑑權

    這是一個比較簡單的場景,主要邏輯是,獲取請求頭,按照 basic auth 協議解析,主要是 base64 解碼操作,做用戶名 & 密碼匹配

2 插件實現方案

除了 Golang 擴展,也選了 Lua 和 Wasm 作爲對比,給大家一些參考

  1. Go 實現

    Go 代碼只有一份,不過我們壓測了 Go 1.20 和 1.21 rc 兩個版本,因爲 1.21 rc 裏包含了一個我們搞了一年多的 cgo 優化 這次我們也可以實際看看那個 cgo 優化的實際效果

  2. Lua 實現

    最開始只找了一個純 Lua 的 base64 decode 函數,不過發現性能不太好,又找了個可以被 JIT 的 decode 函數,所以也是兩個版本

  3. Wasm 實現

    基於 tetratelabs 開源的 proxy-wasm-go-sdk ,用 tinygo 來編譯

代碼實現:https://github.com/doujiang24/envoy-filter-benchmark/

值得一提的是,這些插件代碼,都只是簡單的複用了現成的代碼,並沒有經過特定的優化,主打的是快速實現。

3 壓測環境

機器:阿里雲 ecs.c7.large 機型,2 core CPU & 4 G memory

Envoy 版本:1.26.1

代理上游:Nginx,響應返回 Hello, world

壓測取值:CPU 打滿,QPS 極限值

統一使用 wrk 壓測,單獨的機器上執行

wrk -d 3 -t 4 -c 100 http://localhost:10000 -H 'Authorization: Basic Zm9vbmFtZTp2YWxpZHBhc3N3b3Jk'

如果有興趣的話,可以通過上面的代碼倉庫來複現壓測結論

4 壓測數據

SewZ9C

5 數據結論

  1. 從 Passthrough 的對比看,Lua 和 Wasm 的基礎消耗比 Golang 低

  2. 從 Basic auth 的對比看,Golang 的整體性能反超 Lua 和 Wasm

  3. 切換到可以 JIT 的 Lua 代碼,性能比 Golang 還好

  4. Golang 1.21 比 Golang 1.20 提升了 ~10%,cgo 優化效果確實是不錯的

申明:上面的這些絕對數字,意義都不是很大,不同的運行環境可能都會有不少的差距

  1. Go1.20 中 cgo 涉及到的系統調用,在不同的系統上,性能損耗是不太一樣的,有時候會有很大的出入

  2. Golang filter 的基礎開銷,也是跟系統相關的,之前壓測過其他的系統,沒有這麼大(20%+)

6 個人點評

Lua

Lua 確實很小巧,基礎開銷不高,很適合這種嵌入式的場景。

如果你的需求很簡單,又或者你對 Lua 代碼的優化比較擅長,比如善於利用 LuaJIT,用 Lua 來實現插件應該是不錯的

不過,通常來說,對於複雜的場景,要寫出性能好的 Lua 代碼,挑戰還是比較大的,甚至還需要搞些 C 代碼給 Lua 來調用

Golang

如果需求比較複雜,對於性能優化的奇技淫巧不太擅長,那麼用 Golang 來實現插件就是很合適的選擇

雖然,Golang 的基礎開銷要高一些,不過呢

  1. 在真實的場景裏,還會有一些其他的業務插件邏輯,相對來說,這些基礎開銷比例就不那麼高了

  2. 這些基礎開銷,我們也會持續優化,比如這次 Go 1.21 rc 效果就很明顯

通常情況下,我們的需求都會比 basic auth 要複雜的,甚至我們還可能有多個需求,如果都是用 Go 來實現,那麼這些基礎開銷,就會被分攤了。所以,複雜場景下,Go 的性能優勢會更加明顯。

Wasm

Wasm 的基礎開銷也不高,不過加上業務代碼,性能就不太好了,比純 Lua 還略差一點

或許是 tinygo 生成的 Wasm 不夠高效,沒有進一步分析了

7 最後

性能表現我們從一開始就很重視,也一直在優化,包括 Envoy Golang 自身的實現,以及 cgo 的優化。我們還有更多的優化在路上,或者在規劃中。

本次的性能壓測數據,只是披露了冰山一角,通常的性能壓測還會關心內存,延時等,本文沒有涉及,並不代表不重要。後續有時間,也會提供相關的壓測分析。

最後,我是這麼看待 Envoy Golang 的性能的:

  1. 眼下的性能,也是足夠好的了,雖然有相對較高的基礎開銷,但是整體性能還是不錯的

  2. 未來優化的空間是不小的,爭取基礎開銷能降低到 Lua / Wasm 一個水準

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/CzBaNbg2KZfqhvfTawOkwg