config

package
v1.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 30, 2023 License: Apache-2.0, BSD-2-Clause, BSD-3-Clause, + 2 more Imports: 14 Imported by: 7

README

English | 中文

Introduction

Configuration management plays an extremely important role in the microservices governance system. The tRPC framework provides a set of standard interfaces for business program development, supporting the retrieval of configuration from multiple data sources, parsing configuration, and perceiving configuration changes. The framework shields the details of data source docking, simplifying development. This article aims to provide users with the following information:

  • What is business configuration and how does it differ from framework configuration.
  • Some core concepts of business configuration such as: provider, codec, etc.
  • How to use standard interfaces to retrieve business configurations.
  • How to perceive changes in configuration items.

Concept

What is Business Configuration?

Business configuration refers to configuration used by the business, defined by the business program in terms of format, meaning, and parameter range. The tRPC framework does not use business configuration nor care about its meaning. The framework only focuses on how to retrieve configuration content, parse configuration, discover configuration changes, and notify the business program.

The difference between business configuration and framework configuration lies in the subject using the configuration and the management method. Framework configuration is used for tRPC framework and defined by the framework in terms of format and meaning. Framework configuration only supports local file reading mode and is read during program startup to initialize the framework. Framework configuration does not support dynamic updates; if the framework configuration needs to be updated, the program needs to be restarted.

On the other hand, business configuration supports retrieval from multiple data sources such as local files, configuration centers, databases, etc. If the data source supports configuration item event listening, tRPC framework provides a mechanism to achieve dynamic updating of configurations.

Managing Business Configuration

For managing business configuration, we recommend the best practice of using a configuration center. Using a configuration center has the following advantages:

  • Avoiding source code leaking sensitive information
  • Dynamically updating configurations for services
  • Allowing multiple services to share configurations and avoiding multiple copies of the same configuration
  • Supporting gray releases, configuration rollbacks, and having complete permission management and operation logs
  • Business configuration also supports local files. For local files, most use cases involve clients being used as independent tools or programs in the development and debugging phases. The advantage is that it can work without relying on an external system.

What is Multiple Data Sources?

A data source is the source from which configuration is retrieved and where it is stored. Common data sources include: file, etcd, configmap, etc. The tRPC framework supports setting different data sources for different business configurations. The framework uses a plugin-based approach to extend support for more data sources. In the implementation principle section later, we will describe in detail how the framework supports multiple data sources.

What is Codec?

In business configuration, Codec refers to the format of configurations retrieved from configuration sources. Common configuration file formats include: YAML, JSON, TOML, etc. The framework uses a plugin-based approach to extend support for more decoding formats.

Implementation Principle

To better understand the use of configuration interfaces and how to dock with data sources, let's take a brief look at how the configuration interface module is implemented. The following diagram is a schematic diagram of the configuration module implementation (not a code implementation class diagram):

trpc

The config interface in the diagram provides a standard interface for business code to retrieve configuration items, and each data type has an independent interface that supports returning default values.

We have already introduced Codec and DataProvider in section 2, and these two modules provide standard interfaces and registration functions to support plugin-based encoding/decoding and data source. Taking multi-data sources as an example, DataProvider provides the following three standard interfaces:

  • Read(): provides how to read the original data of the configuration (raw bytes).
  • Watch(): provides a callback function that the framework executes when the data source's data changes.
type DataProvider interface {
    Name() string
    Read(string) ([]byte, error)
    Watch(ProviderCallback)
}

Finally, let's see how to retrieve a business configuration by specifying the data source and decoder:

// Load etcd configuration file: config.WithProvider("etcd").
c, _ := config.Load("test.yaml", config.WithCodec("yaml"), config.WithProvider("etcd"))
// Read String type configuration.
c.GetString("auth.user", "admin")

In this example, the data source is the etcd configuration center, and the business configuration file in the data source is "test.yaml". When the ConfigLoader obtains the "test.yaml" business configuration, it specifies to use YAML format to decode the data content. Finally, the c.GetString("server.app", "default") function is used to obtain the value of the auth.user configuration item in the test.yaml file.

