Skip to content
On this page

操作动态配置文件

Nacos可以动态读取修改删除配置文件,还可以监听配置文件修改

使用go sdk来实现

  • ClientConfig配置参数
Go
constant.ClientConfig {
    TimeoutMs   uint64 // timeout for requesting Nacos server, default value is 10000ms
    NamespaceId string // the namespaceId of Nacos
    Endpoint    string // the endpoint for ACM. https://help.aliyun.com/document_detail/130146.html
    RegionId    string // the regionId for ACM & KMS
    AccessKey   string // the AccessKey for ACM & KMS
    SecretKey   string // the SecretKey for ACM & KMS
    OpenKMS     bool   // it's to open KMS, default is false. https://help.aliyun.com/product/28933.html
    // , to enable encrypt/decrypt, DataId should be start with "cipher-"
    CacheDir             string // the directory for persist nacos service info,default value is current path
    UpdateThreadNum      int    // the number of goroutine for update nacos service info,default value is 20
    NotLoadCacheAtStart  bool   // not to load persistent nacos service info in CacheDir at start time
    UpdateCacheWhenEmpty bool   // update cache when get empty service instance from server
    Username             string // the username for nacos auth
    Password             string // the password for nacos auth
    LogDir               string // the directory for log, default is current path
    RotateTime           string // the rotate time for log, eg: 30m, 1h, 24h, default is 24h
    MaxAge               int64  // the max age of a log file, default value is 3
    LogLevel             string // the level of log, it's must be debug,info,warn,error, default value is info
}
  • ServerConfig配置参数
Go
constant.ServerConfig{
    Scheme      string // the nacos server scheme,defaut=http,this is not required in 2.0 
    ContextPath string // the nacos server contextpath,defaut=/nacos,this is not required in 2.0 
    IpAddr      string // the nacos server address 
    Port        uint64 // nacos server port
    GrpcPort    uint64 // nacos server grpc port, default=server port + 1000, this is not required
}

可用方法

创建连接后,client有以下几个方法可以调用

  • PublishConfig:用于将配置发布到nacos服务器
Go
PublishConfig(param vo.ConfigParam) (bool, error)
  • GetConfig:从nacos服务获取配置
Go
GetConfig(param vo.ConfigParam) (string, error)
  • ListenConfig:监听配置修改,当配置改变的时候会触发OnChange回调函数
Go
ListenConfig(params vo.ConfigParam) (err error)
  • DeleteConfig:删除某个配置
Go
DeleteConfig(param vo.ConfigParam) (bool, error) 
  • CancelListenConfig:取消监听配置修改
Go
CancelListenConfig(params vo.ConfigParam) (err error)
  • SearchConfig:搜索配置

    • search=accurate--精确搜索
    • search=blur--模糊搜索
Go
SearchConfig(param vo.SearchConfigParam) (*model.ConfigPage, error)

不使用命名空间

  1. 定义客户端服务端配置
Go
// create  serverConfig
serverConfigs := []constant.ServerConfig{
    *constant.NewServerConfig(
        "127.0.0.1",
        8848,
        constant.WithContextPath("/nacos"),
    ),
}
// create clientConfig
clientConfig := *constant.NewClientConfig(
    constant.WithNamespaceId(""), // 不使用命名空间这里传空就行
    constant.WithTimeoutMs(5000),
    constant.WithNotLoadCacheAtStart(true),
    constant.WithLogDir("/tmp/nacos/log"),
    constant.WithCacheDir("/tmp/nacos/cache"),
    constant.WithLogLevel("debug"),
    constant.WithUsername("nacos"),
    constant.WithPassword("nacos"),
)
  1. 创建客户端链接,然后就可以对配置进行操作了
Go
// create config client
client, err := clients.NewConfigClient(vo.NacosClientParam{
    ClientConfig:  &clientConfig,
    ServerConfigs: serverConfigs,
})
if err != nil {
    log.Printf("create config client error %s\n", err)
    panic(err)
}

完整代码如下:

