MOSN 源碼閱讀 - 運行Plugin

通過閱讀 MOSN 源碼解析 - Plugin 機制,知道了 MOSN 的插件機制,具體如何運行起來 examples/codes/plugin/pluginfilter 呢?

原理

閱讀文檔可以知道主要是 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 越來越強大。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章