config 包

config 包利用 github.com/spf13/cobragithub.com/spf13/viper 实现了 Nirvana Command 和配置读取,为 Nirvana 服务启动提供了命令行支持。

NirvanaCommand 接口如下:

// NirvanaCommand is a nirvana command.
type NirvanaCommand interface {
    // EnablePlugin enables plugins.
    EnablePlugin(plugins ...Plugin) NirvanaCommand
    // AddOption will fill up options from flags/ENV/config after executing.
    // A non-empty prefix is recommended. It's used to divide option namespaces.
    AddOption(prefix string, options ...CustomOption) NirvanaCommand
    // Add adds a field by key.
    // If you don't have any struct to describe an option, you can use the method to
    // add a single field into nirvana command.
    // `pointer` must be a pointer to golang basic data type (e.g. *int, *string).
    // `key` must a config key. It's like 'nirvana.ip' and 'myconfig.name.firstName'.
    // The key will be converted to flag and env (e.g. --nirvana-ip and NIRVANA_IP).
    // If you want a short flag for the field, you can only set a one-char string.
    // `desc` describes the field.
    Add(pointer interface{}, key string, shortFlag string, desc string) NirvanaCommand
    // Execute runs nirvana server.
    Execute(descriptors ...definition.Descriptor) error
    // ExecuteWithConfig runs nirvana server from a custom config.
    ExecuteWithConfig(cfg *nirvana.Config) error
    // Command returns a command for command.
    Command(cfg *nirvana.Config) *cobra.Command
    // SetHook sets nirvana command hook.
    SetHook(hook NirvanaCommandHook)
    // Hook returns nirvana command hook.
    Hook() NirvanaCommandHook
}

NirvanaCommand 扩展了 nirvana 包的插件能力:

// CustomOption must be a pointer to struct.
//
// Here is an example:
//   type Option struct {
//       FirstName string `desc:"Desc for First Name"`
//       Age       uint16 `desc:"Desc for Age"`
//   }
// The struct has two fields (with prefix example):
//   Field       Flag                   ENV                  Key (In config file)
//   FirstName   --example-first-name   EXAMPLE_FIRST_NAME   example.firstName
//   Age         --example-age          EXAMPLE_AGE          example.age
// When you execute command with `--help`, you can see the help doc of flags and
// descriptions (From field tag `desc`).
//
// The priority is:
//   Flag > ENV > Key > The value you set in option
type CustomOption interface{}

// Plugin is for plugins to collect configurations
type Plugin interface {
    // Name returns plugin name.
    Name() string
    // Configure configures nirvana config via current options.
    Configure(cfg *nirvana.Config) error
}

Nirvana Command 要求每个插件提供一个 Option,并且实现 Plugin 接口。用户在 Comamnd 中传递 Option 来启用插件,并且将插件 Option 中的公开字段根据一定的规则(规则参考上面的注释)从 flag,环境变量,配置文件中读取。这样可以方便用户通过外部选项来改变运行时的行为。

由于 Nirvana Config 服务配置的特殊性,config 包提供了一个 Option 来表达这些配置:

// Option contains basic configurations of nirvana.
type Option struct {
    // IP is the IP to listen.
    IP string `desc:"Nirvana server listening IP"`
    // Port is the port to listen.
    Port uint16 `desc:"Nirvana server listening Port"`
    // Key is private key for HTTPS.
    Key string `desc:"TLS private key (PEM format) for HTTPS"`
    // Cert is certificate for HTTPS.
    Cert string `desc:"TLS certificate (PEM format) for HTTPS"`
}

除了插件 Option 以外,config 包会从以下文件列表中读取配置文件:

目录:
  ./
  ./config/
  {ExecutableFilePath}/
  {ExecutableFilePath}/config/
  /etc/nirvana/

配置文件名:
  nirvana.yaml
  nirvana.toml
  nirvana.json

如果读取到配置文件,那么除了使用 Option 接收配置以外,还可以通过一些帮助方法获取配置:

// IsSet checks to see if the key has been set in any of the data locations.
// IsSet is case-insensitive for a key
func IsSet(key string) bool

// Set sets the value for the key in the override regiser.
// Set is case-insensitive for a key.
// Will be used instead of values obtained via
// flags, config file, ENV, default, or key/value store.
func Set(key string, value interface{})

// Get can retrieve any value given the key to use.
// Get is case-insensitive for a key.
// Get has the behavior of returning the value associated with the first
// place from where it is set. Viper will check in the following order:
// override, flag, env, config file, key/value store, default
//
// Get returns an interface. For a specific value use one of the Get____ methods.
func Get(key string) interface{}

// GetBool returns the value associated with the key as a bool.
func GetBool(key string) bool

// GetDuration returns the value associated with the key as a time.Duration.
func GetDuration(key string) time.Duration

// GetFloat32 returns the value associated with the key as a float32.
func GetFloat32(key string) float32

// GetFloat64 returns the value associated with the key as a float64.
func GetFloat64(key string) float64

// GetInt returns the value associated with the key as a int.
func GetInt(key string) int

// GetInt8 returns the value associated with the key as a int.
func GetInt8(key string) int8

// GetInt16 returns the value associated with the key as a int.
func GetInt16(key string) int16

// GetInt32 returns the value associated with the key as a int32.
func GetInt32(key string) int32

// GetInt64 returns the value associated with the key as a int64.
func GetInt64(key string) int64

// GetString returns the value associated with the key as a string.
func GetString(key string) string

// GetStringSlice returns the value associated with the key as a []string.
func GetStringSlice(key string) []string

// GetUint returns the value associated with the key as a uint.
func GetUint(key string) uint

// GetUint8 returns the value associated with the key as a uint.
func GetUint8(key string) uint8

// GetUint16 returns the value associated with the key as a uint.
func GetUint16(key string) uint16

// GetUint32 returns the value associated with the key as a uint32.
func GetUint32(key string) uint32

// GetUint64 returns the value associated with the key as a uint64.
func GetUint64(key string) uint64

注:如果在 nirvana 包中对 Config 进行了扩展,涉及到字段的改变,也需要在这个包中修改 Option 和相应的功能。

results matching ""

    No results matching ""