micro/go-micro 介绍与源代码分析(二):命令行参数与 Option 机制

( micro/go-micro 本系列,是根据代码阅读顺序,边看边写,因此暂缺一篇工程目录文件综合性的介绍,最后补上)

Option 机制

micro/go-micro 代码中,可以通过 Option 来显式配置微服务属性,来达成:

  • 初始化微服务设置
  • 添加微服务某些功能(通过 Option 来传递 middleware )
  • 替换微服务某些功能(通过 Option 来替换插件)

具体例子,感性认识下:

func main() {
	service := micro.NewService(
		micro.Name("greeter"),                      // 这是个 Option 对象,设置微服务名称
		micro.WrapHandler(logWrapper),              // 这是个 Option 对象,添加一个自定义 log 中间件
		micro.Registry(kubernetes.NewRegistry()),   // 这是个 Option 对象,替换`服务发现`插件为 kubernetes
	)
	service.Init()
	if err := service.Run(); err != nil {
		fmt.Println(err)
	}
}

关于 Option 的实现细节,请参考: Golang 编程之装饰器模式

命令行参数

micro/go-micro 中,命令行参数是 Option 机制的补充,以方便在启动程序时,来配置微服务属性

micro/go-micro 中,命令行参数相关功能流程:

  • 初始化默认值
  • 解析命令行参数
  • 根据命令行参数,更新 Option 设置

下面代码分析解读下

0. 相关 Option 对象

摘自: https://github.com/micro/go-micro/blob/master/config/cmd/options.go , 并添加注释

type Options struct {
	// For the Command Line itself
	Name        string                                                        // Option Name 最终作用于这个字段
	Description string                                                        // Option Description 最终作用于这个字段
	Version     string                                                        // Option Version 最终作用于这个字段

	// We need pointers to things so we can swap them out if needed.
	Broker    *broker.Broker                                                  // Option Broker 最终作用于这个字段
	Registry  *registry.Registry                                              // Option Registry 最终作用于这个字段
	Selector  *selector.Selector                                              // Option Selector 最终作用于这个字段
	Transport *transport.Transport                                            // Option Transport 最终作用于这个字段
	Client    *client.Client                                                  // Option Client 最终作用于这个字段
	Server    *server.Server                                                  // Option Server 最终作用于这个字段  

    // 所有插件列表
	Brokers    map[string]func(...broker.Option) broker.Broker
	Clients    map[string]func(...client.Option) client.Client
	Registries map[string]func(...registry.Option) registry.Registry
	Selectors  map[string]func(...selector.Option) selector.Selector
	Servers    map[string]func(...server.Option) server.Server
	Transports map[string]func(...transport.Option) transport.Transport

	// Other options for implementations of the interface
	// can be stored in a context
	Context context.Context                                                   // 插件开发等第 3 方 Option 可以用这个存
}

// 下面是选项,需要注意,一些选项会对应多个命令行参数

// Command line Name
func Name(n string) Option {
	return func(o *Options) {
		o.Name = n
	}
}

// 类似`创建选项`代码 略
1. 初始化默认值

摘自: https://github.com/micro/go-micro/blob/master/config/cmd/cmd.go , 并添加注释

var (
	DefaultCmd = newCmd()

    // 设置命令行参数
	DefaultFlags = []cli.Flag{
		cli.StringFlag{
			Name:   "client",
			EnvVar: "MICRO_CLIENT",
			Usage:  "Client for go-micro; rpc",
		},
		// 类似命令行参数初始化代码 略
	}

    // 初始化内置插件列表
	DefaultBrokers = map[string]func(...broker.Option) broker.Broker{
		"http":   http.NewBroker,
		"memory": memory.NewBroker,
		"nats":   nats.NewBroker,
	}
    // 类似内置插件列表初始化代码 略
)

根据代码,汇总下目前所有命令行参数:

命令行参数 说明
client client 插件名称
client_request_timeout client 请求超时时间,缺省 5 秒
client_retries client 请求重试次数,缺省 1 次(某些服务发现插件,强调服务可用性,因此存在旧数据,会有可能导致把请求发至不可用的微服务实例上)
client_pool_size client 连接池大小,缺省 1 个连接
client_pool_ttl client 连接池中连接存活时间,缺省 1 分钟
register_ttl 服务发现组件中的节点存活时间
register_interval 服务发现组件中的节点多久刷新自己,来避免自己被 register_ttl 掉
server server 插件名称
server_name 微服务名
server_version 微服务版本号
server_id 微服务节点的节点ID。如果没设置, micro/go-micro 自动设置为 UUID
server_address 微服务服务地址。格式比如: 127.0.0.1:8080
server_advertise 微服务上报服务发现组件时,用的地址
server_metadata 微服务自身元数据,会上报给服务发现组件。是一个 key-value 列表,比如: --server_metadata color=red --server_metadata dc=sh
broker broker 插件名称
broker_address broker 服务器地址列表。比如: 127.0.0.1:8000,127.0.0.1:8001,127.0.0.1:8002
registry registry 插件名称
registry_address registry 服务器地址列表。比如: 127.0.0.1:8000,127.0.0.1:8001,127.0.0.1:8002
selector selector 插件名称
transport transport 插件名称
transport_address 目前代码中未用到该命令行参数!

根据代码,汇总下目前所有内置插件列表如下:

模块 内置插件列表 默认插件
client rpc 、 mucp 、 grpc rpc
server rpc 、 mucp 、 grpc rpc
broker http 、 memory 、 nats http
registry consul 、 gossip 、 mdns 、 memory mdns
selector default 、 dns 、 cache 、 static default( registry )
transport memory 、 http 、 grpc http

注意: codec 模块,未设置对应的命令行参数;不同的 client 、 server 模块,它们的默认codec 模块实现都可能不一样,因此,没有对应的命令行参数

2. 解析命令行参数

摘自: https://github.com/micro/go-micro/blob/master/config/cmd/cmd.go

func (c *cmd) Init(opts ...Option) error {
	for _, o := range opts {
		o(&c.opts)
	}
	c.app.Name = c.opts.Name
	c.app.Version = c.opts.Version
	c.app.HideVersion = len(c.opts.Version) == 0
	c.app.Usage = c.opts.Description
	c.app.RunAndExitOnError()
	return nil
}

micro/go-micro 使用了 micro/cli 库做命令行解析,这块细节可以跳过

3. 根据命令行参数,更新 Option 设置

摘自: https://github.com/micro/go-micro/blob/master/config/cmd/cmd.go

func (c *cmd) Before(ctx *cli.Context) error {
    // 代码略
}

一看就懂,细节略

其他

micro/go-micro 插件的可插拔机制,就是通过命令行参数来实现的

具体运用以下相关内容:

  • 命令行参数
  • 包导入自动注册
  • 工厂模式

细节请参考: Golang 编程之工厂模式

以上

发布了129 篇原创文章 · 获赞 73 · 访问量 16万+

猜你喜欢

转载自blog.csdn.net/u013272009/article/details/93382080