Go
func noNameSpaceOperation() {
	// create  serverConfig
	serverConfigs := []constant.ServerConfig{
		*constant.NewServerConfig(
			"127.0.0.1",
			8848,
			constant.WithContextPath("/nacos"),
		),
	}
	// create clientConfig
	clientConfig := *constant.NewClientConfig(
		constant.WithNamespaceId(""),
		constant.WithTimeoutMs(5000),
		constant.WithNotLoadCacheAtStart(true),
		constant.WithLogDir("/tmp/nacos/log"),
		constant.WithCacheDir("/tmp/nacos/cache"),
		constant.WithLogLevel("debug"),
		constant.WithUsername("nacos"),
		constant.WithPassword("nacos"),
	)
	// create config client
	client, err := clients.NewConfigClient(vo.NacosClientParam{
		ClientConfig:  &clientConfig,
		ServerConfigs: serverConfigs,
	})
	if err != nil {
		log.Printf("create config client error %s\n", err)
		panic(err)
	}
	// publish config
	_, err = client.PublishConfig(vo.ConfigParam{
		DataId:  "test-dataId-1",
		Group:   "test-group1",
		Content: "Hello, I am test data1",
	})
	_, err = client.PublishConfig(vo.ConfigParam{
		DataId:  "test-dataId-2",
		Group:   "test-group2",
		Type:    "yaml", // 提交的数据类型
		Content: "Hello, I am test data2 change",
	})
	if err != nil {
		log.Printf("publish config error => %s\n", err)
		return
	}
	time.Sleep(2 * time.Second)

	// get config
	testGroup1Content, err := client.GetConfig(vo.ConfigParam{
		DataId: "test-dataId-1",
		Group:  "test-group1",
	})
	if err != nil {
		log.Printf("get test-group1 config error => %s\n", err)
		return
	}
	fmt.Printf("testGroup1Content is: %s \n", testGroup1Content)
	testGroup2Content, err := client.GetConfig(vo.ConfigParam{
		DataId: "test-dataId-2",
		Group:  "test-group2",
	})
	if err != nil {
		log.Printf("get test-group2 config error => %s\n", err)
		return
	}
	fmt.Printf("testGroup2Content is: %s \n", testGroup2Content)
	// listen config change
	err = client.ListenConfig(vo.ConfigParam{
		DataId: "test-dataId-1",
		Group:  "test-group1",
		OnChange: func(namespace, group, dataId, data string) {
			fmt.Printf("[namespace: %s], [group: %s], [dataId: %s] changed, content is 【%s】\n", namespace, group, dataId, data)
		},
	})

	err = client.ListenConfig(vo.ConfigParam{
		DataId: "test-dataId-2",
		Group:  "test-group2",
		OnChange: func(namespace, group, dataId, data string) {
			fmt.Printf("[namespace: %s], [group: %s], [dataId: %s] changed, content is 【%s】\n", namespace, group, dataId, data)
		},
	})
	if err != nil {
		return
	}
	time.Sleep(30 * time.Second)
	// delete config
	_, err = client.DeleteConfig(vo.ConfigParam{
		DataId: "test-dataId-2",
		Group:  "test-group2",
	})
	if err != nil {
		return
	}
	fmt.Println("delete test-group2 success")
	// cancel listen config change
	err = client.CancelListenConfig(vo.ConfigParam{
		DataId: "test-dataId-1",
		Group:  "test-group1",
	})
	if err != nil {
		return
	}
	fmt.Println("cancel listen test-group1 success")
	time.Sleep(30 * time.Second)
	// search config
	searchedConfig, err := client.SearchConfig(vo.SearchConfigParam{
		Search:   "blur", // accurate/blur 准确/模糊搜索
		DataId:   "",
		Group:    "",
		PageNo:   1,
		PageSize: 10,
	})
	if err != nil {
		fmt.Printf("search config error %s \n", err)
		return
	}
	fmt.Printf("searchd config is %v \n", searchedConfig)
}

使用命名空间

先去http://localhost:8848/nacos,点击左侧的命名空间菜单,然后点击新建命名空间,然后复制命名空间ID

然后在调用constant.NewClientConfig方法的时候,加上命名空间ID

