通過閱讀 MOSN 源碼解析 - Plugin 機制,知道了 MOSN
的插件機制,具體如何運行起來 examples/codes/plugin/pluginfilter
呢?
- 本文基於 commit id: 50c777ff,把示例插件加入到
MOSN
中。
原理
閱讀文檔可以知道主要是 MOSN
內部加載的 client
去調用 server
,其中 client
是通過
源碼:
func init() {
api.RegisterStream("pluginfilter", CreatePluginFilterFactory)
}
來註冊的,server
則是通過
func Register(name string, config *Config) (*Client, error)
來初始化客戶端的。
修改代碼
client
加入到 MOSN
通過查看代碼,可以很容易發現 client
註冊的時候實現如下接口
type StreamFilterChainFactory interface {
CreateFilterChain(context context.Context, callbacks StreamFilterChainFactoryCallbacks)
}
在 CreateFileChain
裏面調用 Register
來初始化 client
。
once.Do(func() {
var err error
// pluginfilter 是插件名稱,和下面編譯插件對應
client, err = plugin.Register("pluginfilter", nil)
if err != nil {
log.DefaultLogger.Errorf("plugin Register error: %v", err)
}
})
爲了方便調試,對 examples/codes/plugin/pluginfilter/pluginfilter.go
做了如下修改,打印日誌信息
82 body = response.GetBody()
83 if body != nil {
84 buf.Drain(buf.Len())
85 buf.Write(body)
86 }
+ 87 log.DefaultLogger.Infof("debug pluginfilter info") // 添加內容,打印一行日誌查看調用過程
88 }
89 return api.StreamFilterContinue
90 }
爲了把 pluginfilter
註冊進去,所以在 cmd/mosn/main/mosn.go 裏面的 import
添加
import (
......
_ "mosn.io/mosn/examples/codes/plugin/pluginfilter"
......
)
編譯
進入項目根目錄直接執行
插件
# champly @ champlydeiMac in ~/go/src/mosn.io/mosn on git:master x [10:30:06]
$ go build examples/codes/plugin/pluginfilter/server/pluginfilter.go
# champly @ champlydeiMac in ~/go/src/mosn.io/mosn on git:master x [10:30:38]
$ ll pluginfilter
-rwxr-xr-x 1 champly staff 23M 3 11 10:30 pluginfilter
- 如果名字不是
pluginfilter
要修改,因爲在代碼裏面寫死了的
MOSN
# champly @ champlydeiMac in ~/go/src/mosn.io/mosn on git:master x [10:32:28] C:1
$ go build -o mosn ./cmd/mosn/main
# champly @ champlydeiMac in ~/go/src/mosn.io/mosn on git:master x [10:32:35]
$ ll mosn
-rwxr-xr-x 1 champly staff 35M 3 11 10:32 mosn
修改配置文件
添加 plugin
日誌路徑
{
"plugin": {
"log_base": "/tmp/" // 這裏修改爲可以創建的路徑
}
.....
}
啓動一個程序使其監聽端口 2046
如 examples/codes/filter/commonrule/server.go,把 8080
修改爲 2046
然後運行
go run ./examples/codes/filter/commonrule/server.go
運行
# champly @ champlydeiMac in ~/go/src/mosn.io/mosn on git:master x [10:38:19]
$ ./mosn start -c ./examples/codes/plugin/pluginfilter/config.json
2020-03-11 10:38:20,902 [INFO] [router] [Extend] [RegisterRouterRule] order is 1
2020-03-11 10:38:20,903 [INFO] [router] [Extend] [RegisterHandlerChain] order is 1
2020-03-11 10:38:20,904 [INFO] [config] processor added to configParsedCBMaps
2020-03-11 10:38:20,905 [INFO] [network] [ register pool factory] register protocol: Http1 factory
2020-03-11 10:38:20,905 [INFO] [network] [ register pool factory] register protocol: Http2 factory
2020-03-11 10:38:20,905 [INFO] [network] [ register pool factory] register protocol: SofaRpc factory
2020-03-11 10:38:20,906 [INFO] [network] [ register pool factory] register protocol: X factory
2020/03/11 10:38:20 load config from : ./examples/codes/plugin/pluginfilter/config.json
2020-03-11 10:38:20,907 [INFO] [mosn] [init tracing] disbale tracing
2020-03-11 10:38:20,908 [INFO] [server] [reconfigure] not reconfigure: dial unix /Users/champly/go/src/mosn.io/mosn/examples/codes/plugin/pluginfilter/reconfig.sock: connect: no such file or directory
2020-03-11 10:38:20,908 [INFO] [mosn] [NewMosn] new mosn created
2020-03-11 10:38:20,908 [INFO] [cluster] [cluster manager] [AddOrUpdatePrimaryCluster] cluster clientCluster updated
2020-03-11 10:38:20,908 [INFO] [upstream] [host set] update host, final host total: 1
2020-03-11 10:38:20,908 [INFO] [cluster] [primaryCluster] [UpdateHosts] cluster clientCluster update hosts: 1
2020-03-11 10:38:20,908 [INFO] mosn start xds client
2020-03-11 10:38:20,908 [WARN] [feature gate] feature XdsMtlsEnable is not enabled
2020-03-11 10:38:20,908 [WARN] [feature gate] feature PayLoadLimitEnable is not enabled
2020-03-11 10:38:20,908 [WARN] [feature gate] feature MultiTenantMode is not enabled
2020-03-11 10:38:20,908 [INFO] mosn parse registry info
2020-03-11 10:38:20,908 [INFO] mosn prepare for start
2020-03-11 10:38:20,909 [INFO] mosn start server
2020-03-11 10:38:20,909 [INFO] [admin store] [start service] start service Mosn Admin Server on [::]:34901
通過 curl
請求 localhost:2045
$ curl localhost:2045
Method: GET
Protocol: HTTP/1.1
Host: localhost:2045
RemoteAddr: 127.0.0.1:64765
RequestURI: "/"
URL: &url.URL{Scheme:"", Opaque:"", User:(*url.Userinfo)(nil), Host:"", Path:"/", RawPath:"", ForceQuery:false, RawQuery:"", Fragment:""}
Body.ContentLength: 0 (-1 means unknown)
Close: false (relevant for HTTP/1 only)
TLS: (*tls.ConnectionState)(nil)
Headers:
Accept: */*
User-Agent: curl/7.54.0
查看剛纔配置的 plugin
路徑,裏面有一個 pluginfilter.log
文件,如果沒有應該是權限不對
2020-03-11 10:39:07,525 [INFO] filter header:8, body:0, trailer:0
這個內容是 server/pluginfilter.go 記錄的
然後查看 examples/codes/plugin/logs/mosn.log
會發現剛纔我們修改的信息
2020-03-11 10:39:07,526 [INFO] debug pluginfilter info
分析
通過上面的操作,已經把第三方插件運行起來了,插件如何能生效,在什麼地方生效呢?
查看配置文件
{
......
"stream_filters": [
{
"type": "pluginfilter"
}
]
......
}
stream_filters
是通過api.RegisterStream
註冊的filter_chains
是通過api.RegisterNetwork
註冊的
可以注入的位置,源碼
type StreamFilterChainFactoryCallbacks interface {
AddStreamSenderFilter(filter StreamSenderFilter)
AddStreamReceiverFilter(filter StreamReceiverFilter, p FilterPhase)
// add access log per stream
AddStreamAccessLog(accessLog AccessLog)
}
const (
BeforeRoute FilterPhase = iota
AfterRoute
)
總結
通過閱讀源碼學習了很多,希望 MOSN
越來越強大。