Interface Usage

This article only introduces the corresponding interfaces from the perspective of using business configurations. If users need to develop data source plugins or Codec plugins, please refer to tRPC-Go Development Configuration Plugin. For specific interface parameters, please refer to the tRPC-Go API manual.

The tRPC-Go framework provides two sets of interfaces for "reading configuration items" and "watching configuration item changes".

Reading Configuration Items

Step 1: Selecting Plugins

Before using the configuration interface, it is necessary to configure data source plugins and their configurations in advance. Please refer to the Plugin Ecology for plugin usage. The tRPC framework supports local file data sources by default.

Step 2: Plugin Initialization

Since the data source is implemented using a plugin, tRPC framework needs to initialize all plugins in the server initialization function by reading the "trpc_go.yaml" file. The read operation of business configuration must be carried out after completing trpc.NewServer().

import (
    trpc "trpc.group/trpc-go/trpc-go"
)
// Plugin system will be initialized when the server is instantiated, and all configuration read operations need to be performed after this.
trpc.NewServer()

Step 3: Loading Configuration Load configuration file from data source and return config data structure. The data source type and Codec format can be specified, with the framework defaulting to "file" data source and "YAML" Codec. The interface is defined as follows:

// Load configuration file: path is the path of the configuration file.
func Load(path string, opts ...LoadOption) (Config, error)
// Change Codec type, default is "YAML" format.
func WithCodec(name string) LoadOption
// Change data source, default is "file".
func WithProvider(name string) LoadOption

The sample code is as follows:

// Load etcd configuration file: config.WithProvider("etcd").
c, _ := config.Load("test1.yaml", config.WithCodec("yaml"), config.WithProvider("etcd"))
// Load local configuration file, codec is json, data source is file.
c, _ := config.Load("../testdata/auth.yaml", config.WithCodec("json"), config.WithProvider("file"))
// Load local configuration file, default Codec is yaml, data source is file.
c, _ := config.Load("../testdata/auth.yaml")

Step 4: Retrieving Configuration Items Get the value of a specific configuration item from the config data structure. Default values can be set, and the framework provides the following standard interfaces:

// Config general interface.
type Config interface {
    Load() error
    Reload()
    Get(string, interface{}) interface{}
    Unmarshal(interface{}) error
    IsSet(string) bool
    GetInt(string, int) int
    GetInt32(string, int32) int32
    GetInt64(string, int64) int64
    GetUint(string, uint) uint
    GetUint32(string, uint32) uint32
    GetUint64(string, uint64) uint64
    GetFloat32(string, float32) float32
    GetFloat64(string, float64) float64
    GetString(string, string) string
    GetBool(string, bool) bool
    Bytes() []byte
}

The sample code is as follows:

// Read bool type configuration.
c.GetBool("server.debug", false)
// Read String type configuration.
c.GetString("server.app", "default")

Watching configuration item changes

The framework provides a Watch mechanism for business programs to define and execute their own logic based on received configuration item change events in KV-type configuration centers. The monitoring interface is designed as follows:

// Get retrieves kvconfig by name.
func Get(name string) KVConfig

// KVConfig is the interface for KV configurations.
type KVConfig interface {
    KV
    Watcher
    Name() string
}

// Watcher is the interface for monitoring.
type Watcher interface {
    // Watch monitors the changes of the configuration item key.
    Watch(ctx context.Context, key string, opts ...Option) (<-chan Response, error)
}

// Response represents the response from the configuration center.
type Response interface {
    // Value gets the value corresponding to the configuration item.
    Value() string
    // MetaData provides additional metadata information.
    // Configuration Option options can be used to carry extra functionality implementation of different configuration centers, such as namespace, group, lease, etc.
    MetaData() map[string]string
    // Event gets the type of the Watch event.
    Event() EventType
}

// EventType represents the types of events monitored for configuration changes.
type EventType uint8
const (
    // EventTypeNull represents an empty event.
    EventTypeNull EventType = 0
    // EventTypePut represents a set or update configuration event.
    EventTypePut EventType = 1
    // EventTypeDel represents a delete configuration item event.
    EventTypeDel EventType = 2
)

