agollo

package module
v1.0.1 Latest Latest
Warning

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

Go to latest
Published: Jun 13, 2019 License: Apache-2.0 Imports: 15 Imported by: 61

README

Agollo - Go Client for Apollo

================

agollo

携程Apollo Golang版客户端

快速开始

获取安装
go get -u github.com/shima-park/agollo

Features

  • 实时同步配置
  • 配置文件容灾
  • 零依赖
  • 支持多namespace
  • 提供Viper配置库的apollo插件

示例

简单示例
func main(){
    a, err := agollo.New("localhost:8080", "your_appid", agollo.AutoFetchOnCacheMiss())
	if err != nil {
		panic(err)
	}

        // 获取your_appid下
	fmt.Println(
		a.Get("foo"),                // namespace为application中配置项foo的value
		a.GetNameSpace("test.json"), // namespace为test.json的所有配置项
		a.Get("foo", agollo.WithDefault("bar")), // foo这个key不存在时返回bar
		a.Get("foo", agollo.WithNamespace("baz")), // namespace为baz, key为foo的value
	)
}
详细特性展示

请将example/sample下app.properties修改为你本地或者测试的apollo配置。

func main() {
	// 通过默认根目录下的app.properties初始化agollo
	err := agollo.InitWithDefaultConfigFile(
		agollo.WithLogger(agollo.NewLogger(agollo.LoggerWriter(os.Stdout))), // 打印日志信息
		agollo.PreloadNamespaces("TEST.Namespace"),                          // 预先加载的namespace列表,如果是通过配置启动,会在app.properties配置的基础上追加
		agollo.AutoFetchOnCacheMiss(),                                       // 在配置未找到时,去apollo的带缓存的获取配置接口,获取配置
		agollo.FailTolerantOnBackupExists(),                                 // 在连接apollo失败时,如果在配置的目录下存在.agollo备份配置,会读取备份在服务器无法连接的情况下
	)
	if err != nil {
		panic(err)
	}

	/*
		通过指定配置文件地址的方式初始化
		agollo.InitWithConfigFile(configFilePath string, opts ....Option)

		参数形式初始化agollo的方式,适合二次封装
		(1)使用默认的内置对象,用来直接使用包的静态方法
		agollo.Init(
			"localhost:8080",
			"AppTest",
		        opts...,
		)
		(2)不使用包的静态方法,或者需要新建接口对象
		newAgollo, err := agollo.New(
			"localhost:8080",
			"AppTest",
		        opts...,
			)
	*/

	// 获取默认配置中cluster=default namespace=application key=Name的值
	fmt.Println("Name:", agollo.Get("Name"))

	// 获取默认配置中cluster=default namespace=application key=YourConfigKey的值,提供默认值返回
	fmt.Println("YourConfigKey:", agollo.Get("YourConfigKey", agollo.WithDefault("YourDefaultValue")))

	// 获取默认配置中cluster=default namespace=Test.Namespace key=YourConfigKey2的值,提供默认值返回
	fmt.Println("YourConfigKey2:", agollo.Get("YourConfigKey2", agollo.WithDefault("YourDefaultValue"), agollo.WithNamespace("YourNamespace")))

	// 获取namespace下的所有配置项
	fmt.Println("Configuration of the namespace:", agollo.GetNameSpace("application"))

	// TEST.Namespace1是非预加载的namespace
	// agollo初始化是带上agollo.AutoFetchOnCacheMiss()可选项的话
	// 陪到非预加载的namespace,会去apollo缓存接口获取配置
	// 未配置的话会返回空或者传入的默认值选项
	fmt.Println(agollo.Get("Name", agollo.WithDefault("foo"), agollo.WithNamespace("TEST.Namespace1")))

	// 如果想监听并同步服务器配置变化,启动apollo长轮训
	// 返回一个期间发生错误的error channel,按照需要去处理
	errorCh := agollo.Start()

	// 监听apollo配置更改事件
	// 返回namespace和其变化前后的配置,以及可能出现的error
	watchCh := agollo.Watch()

	go func() {
		for {
			select {
			case err := <-errorCh:
				fmt.Println("Error:", err)
			case update := <-watchCh:
				fmt.Println("Apollo Update:", update)
			}
		}
	}()

	select {}
}

