简介
apollo是一个配置中心,可以通过apollo客户端拉取配置信息,以及监听apollo配置的发布事件,来达到热更配置的目的。
使用
配置apollo的namespace
使用默认的app.properties配置
appid : "dev_service" // 项目名字
cluster: "dev" // 集群
server_url : "http://192.168.82.10:8080" // 地址
namespace: "application" // 文件
secret: "" // 管理秘钥,可不使用
初始化,拉取配置信息
import (
"gitee.com/dennis-kk/service-box-go/util/slog"
"github.com/apolloconfig/agollo/v4"
apolloConfig "github.com/apolloconfig/agollo/v4/env/config"
"github.com/apolloconfig/agollo/v4/storage"
)
type ApolloConfigClient struct {
AppID string
Cluster string
IP string
NamespaceName string
Secret string
sdk agollo.Client
}
// 开始拉取配置
func (c *ApolloConfigClient) Start() error {
var err error
c.sdk, err = agollo.StartWithConfig(func() (*apolloConfig.AppConfig, error) {
return &apolloConfig.AppConfig{
AppID: c.AppID,
Cluster: c.Cluster,
IP: c.IP,
NamespaceName: c.NamespaceName,
IsBackupConfig: false,
Secret: c.Secret,
SyncServerTimeout: 2,
}, nil
})
if err != nil {
return err
}
return nil
}
添加监听事件
type ApolloEventListener struct {
}
func (l *ApolloEventListener) OnChange(changeEvent *storage.ChangeEvent) {
for key, value := range changeEvent.Changes {
slog.Info("apollo %v config change, key : %v, old_value : %v, new_value : %v",
changeEvent.Namespace, key, value.OldValue, value.NewValue)
}
}
func (l *ApolloEventListener) OnNewestChange(event *storage.FullChangeEvent) {
for key, value := range event.Changes {
slog.Info("pull apollo %v config, key : %v, value : %v",
event.Namespace, key, value)
}
}
c.sdk.AddChangeListener(&ApolloEventListener{})
获取key的对应值
func (c *ApolloConfigClient) GetStringValue(key string, defaultValue string) string {
conf := c.sdk.GetConfig(c.NamespaceName)
return conf.GetStringValueImmediately(key, defaultValue)
}
func (c *ApolloConfigClient) GetIntValue(key string, defaultValue int) int {
conf := c.sdk.GetConfig(c.NamespaceName)
return conf.GetIntValueImmediately(key, defaultValue)
}
func (c *ApolloConfigClient) GetFloatValue(key string, defaultValue float64) float64 {
conf := c.sdk.GetConfig(c.NamespaceName)
return conf.GetFloatValueImmediately(key, defaultValue)
}
func (c *ApolloConfigClient) GetBoolValue(key string, defaultValue bool) bool {
conf := c.sdk.GetConfig(c.NamespaceName)
return conf.GetBoolValueImmediately(key, defaultValue)
}
func (c *ApolloConfigClient) GetStringSliceValue(key string, defaultValue []string) []string {
conf := c.sdk.GetConfig(c.NamespaceName)
value := conf.GetStringValueImmediately(key, "")
arr := []string{}
err := json.Unmarshal([]byte(value), &arr)
if err != nil {
slog.Error("GetStringSliceValue error: %v, key: %v", err, key)
return defaultValue
}
return arr
}
func (c *ApolloConfigClient) GetIntSliceValue(key string, defaultValue []int) []int {
conf := c.sdk.GetConfig(c.NamespaceName)
value := conf.GetStringValueImmediately(key, "")
arr := []int{}
err := json.Unmarshal([]byte(value), &arr)
if err != nil {
slog.Error("GetIntSliceValue error: %v, key: %v", err, key)
return defaultValue
}
return arr
}
完整demo
package dao
import (
"gitee.com/dennis-kk/service-box-go/util/config"
"gitee.com/dennis-kk/service-box-go/util/slog"
"encoding/json"
"sync/atomic"
"github.com/apolloconfig/agollo/v4"
apolloConfig "github.com/apolloconfig/agollo/v4/env/config"
"github.com/apolloconfig/agollo/v4/storage"
)
type ApolloEventListener struct {
hasLogFull int32
}
func (l *ApolloEventListener) OnChange(changeEvent *storage.ChangeEvent) {
for key, value := range changeEvent.Changes {
slog.Info("apollo %v config change, key : %v, old_value : %v, new_value : %v",
changeEvent.Namespace, key, value.OldValue, value.NewValue)
}
}
func (l *ApolloEventListener) OnNewestChange(event *storage.FullChangeEvent) {
// 只打印一次全量
if ok := atomic.CompareAndSwapInt32(&l.hasLogFull, 0, 1); !ok {
return
}
for key, value := range event.Changes {
slog.Info("pull apollo %v config, key : %v, value : %v",
event.Namespace, key, value)
}
}
type ApolloConfigClient struct {
AppID string
Cluster string
IP string
NamespaceName string
Secret string
sdk agollo.Client
}
func NewApolloConfigClient(cfg config.Config) (*ApolloConfigClient, error) {
appId := cfg.Get("apllo_cfg", "appid").String("")
cluster := cfg.Get("apllo_cfg", "cluster").String("")
serverIp := cfg.Get("apllo_cfg", "server_url").String("")
namespace := cfg.Get("apllo_cfg", "namespace").String("")
secret := cfg.Get("apllo_cfg", "secret").String("")
client := &ApolloConfigClient{
AppID: appId,
Cluster: cluster,
IP: serverIp,
NamespaceName: namespace,
Secret: secret,
}
err := client.Start()
if err != nil {
slog.Error("first start apollo error: %v", err)
return nil, err
}
return client, err
}
// 开始拉取配置
func (c *ApolloConfigClient) Start() error {
var err error
c.sdk, err = agollo.StartWithConfig(func() (*apolloConfig.AppConfig, error) {
return &apolloConfig.AppConfig{
AppID: c.AppID,
Cluster: c.Cluster,
IP: c.IP,
NamespaceName: c.NamespaceName,
IsBackupConfig: false,
Secret: c.Secret,
SyncServerTimeout: 2,
}, nil
})
if err != nil {
slog.Error("start apollo client error: %v", err)
return err
}
c.sdk.AddChangeListener(&ApolloEventListener{hasLogFull: 0})
return nil
}
func (c *ApolloConfigClient) Stop() {
if c.sdk == nil {
return
}
c.sdk.Close()
}
// 获取key对应的值
func (c *ApolloConfigClient) GetStringValue(key string, defaultValue string) string {
conf := c.sdk.GetConfig(c.NamespaceName)
return conf.GetStringValueImmediately(key, defaultValue)
}
func (c *ApolloConfigClient) GetIntValue(key string, defaultValue int) int {
conf := c.sdk.GetConfig(c.NamespaceName)
return conf.GetIntValueImmediately(key, defaultValue)
}
func (c *ApolloConfigClient) GetFloatValue(key string, defaultValue float64) float64 {
conf := c.sdk.GetConfig(c.NamespaceName)
return conf.GetFloatValueImmediately(key, defaultValue)
}
func (c *ApolloConfigClient) GetBoolValue(key string, defaultValue bool) bool {
conf := c.sdk.GetConfig(c.NamespaceName)
return conf.GetBoolValueImmediately(key, defaultValue)
}
func (c *ApolloConfigClient) GetStringSliceValue(key string, defaultValue []string) []string {
conf := c.sdk.GetConfig(c.NamespaceName)
value := conf.GetStringValueImmediately(key, "")
arr := []string{}
err := json.Unmarshal([]byte(value), &arr)
if err != nil {
slog.Error("GetStringSliceValue error: %v, key: %v", err, key)
return defaultValue
}
return arr
}
func (c *ApolloConfigClient) GetIntSliceValue(key string, defaultValue []int) []int {
conf := c.sdk.GetConfig(c.NamespaceName)
value := conf.GetStringValueImmediately(key, "")
arr := []int{}
err := json.Unmarshal([]byte(value), &arr)
if err != nil {
slog.Error("GetIntSliceValue error: %v, key: %v", err, key)
return defaultValue
}
return arr
}