The following example demonstrates how a business program monitors the "test.yaml" file on etcd, prints configuration item change events, and updates the configuration:

import (
    "sync/atomic"
    // ...
)
type yamlFile struct {
    Server struct {
        App string
    }
}
var cfg atomic.Value // Concurrent-safe Value.
// Listen to remote configuration changes on etcd using the Watch interface in trpc-go/config.
c, _ := config.Get("etcd").Watch(context.TODO(), "test.yaml")
go func() {
    for r := range c {
        yf := &yamlFile{}
        fmt.Printf("Event: %d, Value: %s", r.Event(), r.Value())
        if err := yaml.Unmarshal([]byte(r.Value()), yf); err == nil {
            cfg.Store(yf)
        }
    }
}()
// After the configuration is initialized, the latest configuration object can be obtained through the Load method of atomic.Value.
cfg.Load().(*yamlFile)

Data Source Integration

Refer to trpc-ecosystem/go-config-etcd.

Documentation

Overview

Package config provides common config interface.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrConfigNotExist is config not exist error
	ErrConfigNotExist = errors.New("trpc/config: config not exist")

	// ErrProviderNotExist is provider not exist error
	ErrProviderNotExist = errors.New("trpc/config: provider not exist")

	// ErrCodecNotExist is codec not exist error
	ErrCodecNotExist = errors.New("trpc/config: codec not exist")
)
View Source
var DefaultConfigLoader = newTrpcConfigLoad()

DefaultConfigLoader is the default config loader.

View Source
var ErrConfigNotSupport = errors.New("trpc/config: not support")

ErrConfigNotSupport is not supported config error

Functions

func GetInt

func GetInt(key string) (int, error)

GetInt returns int value get by key.

func GetIntWithDefault

func GetIntWithDefault(key string, def int) int

GetIntWithDefault returns int value get by key. If anything wrong, returns default value specified by input param def.

func GetJSON

func GetJSON(key string, val interface{}) error

GetJSON gets json data by key. The value will unmarshal into val parameter.

func GetJSONWithProvider

func GetJSONWithProvider(key string, val interface{}, provider string) error

GetJSONWithProvider gets json data by key. The value will unmarshal into val parameter the provider name is defined by provider parameter.

func GetString

func GetString(key string) (string, error)

GetString returns string value get from kv storage by key.

func GetStringWithDefault

func GetStringWithDefault(key, def string) string

GetStringWithDefault returns string value get by key. If anything wrong, returns default value specified by input param def.

func GetTOML

func GetTOML(key string, val interface{}) error

GetTOML gets toml data by key. The value will unmarshal into val parameter.

func GetTOMLWithProvider

func GetTOMLWithProvider(key string, val interface{}, provider string) error

GetTOMLWithProvider gets toml data by key. The value will unmarshal into val parameter the provider name is defined by provider parameter.

func GetWithUnmarshal

func GetWithUnmarshal(key string, val interface{}, unmarshalName string) error

GetWithUnmarshal gets the specific encoding data by key. the encoding type is defined by unmarshalName parameter.

func GetWithUnmarshalProvider

func GetWithUnmarshalProvider(key string, val interface{}, unmarshalName string, provider string) error

GetWithUnmarshalProvider gets the specific encoding data by key the encoding type is defined by unmarshalName parameter the provider name is defined by provider parameter.

func GetYAML

func GetYAML(key string, val interface{}) error

GetYAML gets yaml data by key. The value will unmarshal into val parameter.

func GetYAMLWithProvider

func GetYAMLWithProvider(key string, val interface{}, provider string) error

GetYAMLWithProvider gets yaml data by key. The value will unmarshal into val parameter the provider name is defined by provider parameter.

func Register

func Register(c KVConfig)

Register registers a kv config by its name.

func RegisterCodec

func RegisterCodec(c Codec)

RegisterCodec registers codec by its name.

