这篇文章中的 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