结合viper使用,提高配置读取舒适度

例如apollo中有以下配置:

appsalt = xxx
database.driver = mysql
database.host = localhost
database.port = 3306
database.timeout = 5s
// ...

示例代码:

import (
    "fmt"
	"github.com/shima-park/agollo/viper-remote"
	"github.com/spf13/viper"
)

type Config struct {
	AppSalt string         `mapstructure:"appsalt"`
	DB      DatabaseConfig `mapstructure:"database"`
}

type DatabaseConfig struct {
	Driver   string        `mapstructure:"driver"`
	Host     string        `mapstructure:"host"`
	Port     int           `mapstructure:"port"`
	Timeout time.Duration  `mapstructure:"timeout"`
	// ...
}

func main(){
    remote.SetAppID("your_appid")
    v := viper.New()
    v.SetConfigType("prop") // 根据namespace实际格式设置对应type
    err := v.AddRemoteProvider("apollo", "your_apollo_endpoint", "your_apollo_namespace")
    // ... error handle
    err = v.ReadRemoteConfig()
    // ... error handle

    // 直接反序列化到结构体中
    var conf Config
    err = v.Unmarshal(&conf)
    // ... error handle
    fmt.Printf("%+v\n", conf)
    
    // 各种基础类型配置项读取
    fmt.Println("Host:", v.GetString("db.host"))
    fmt.Println("Port:", v.GetInt("db.port"))
    fmt.Println("Timeout:", v.GetDuration("db.timeout"))
    
    // 获取所有key,所有配置
    fmt.Println("AllKeys", v.AllKeys(), "AllSettings",  v.AllSettings())
}

License

The project is licensed under the Apache 2 license.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Get

func Get(key string, opts ...GetOption) string

func Init

func Init(configServerURL, appID string, opts ...Option) (err error)

func InitWithConfigFile

func InitWithConfigFile(configFilePath string, opts ...Option) (err error)

func InitWithDefaultConfigFile

func InitWithDefaultConfigFile(opts ...Option) error

func Start

func Start() <-chan *LongPollerError

func Stop

func Stop()

func ToStringE added in v1.0.1

func ToStringE(i interface{}) (string, error)

ToStringE casts an interface to a string type.

func Watch

func Watch() <-chan *ApolloResponse

func WatchNamespace

func WatchNamespace(namespace string, stop chan bool) <-chan *ApolloResponse

Types

type Agollo

type Agollo interface {
	Start() <-chan *LongPollerError
	Stop()
	Get(key string, opts ...GetOption) string
	GetNameSpace(namespace string) Configurations
	Watch() <-chan *ApolloResponse
	WatchNamespace(namespace string, stop chan bool) <-chan *ApolloResponse
	Options() Options
}

func GetAgollo

func GetAgollo() Agollo

func New

func New(configServerURL, appID string, opts ...Option) (Agollo, error)

func NewWithConfigFile

func NewWithConfigFile(configFilePath string, opts ...Option) (Agollo, error)

type ApolloClient

type ApolloClient interface {
	Notifications(configServerURL, appID, clusterName string, notifications []Notification) (int, []Notification, error)

	// 该接口会直接从数据库中获取配置,可以配合配置推送通知实现实时更新配置。
	GetConfigsFromNonCache(configServerURL, appID, cluster, namespace string, opts ...NotificationsOption) (int, *Config, error)

	// 该接口会从缓存中获取配置,适合频率较高的配置拉取请求,如简单的每30秒轮询一次配置。
	GetConfigsFromCache(configServerURL, appID, cluster, namespace string) (Configurations, error)
}

https://github.com/ctripcorp/apollo/wiki/%E5%85%B6%E5%AE%83%E8%AF%AD%E8%A8%80%E5%AE%A2%E6%88%B7%E7%AB%AF%E6%8E%A5%E5%85%A5%E6%8C%87%E5%8D%97

func NewApolloClient

func NewApolloClient(opts ...ApolloClientOption) ApolloClient

