go~wasm插件的開發(fa)
Go和TinyGo是兩(liang)種不同的Go語言編譯器,它們之間有以下幾點區(qu)別(bie):
-
目標平臺:
- 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代碼編譯為目標平臺的機器碼。
總的來(lai)說,Go適合構建通用(yong)(yong)計算(suan)機上(shang)的應用(yong)(yong)程序,而TinyGo則更適合用(yong)(yong)于嵌入式(shi)系(xi)統(tong)和物聯(lian)網(wang)設備(bei)等資源(yuan)受限的平臺(tai)。選擇使(shi)用(yong)(yong)哪種編譯器取(qu)決于你的目標平臺(tai)和需求。
github.com/alibaba/higress/plugins/wasm-go這個由阿里團隊開發的包,目前2024-03-01已經集成了redis,目前只在阿里mse上使用,不支持本地化使用,目前本地化envoy環境還不支持這個東西。
可關注(zhu)它的(de)sdk,github.com/higress-group/proxy-wasm-go-sdk,目前(qian)最新版是202402026號的(de),再更新后(hou),應該就支持了
沒有封裝的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 {
}
這句話(hua)的(de)(de)意思是(shi):當配置單條鏈接(jie)的(de)(de)buffer大小時(shi),這個配置會影響網關連接(jie)的(de)(de)吞吐(tu)量(即單位時(shi)間內處理的(de)(de)請求或數據量)和網關所使用的(de)(de)內存量。具體來說(shuo):
-
吞吐量影響:單條鏈接的(de)(de)buffer大小會(hui)直接影響數據在網(wang)關連接中的(de)(de)傳(chuan)輸(shu)(shu)速度(du)和(he)效(xiao)率。較大的(de)(de)buffer大小可(ke)能會(hui)提高數據傳(chuan)輸(shu)(shu)的(de)(de)速度(du),從而增加吞吐量(liang);而較小的(de)(de)buffer大小可(ke)能會(hui)導(dao)致數據傳(chuan)輸(shu)(shu)速度(du)變慢,降低吞吐量(liang)。
-
內存使用影響:配置單條鏈(lian)接的(de)buffer大小后(hou),會(hui)占用(yong)一(yi)定量(liang)的(de)內(nei)存空間來存儲這些(xie)buffer。如果(guo)buffer大小較(jiao)大,將會(hui)消耗更多的(de)內(nei)存資源(yuan);反之,如果(guo)buffer大小較(jiao)小,則消耗的(de)內(nei)存資源(yuan)也(ye)相(xiang)對(dui)較(jiao)少(shao)。因此,合理配置buffer大小可以平衡吞吐量(liang)和內(nei)存使用(yong)之間的(de)關系,以達到更好(hao)的(de)性能表現。
對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)
這兩(liang)個(ge)方法(fa)定義的區別在(zai)于(yu)它們的接收者(Receiver)不(bu)同:
-
func (config RedisConfig) BlackProcess(ctx wrapper.HttpContext, log wrapper.Log, val string, blackType string):這是一個針對RedisConfig類型值的方法,即使用值接收者。在調用該方法時,會對傳入的RedisConfig對(dui)(dui)象進(jin)行(xing)值拷貝,方法內部對(dui)(dui)對(dui)(dui)象的修改(gai)不會影響(xiang)原始(shi)對(dui)(dui)象。 -
func (config *RedisConfig) BlackProcess(ctx wrapper.HttpContext, log wrapper.Log, val string, blackType string):這是一個針對RedisConfig類型指針的方法,即使用指針接收者。在調用該方法時,會直接操作指向RedisConfig對象(xiang)的(de)指針,方法(fa)內部對對象(xiang)的(de)修改會影響原始對象(xiang)。
通常情(qing)況下,如果需要在方法(fa)內(nei)部(bu)修(xiu)改接收(shou)者(zhe)(zhe)(zhe)對象的狀(zhuang)(zhuang)態或屬性(xing),應該使用指(zhi)針接收(shou)者(zhe)(zhe)(zhe);如果不需要修(xiu)改對象狀(zhuang)(zhuang)態,只是(shi)對對象進行操作,可以使用值(zhi)接收(shou)者(zhe)(zhe)(zhe)。根(gen)據(ju)具體需求選(xuan)擇合適(shi)的接收(shou)者(zhe)(zhe)(zhe)類型(xing)來(lai)定義方法(fa)。