func RegisterProvider

func RegisterProvider(p DataProvider)

RegisterProvider registers a data provider by its name.

func RegisterUnmarshaler

func RegisterUnmarshaler(name string, us Unmarshaler)

RegisterUnmarshaler registers an unmarshaler by name.

func Reload

func Reload(path string, opts ...LoadOption) error

Reload reloads config data.

func SetGlobalKV

func SetGlobalKV(kv KV)

SetGlobalKV sets the instance of kv config center.

Types

type Codec

type Codec interface {

	// Name returns codec's name.
	Name() string

	// Unmarshal deserializes the config data bytes into
	// the second input parameter.
	Unmarshal([]byte, interface{}) error
}

Codec defines codec interface.

func GetCodec

func GetCodec(name string) Codec

GetCodec returns the codec by name.

type Config

type Config interface {
	// Load loads config.
	Load() error

	// Reload reloads config.
	Reload()

	// Get returns config by key.
	Get(string, interface{}) interface{}

	// Unmarshal deserializes the config into input param.
	Unmarshal(interface{}) error

	// IsSet returns if the config specified by key exists.
	IsSet(string) bool

	// GetInt returns int value by key, the second parameter
	// is default value when key is absent or type conversion fails.
	GetInt(string, int) int

	// GetInt32 returns int32 value by key, the second parameter
	// is default value when key is absent or type conversion fails.
	GetInt32(string, int32) int32

	// GetInt64 returns int64 value by key, the second parameter
	// is default value when key is absent or type conversion fails.
	GetInt64(string, int64) int64

	// GetUint returns uint value by key, the second parameter
	// is default value when key is absent or type conversion fails.
	GetUint(string, uint) uint

	// GetUint32 returns uint32 value by key, the second parameter
	// is default value when key is absent or type conversion fails.
	GetUint32(string, uint32) uint32

	// GetUint64 returns uint64 value by key, the second parameter
	// is default value when key is absent or type conversion fails.
	GetUint64(string, uint64) uint64

	// GetFloat32 returns float32 value by key, the second parameter
	// is default value when key is absent or type conversion fails.
	GetFloat32(string, float32) float32

	// GetFloat64 returns float64 value by key, the second parameter
	// is default value when key is absent or type conversion fails.
	GetFloat64(string, float64) float64

	// GetString returns string value by key, the second parameter
	// is default value when key is absent or type conversion fails.
	GetString(string, string) string

	// GetBool returns bool value by key, the second parameter
	// is default value when key is absent or type conversion fails.
	GetBool(string, bool) bool

	// Bytes returns config data as bytes.
	Bytes() []byte
}

Config defines the common config interface. We can implement different config center by this interface.

func Load

func Load(path string, opts ...LoadOption) (Config, error)

Load returns the config specified by input parameter.

type DataProvider

type DataProvider interface {
	// Name returns the data provider's name.
	Name() string

	// Read reads the specific path file, returns
	// it content as bytes.
	Read(string) ([]byte, error)

	// Watch watches config changing. The change will
	// be handled by callback function.
	Watch(ProviderCallback)
}

DataProvider defines common data provider interface. we can implement this interface to define different data provider( such as file, TConf, ETCD, configmap) and parse config data to standard format( such as json, toml, yaml, etc.) by codec.

func GetProvider

func GetProvider(name string) DataProvider

GetProvider returns the provider by name.

type EventType

type EventType uint8

EventType defines the event type of config change.

const (
	// EventTypeNull represents null event.
	EventTypeNull EventType = 0

	// EventTypePut represents set or update config event.
	EventTypePut EventType = 1

	// EventTypeDel represents delete config event.
	EventTypeDel EventType = 2
)

type FileProvider

type FileProvider struct {
	// contains filtered or unexported fields
}

FileProvider is a config provider which gets config from file system.

func (*FileProvider) Name

func (*FileProvider) Name() string

Name returns file provider's name.

func (*FileProvider) Read

func (fp *FileProvider) Read(path string) ([]byte, error)

Read reads the specific path file, returns it content as bytes.

