這篇文章中的 plugin 主要講https://github.com/micro/micro 中的插件,主要用於自定義網關中如何加載插件。(如文章[micro auth jwt])git
go-micro中的插件請見https://github.com/micro/go-p...github
官方README中有一些介紹web
https://github.com/micro/micr...segmentfault
官方示例:app
在項目目錄建立plugin.goui
package main import ( "log" "github.com/micro/cli/v2" "github.com/micro/micro/v2/plugin" ) func init() { plugin.Register(plugin.NewPlugin( plugin.WithName("example"), plugin.WithFlag(cli.StringFlag{ Name: "example_flag", Usage: "This is an example plugin flag", EnvVars: []string{"EXAMPLE_FLAG"}, Value: "avalue", }), plugin.WithInit(func(ctx *cli.Context) error { log.Println("Got value for example_flag", ctx.String("example_flag")) return nil }), )) }
最後編譯url
`go build -o micro ./main.go ./plugin.go`插件
一步步看看是怎樣註冊的,在micro/plugin/manager.go中code
type manager struct { sync.Mutex plugins []Plugin registered map[string]bool } var ( // global plugin manager defaultManager = newManager() ) func newManager() *manager { return &manager{ registered: make(map[string]bool), } }
plugin包有默認`defaultManager = newManager()`,是一個manager{}對象router
再來看plugin.NewPlugin()
// NewPlugin makes it easy to create a new plugin func NewPlugin(opts ...Option) Plugin { return newPlugin(opts...) } func newPlugin(opts ...Option) Plugin { options := Options{ Name: "default", Init: func(ctx *cli.Context) error { return nil }, } for _, o := range opts { o(&options) } handler := func(hdlr http.Handler) http.Handler { for _, h := range options.Handlers { hdlr = h(hdlr) } return hdlr } return &plugin{ opts: options, handler: handler, } }
作了如下事情:
定義handler方法
初始化並返回plugin{}
plugin.WithHandler()
,例子放在最後)最後是外層的plugin.Register()
// Register registers a global plugins func Register(plugin Plugin) error { return defaultManager.Register(plugin) } func (m *manager) Register(plugin Plugin) error { m.Lock() defer m.Unlock() name := plugin.String() if m.registered[name] { return fmt.Errorf("Plugin with name %s already registered", name) } m.registered[name] = true m.plugins = append(m.plugins, plugin) return nil }
作了如下事情:
到這裏插件的註冊就完成了,那什麼是被調用的,怎麼生效的呢?
接下來看cmd.Init()
// Init initialised the command line func Init(options ...micro.Option) { Setup(cmd.App(), options...) cmd.Init( cmd.Name(name), cmd.Description(description), cmd.Version(buildVersion()), ) } func setup(app *ccli.App) { //無關內容略... plugins := plugin.Plugins() for _, p := range plugins { if flags := p.Flags(); len(flags) > 0 { app.Flags = append(app.Flags, flags...) } if cmds := p.Commands(); len(cmds) > 0 { app.Commands = append(app.Commands, cmds...) } } before := app.Before app.Before = func(ctx *ccli.Context) error { //無關內容略... for _, p := range plugins { if err := p.Init(ctx); err != nil { return err } } //無關內容略... } }
作了如下事情:
Init()
方法下面是一個有plugin.WithHandler()
的插件例子
package main import ( "net/http" "myauth/lib/token" log "github.com/micro/go-micro/v2/logger" "github.com/micro/micro/v2/cmd" "github.com/micro/micro/v2/plugin" ) func main() { tk := &token.Token{} tk.Init([]byte("key123456")) plugin.Register(plugin.NewPlugin( plugin.WithName("auth"), plugin.WithHandler( JWTAuthWrapper(tk), ), )) cmd.Init() } func JWTAuthWrapper(t *token.Token) plugin.Handler { return func(h http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { log.Info("===========", r.URL.Path) //不須要登陸的url地址 strings.HasPrefix(r.URL.Path, "/hello") || if r.URL.Path == "/myauth/Myauth/GetJwt" || r.URL.Path == "/myauth/Myauth/InspectJwt" { h.ServeHTTP(w, r) return } // tokenstr := r.Header.Get("Authorization")//如今不能夠用Authorization,須要用Bearer tokenstr := r.Header.Get("Bearer") log.Info("tokenstr", tokenstr) userFromToken, e := t.Decode(tokenstr) log.Info("userFromToken", userFromToken) if e != nil { _, _ = w.Write([]byte("unauthorized")) return } // r.Header.Set("X-Example-Username", userFromToken.UserName) h.ServeHTTP(w, r) return }) } }
這個例子是一個自定義micro網關,攔截請求檢查header中的jwt token信息
總結
go micro 分析系列文章
go micro server 啓動分析
go micro client
go micro broker
go micro cmd
go micro config
go micro store
go micro registry
go micro router
go micro runtime
go micro transport
go micro web
go micro registry 插件consul
go micro plugin
go micro jwt 網關鑑權
go micro 鏈路追蹤
go micro 熔斷與限流
go micro wrapper 中間件
go micro metrics 接入Prometheus、Grafana