MOSN 源码阅读 - 运行Plugin

通过阅读 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 越来越强大。

你可能感兴趣的:(istio,Go,service,mesh)