func (*FileProvider) Watch

func (fp *FileProvider) Watch(cb ProviderCallback)

Watch watches config changing. The change will be handled by callback function.

type JSONCodec

type JSONCodec struct{}

JSONCodec is json codec.

func (*JSONCodec) Name

func (*JSONCodec) Name() string

Name returns json codec's name.

func (*JSONCodec) Unmarshal

func (c *JSONCodec) Unmarshal(in []byte, out interface{}) error

Unmarshal deserializes the in bytes into out parameter by json.

type JSONUnmarshaler

type JSONUnmarshaler struct{}

JSONUnmarshaler is json unmarshaler.

func (*JSONUnmarshaler) Unmarshal

func (ju *JSONUnmarshaler) Unmarshal(data []byte, val interface{}) error

Unmarshal deserializes the data bytes into parameter val in json protocol.

type KV

type KV interface {
	// Put puts or updates config value by key.
	Put(ctx context.Context, key, val string, opts ...Option) error

	// Get returns config value by key.
	Get(ctx context.Context, key string, opts ...Option) (Response, error)

	// Del deletes config value by key.
	Del(ctx context.Context, key string, opts ...Option) error
}

KV defines a kv storage for config center.

func GlobalKV

func GlobalKV() KV

GlobalKV returns an instance of kv config center.

type KVConfig

type KVConfig interface {
	KV
	Watcher
	Name() string
}

KVConfig defines a kv config interface.

func Get

func Get(name string) KVConfig

Get returns a kv config by name.

type LoadOption

type LoadOption func(*TrpcConfig)

LoadOption defines the option function for loading configuration.

func WithCodec

func WithCodec(name string) LoadOption

WithCodec returns an option which sets the codec's name.

func WithProvider

func WithProvider(name string) LoadOption

WithProvider returns an option which sets the provider's name.

type Option

type Option func(*options)

Option is the option for config provider sdk.

type ProviderCallback

type ProviderCallback func(string, []byte)

ProviderCallback is callback function for provider to handle config change.

type Response

type Response interface {
	// Value returns config value as string.
	Value() string

	// MetaData returns extra metadata. With option,
	// we can implement some extra features for different config center,
	// such as namespace, group, lease, etc.
	MetaData() map[string]string

	// Event returns the type of watch event.
	Event() EventType
}

Response defines config center's response interface.

type TomlCodec

type TomlCodec struct{}

TomlCodec is toml codec.

func (*TomlCodec) Name

func (*TomlCodec) Name() string

Name returns toml codec's name.

func (*TomlCodec) Unmarshal

func (c *TomlCodec) Unmarshal(in []byte, out interface{}) error

Unmarshal deserializes the in bytes into out parameter by toml.

type TomlUnmarshaler

type TomlUnmarshaler struct{}

TomlUnmarshaler is toml unmarshaler.

func (*TomlUnmarshaler) Unmarshal

func (tu *TomlUnmarshaler) Unmarshal(data []byte, val interface{}) error

Unmarshal deserializes the data bytes into parameter val in toml protocol.

type TrpcConfig

type TrpcConfig struct {
	// contains filtered or unexported fields
}

TrpcConfig is used to parse yaml config file for trpc.

func (*TrpcConfig) Bytes

func (c *TrpcConfig) Bytes() []byte

Bytes returns original config data as bytes.

func (*TrpcConfig) Get

func (c *TrpcConfig) Get(key string, defaultValue interface{}) interface{}

Get returns config value by key. If key is absent will return the default value.

func (*TrpcConfig) GetBool

func (c *TrpcConfig) GetBool(key string, defaultValue bool) bool

GetBool returns bool value by key, the second parameter is default value when key is absent or type conversion fails.

func (*TrpcConfig) GetFloat32

func (c *TrpcConfig) GetFloat32(key string, defaultValue float32) float32

GetFloat32 returns float32 value by key, the second parameter is default value when key is absent or type conversion fails.

func (*TrpcConfig) GetFloat64

func (c *TrpcConfig) GetFloat64(key string, defaultValue float64) float64