Go
// create clientConfig
clientConfig := *constant.NewClientConfig(
    constant.WithNamespaceId("namespaceId"),
    constant.WithTimeoutMs(5000),
    constant.WithNotLoadCacheAtStart(true),
    constant.WithLogDir("/tmp/nacos/log"),
    constant.WithCacheDir("/tmp/nacos/cache"),
    constant.WithLogLevel("debug"),
    constant.WithUsername("nacos"),
    constant.WithPassword("nacos"),
)

获取nacos server的配置,并转为go struct

相关工具网站:

nacos server配置如下

yaml
mysql:
  userName: admin
  password: qwert1
  host: 172.16.40.85
  port: 3306
redis:
  addr: 127.0.0.1:9381
  password: 235kls32235sdf
  db: 0
wechat:
  appID: qwe4sdgkk
  appSecret: qwe%appSecret%rt
  baseURL: https://api.weixin.qq.com

go实现代码如下:

Go
package main

import (
	"fmt"
	"github.com/nacos-group/nacos-sdk-go/v2/clients"
	"github.com/nacos-group/nacos-sdk-go/v2/common/constant"
	"github.com/nacos-group/nacos-sdk-go/v2/vo"
	"gopkg.in/yaml.v3"
	"time"
)

type AllConfig struct {
	Mysql  MysqlConfig  `yaml:"mysql"`
	Redis  RedisConfig  `yaml:"redis"`
	Wechat WechatConfig `yaml:"wechat"`
}

type MysqlConfig struct {
	UserName string `yaml:"userName"`
	Password string `yaml:"password"`
	Host     string `yaml:"host"`
	Port     string `yaml:"port"`
}

type RedisConfig struct {
	Addr     string `yaml:"addr"`
	Password string `yaml:"password"`
	DB       int    `yaml:"db"`
}

type WechatConfig struct {
	AppID     string `yaml:"appID"`
	AppSecret string `yaml:"appSecret"`
	BaseURL   string `yaml:"baseURL"`
}

func convertYamlToStruct(in []byte, out interface{}) error {
	return yaml.Unmarshal(in, out)
}

func fetchRemoteConfig() {
	// create server config
	serverConfigs := []constant.ServerConfig{
		*constant.NewServerConfig("127.0.0.1", 8848, constant.WithContextPath("/nacos")),
	}
	// create naming clientConfig
	clientConfig := *constant.NewClientConfig(
		constant.WithNamespaceId("d90cfc52-948b-41e7-82f7-bd22dbb36221"),
		constant.WithTimeoutMs(5000),
		constant.WithNotLoadCacheAtStart(true),
		constant.WithLogDir("/tmp/nacos/log"),
		constant.WithCacheDir("/tmp/nacos/cache"),
		constant.WithLogLevel("debug"),
		constant.WithUsername("nacos"),
		constant.WithPassword("nacos"),
	)
	// create config client for dynamic configuration
	namingClient, err := clients.NewConfigClient(vo.NacosClientParam{
		ServerConfigs: serverConfigs,
		ClientConfig:  &clientConfig,
	})
	if err != nil {
		panic(err)
	}
	configParam := vo.ConfigParam{
		DataId: "test-config",
		Group:  "DEFAULT_GROUP",
		Type:   "yaml",
	}
	remoteConfig, err := namingClient.GetConfig(configParam)
	var allConfig AllConfig
	err = convertYamlToStruct([]byte(remoteConfig), &allConfig)
	//fmt.Printf("allConfig is %v \n", allConfig.Wechat)
	if err != nil {
		panic(err)
	}
	err = namingClient.ListenConfig(vo.ConfigParam{
		DataId: "test-config",
		Group:  "DEFAULT_GROUP",
		Type:   "yaml",
		OnChange: func(namespace, group, dataId, data string) {
			//fmt.Printf("[namespace: %s], [group: %s], [dataId: %s] changed, content is 【%s】, contentType is [%T]\n", namespace, group, dataId, data, data)
			err = convertYamlToStruct([]byte(data), &allConfig)
			if err != nil {
				panic(err)
			}
			fmt.Printf("修改后的allConfig为%v \n", allConfig)
		},
	})
	if err != nil {
		panic(err)
	}
	fmt.Println("startup successful")
	time.Sleep(60 * time.Second)
}

func main() {
	fetchRemoteConfig()
}