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
物件的指標,方法內部對物件的修改會影響原始物件。
通常情況下,如果需要在方法內部修改接收者物件的狀態或屬性,應該使用指標接收者;如果不需要修改物件狀態,只是對物件進行操作,可以使用值接收者。根據具體需求選擇合適的接收者型別來定義方法。