type ApolloClientOption

type ApolloClientOption func(*apolloClient)

func WithConfigType

func WithConfigType(configType string) ApolloClientOption

func WithDoer

func WithDoer(d Doer) ApolloClientOption

func WithIP

func WithIP(ip string) ApolloClientOption

type ApolloResponse

type ApolloResponse struct {
	Namespace string
	OldValue  Configurations
	NewValue  Configurations
	Error     error
}

type Config

type Config struct {
	AppID          string         `json:"appId"`          // appId: "AppTest",
	Cluster        string         `json:"cluster"`        // cluster: "default",
	NamespaceName  string         `json:"namespaceName"`  // namespaceName: "TEST.Namespace1",
	Configurations Configurations `json:"configurations"` // configurations: {Name: "Foo"},
	ReleaseKey     string         `json:"releaseKey"`     // releaseKey: "20181017110222-5ce3b2da895720e8"
}

type Configurations

type Configurations map[string]interface{}

func GetNameSpace

func GetNameSpace(namespace string) Configurations

type Doer

type Doer interface {
	Do(*http.Request) (*http.Response, error)
}

type GetOption

type GetOption func(*GetOptions)

func WithDefault

func WithDefault(defVal string) GetOption

func WithNamespace

func WithNamespace(namespace string) GetOption

type GetOptions

type GetOptions struct {
	DefaultValue string
	Namespace    string
}

type Logger

type Logger interface {
	Log(kvs ...interface{})
}

func NewLogger

func NewLogger(opts ...LoggerOption) Logger

type LoggerOption

type LoggerOption func(*logger)

func LoggerWriter

func LoggerWriter(w io.Writer) LoggerOption

type LongPollerError

type LongPollerError struct {
	ConfigServerURL string
	AppID           string
	Cluster         string
	Notifications   []Notification
	Namespace       string // 服务响应200后去非缓存接口拉取时的namespace
	Err             error
}

type Notification

type Notification struct {
	NamespaceName  string `json:"namespaceName"`  // namespaceName: "application",
	NotificationID int    `json:"notificationId"` // notificationId: 107
}

type Notifications

type Notifications []Notification

func (Notifications) String

func (n Notifications) String() string

type NotificationsOption

type NotificationsOption func(*NotificationsOptions)

func ReleaseKey

func ReleaseKey(releaseKey string) NotificationsOption

type NotificationsOptions

type NotificationsOptions struct {
	ReleaseKey string
}

type Option

type Option func(*Options)

func AutoFetchOnCacheMiss

func AutoFetchOnCacheMiss() Option

func BackupFile

func BackupFile(backupFile string) Option

func Cluster

func Cluster(cluster string) Option

func DefaultNamespace

func DefaultNamespace(defaultNamespace string) Option

func FailTolerantOnBackupExists

func FailTolerantOnBackupExists() Option

func LongPollerInterval

func LongPollerInterval(i time.Duration) Option

func PreloadNamespaces

func PreloadNamespaces(namespaces ...string) Option

func WithApolloClient

func WithApolloClient(c ApolloClient) Option

func WithLogger

func WithLogger(l Logger) Option

type Options

type Options struct {
	ConfigServerURL            string        // apollo 服务地址
	AppID                      string        // appid
	Cluster                    string        // 默认的集群名称,默认:default
	DefaultNamespace           string        // 默认的命名空间,默认:application
	PreloadNamespaces          []string      // 预加载命名空间,默认:application
	ApolloClient               ApolloClient  // apollo HTTP api实现
	Logger                     Logger        // 需要日志需要设置实现,或者注入有效的io.Writer,默认: ioutil.Discard
	AutoFetchOnCacheMiss       bool          // 自动获取非预设以外的namespace的配置,默认:false
	LongPollerInterval         time.Duration // 轮训间隔时间,默认:1s
	BackupFile                 string        // 备份文件存放地址,默认:.agollo
	FailTolerantOnBackupExists bool          // 服务器连接失败时允许读取备份,默认:false
}

Directories

Path Synopsis
examples
sample command
viper command

Jump to

Keyboard shortcuts

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