go~wasm插件的開發
Go和TinyGo是兩種不同的Go語言編譯器,它們之間有以下幾點區別:
-
目標平臺:
- Go:Go語言編譯器主要面向通用計算機平臺,如Windows、Linux、macOS等。
- TinyGo:TinyGo專注于支持嵌入式系統和物聯網設備等資源受限的平臺,如微控制器、嵌入式設備、WebAssembly等。
-
性能:
- Go:Go編譯器生成的可執行文件通常較大,運行速度較快,適合在通用計算機上運行。
- TinyGo:TinyGo針對嵌入式系統做了優化,生成的可執行文件更小,運行速度可能會受到一定影響,但更適合在資源受限的環境下運行。
-
語言特性支持:
- Go:Go語言擁有完整的標準庫和語言特性,適合構建各類應用程序。
- TinyGo:由于針對嵌入式系統,TinyGo對部分Go語言特性和標準庫進行了裁剪,不支持所有Go標準庫,但提供了適用于嵌入式系統的替代方案。
-
編譯器實現:
- Go:Go編譯器是使用Go語言本身實現的。
- TinyGo:TinyGo是一個基于LLVM的Go編譯器前端,通過LLVM將Go代碼編譯為目標平臺的機器碼。
總的來說,Go適合構建通用計算機上的應用程序,而TinyGo則更適合用于嵌入式系統和物聯網設備等資源受限的平臺。選擇使用哪種編譯器取決于你的目標平臺和需求。
github.com/alibaba/higress/plugins/wasm-go這個由阿里團隊開發的包,目前2024-03-01已經集成了redis,目前只在阿里mse上使用,不支持本地化使用,目前本地化envoy環境還不支持這個東西。
可關注它的sdk,github.com/higress-group/proxy-wasm-go-sdk,目前最新版是202402026號的,再更新后,應該就支持了
沒有封裝的redis命令,可以這樣使用
沒有的命令可以先用 Command(cmds []interface{}, callback RedisResponseCallback),通過 []interface{}{"set", "id", 1} 這種方式執行redis命令
重寫onHttpRequestBody之后需要設置請求體限制
- 當你需要接收請求體時,你需要將mse->參數配置->DownstreamConnectionBufferLimits,默認是32768 byte
- DownstreamConnectionBufferLimits:作用于網關連接,單條鏈接的buffer大小,配置后會影響吞吐和網關的內存使用
func onHttpRequestBody(ctx wrapper.HttpContext, config MyConfig, body []byte, log wrapper.Log) types.Action {
}
這句話的意思是:當配置單條鏈接的buffer大小時,這個配置會影響網關連接的吞吐量(即單位時間內處理的請求或數據量)和網關所使用的內存量。具體來說:
-
吞吐量影響:單條鏈接的buffer大小會直接影響數據在網關連接中的傳輸速度和效率。較大的buffer大小可能會提高數據傳輸的速度,從而增加吞吐量;而較小的buffer大小可能會導致數據傳輸速度變慢,降低吞吐量。
-
內存使用影響:配置單條鏈接的buffer大小后,會占用一定量的內存空間來存儲這些buffer。如果buffer大小較大,將會消耗更多的內存資源;反之,如果buffer大小較小,則消耗的內存資源也相對較少。因此,合理配置buffer大小可以平衡吞吐量和內存使用之間的關系,以達到更好的性能表現。
對return types.ActionPause的理解
- return types.ActionPause請求被阻塞后,通過proxywasm.ResumeHttpRequest()恢復執行,這樣其它插件(filter)可以繼續執行
- 當前方法中,如果return types.ActionPause后面還有其它代碼,這些代碼不會被執行,因為方法已經退出了
如下代碼,當eptid不為空時,執行了return types.ActionPause,及時它proxywasm.ResumeHttpRequest()了,那下面的代碼username這塊,也不會被執行
if eid != "" {
err := blackProcess(ctx, config, log, != "" {, BLACKLIST_EPTID)
if err != nil {
log.Errorf("blackProcess error while calling redis")
return types.ActionContinue
}
return types.ActionPause
}
if username != "" {
err := blackProcess(ctx, config, log, username, BLACKLIST_KCUSERNAME)
if err != nil {
log.Errorf("blackProcess error while calling redis")
return types.ActionContinue
}
return types.ActionPause
}
以下這兩個方法定義有什么區別
- func (config RedisConfig) BlackProcess(ctx wrapper.HttpContext, log wrapper.Log, val string, blackType string)
- func (config *RedisConfig) BlackProcess(ctx wrapper.HttpContext, log wrapper.Log, val string, blackType string)
這兩個方法定義的區別在于它們的接收者(Receiver)不同:
-
func (config RedisConfig) BlackProcess(ctx wrapper.HttpContext, log wrapper.Log, val string, blackType string):這是一個針對RedisConfig類型值的方法,即使用值接收者。在調用該方法時,會對傳入的RedisConfig對象進行值拷貝,方法內部對對象的修改不會影響原始對象。 -
func (config *RedisConfig) BlackProcess(ctx wrapper.HttpContext, log wrapper.Log, val string, blackType string):這是一個針對RedisConfig類型指針的方法,即使用指針接收者。在調用該方法時,會直接操作指向RedisConfig對象的指針,方法內部對對象的修改會影響原始對象。
通常情況下,如果需要在方法內部修改接收者對象的狀態或屬性,應該使用指針接收者;如果不需要修改對象狀態,只是對對象進行操作,可以使用值接收者。根據具體需求選擇合適的接收者類型來定義方法。
浙公網安備 33010602011771號