GetFloat64 returns float64 value by key, the second parameter is default value when key is absent or type conversion fails.

func (*TrpcConfig) GetInt

func (c *TrpcConfig) GetInt(key string, defaultValue int) int

GetInt returns int value by key, the second parameter is default value when key is absent or type conversion fails.

func (*TrpcConfig) GetInt32

func (c *TrpcConfig) GetInt32(key string, defaultValue int32) int32

GetInt32 returns int32 value by key, the second parameter is default value when key is absent or type conversion fails.

func (*TrpcConfig) GetInt64

func (c *TrpcConfig) GetInt64(key string, defaultValue int64) int64

GetInt64 returns int64 value by key, the second parameter is default value when key is absent or type conversion fails.

func (*TrpcConfig) GetString

func (c *TrpcConfig) GetString(key string, defaultValue string) string

GetString returns string value by key, the second parameter is default value when key is absent or type conversion fails.

func (*TrpcConfig) GetUint

func (c *TrpcConfig) GetUint(key string, defaultValue uint) uint

GetUint returns uint value by key, the second parameter is default value when key is absent or type conversion fails.

func (*TrpcConfig) GetUint32

func (c *TrpcConfig) GetUint32(key string, defaultValue uint32) uint32

GetUint32 returns uint32 value by key, the second parameter is default value when key is absent or type conversion fails.

func (*TrpcConfig) GetUint64

func (c *TrpcConfig) GetUint64(key string, defaultValue uint64) uint64

GetUint64 returns uint64 value by key, the second parameter is default value when key is absent or type conversion fails.

func (*TrpcConfig) IsSet

func (c *TrpcConfig) IsSet(key string) bool

IsSet returns if the config specified by key exists.

func (*TrpcConfig) Load

func (c *TrpcConfig) Load() error

Load loads config.

func (*TrpcConfig) Reload

func (c *TrpcConfig) Reload()

Reload reloads config.

func (*TrpcConfig) Unmarshal

func (c *TrpcConfig) Unmarshal(out interface{}) error

Unmarshal deserializes the config into input param.

type TrpcConfigLoader

type TrpcConfigLoader struct {
	// contains filtered or unexported fields
}

TrpcConfigLoader is a config loader for trpc.

func (*TrpcConfigLoader) Load

func (loader *TrpcConfigLoader) Load(path string, opts ...LoadOption) (Config, error)

Load returns the config specified by input parameter.

func (*TrpcConfigLoader) Reload

func (loader *TrpcConfigLoader) Reload(path string, opts ...LoadOption) error

Reload reloads config data.

type Unmarshaler

type Unmarshaler interface {
	// Unmarshal deserializes the data bytes into value parameter.
	Unmarshal(data []byte, value interface{}) error
}

Unmarshaler defines a unmarshal interface, this will be used to parse config data.

func GetUnmarshaler

func GetUnmarshaler(name string) Unmarshaler

GetUnmarshaler returns an unmarshaler by name.

type Watcher

type Watcher interface {
	// Watch watches the config key change event.
	Watch(ctx context.Context, key string, opts ...Option) (<-chan Response, error)
}

Watcher defines the interface of config center watch event.

type YamlCodec

type YamlCodec struct{}

YamlCodec is yaml codec.

func (*YamlCodec) Name

func (*YamlCodec) Name() string

Name returns yaml codec's name.

func (*YamlCodec) Unmarshal

func (c *YamlCodec) Unmarshal(in []byte, out interface{}) error

Unmarshal deserializes the in bytes into out parameter by yaml.

type YamlUnmarshaler

type YamlUnmarshaler struct{}

YamlUnmarshaler is yaml unmarshaler.

func (*YamlUnmarshaler) Unmarshal

func (yu *YamlUnmarshaler) Unmarshal(data []byte, val interface{}) error

Unmarshal deserializes the data bytes into parameter val in yaml protocol.

Directories

Path Synopsis
Package mockconfig is a generated GoMock package.
Package mockconfig is a generated GoMock package.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL