github.com/jtzjtz/kit@v1.0.2/config/config.go (about)

     1  package config
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/go-errors/errors"
     6  	"github.com/micro/go-micro/v2/config"
     7  	"github.com/micro/go-micro/v2/logger"
     8  	"github.com/nacos-group/nacos-sdk-go/clients"
     9  	"github.com/nacos-group/nacos-sdk-go/clients/config_client"
    10  	"github.com/nacos-group/nacos-sdk-go/common/constant"
    11  	"github.com/nacos-group/nacos-sdk-go/vo"
    12  
    13  	"log"
    14  	"os"
    15  )
    16  
    17  type IDataConfig interface {
    18  	//重载接口
    19  	Reload() error
    20  	//检查接口
    21  	IsLoad() bool
    22  }
    23  
    24  type NacosConfig struct {
    25  	Address             string
    26  	Port                uint64
    27  	Scheme              string
    28  	ContextPath         string
    29  	NameSpaceId         string
    30  	TimeoutMs           uint64
    31  	NotLoadCacheAtStart bool
    32  	LogDir              string
    33  	CacheDir            string
    34  	RotateTime          string
    35  	MaxAge              int64
    36  	LogLevel            string
    37  }
    38  type Client struct {
    39  	conn        config_client.IConfigClient
    40  	cacheDIr    string
    41  	isConnected bool
    42  }
    43  
    44  //初始化nacos客户端
    45  func InitClient(conf NacosConfig) (Client, error) {
    46  	sc := []constant.ServerConfig{
    47  		*constant.NewServerConfig(
    48  			conf.Address,
    49  			conf.Port,
    50  			constant.WithScheme(conf.Scheme),
    51  			constant.WithContextPath(conf.ContextPath)),
    52  	}
    53  
    54  	cc := *constant.NewClientConfig(
    55  		constant.WithNamespaceId(conf.NameSpaceId),
    56  		constant.WithTimeoutMs(conf.TimeoutMs),
    57  		constant.WithNotLoadCacheAtStart(conf.NotLoadCacheAtStart),
    58  		constant.WithLogDir(conf.LogDir),
    59  		constant.WithCacheDir(conf.CacheDir),
    60  		constant.WithRotateTime(conf.RotateTime),
    61  		constant.WithMaxAge(conf.MaxAge),
    62  		constant.WithLogLevel(conf.LogLevel),
    63  	)
    64  	nacosClient, err := clients.NewConfigClient(
    65  		vo.NacosClientParam{
    66  			ClientConfig:  &cc,
    67  			ServerConfigs: sc,
    68  		},
    69  	)
    70  
    71  	if err != nil {
    72  		log.Fatal("nacos init err", err)
    73  		return Client{isConnected: false}, err
    74  
    75  	}
    76  	c := Client{conn: nacosClient, cacheDIr: conf.CacheDir, isConnected: true}
    77  	return c, err
    78  }
    79  
    80  //获取配置信息 返回字符串
    81  func (t *Client) GetConfig(dataid string, group string) (string, error) {
    82  	if t.isConnected == false {
    83  		return "", errors.New("nacos 连接失败")
    84  	}
    85  	data, er := t.conn.GetConfig(vo.ConfigParam{
    86  		DataId: dataid,
    87  		Group:  group,
    88  	})
    89  	if er != nil {
    90  		log.Fatal("nacos get config err", er)
    91  		return "", er
    92  
    93  	}
    94  	return data, nil
    95  }
    96  
    97  //获取配置信息 转为targetConfig isWatch 是否监听配置变更
    98  func (t *Client) GetDataConfig(dataid string, group string, targetConfig IDataConfig, isWatch bool) error {
    99  	data, err := t.GetConfig(dataid, group)
   100  	if err != nil {
   101  		return err
   102  	}
   103  
   104  	if saveError := saveConfig(data, dataid, group, targetConfig, t.cacheDIr); saveError != nil {
   105  		return saveError
   106  	}
   107  	if isWatch {
   108  		return t.WatchConfig(dataid, group, targetConfig, true)
   109  	}
   110  	return nil
   111  }
   112  
   113  //监听
   114  func (t *Client) WatchConfig(dataid string, group string, targetConfig IDataConfig, isReload bool) error {
   115  	err := t.conn.ListenConfig(vo.ConfigParam{
   116  		DataId: dataid,
   117  		Group:  group,
   118  		OnChange: func(namespace, group, dataId, data string) {
   119  			//是否重载变量
   120  			shouldReload := isReload
   121  			//因为开启监听也会调用OnChange函数,所以加此判断
   122  			//if  !model.IsLoad(){
   123  			//	shouldReload=false  //如果model 没有被加载过,则不需要做重载
   124  			//}
   125  			err := saveConfig(data, dataid, group, targetConfig, t.cacheDIr)
   126  			if err != nil {
   127  				return
   128  			}
   129  
   130  			//重载
   131  			if shouldReload { //重载关键代码
   132  				err := targetConfig.Reload()
   133  				if err != nil {
   134  					logger.Error(err)
   135  					return
   136  				} else {
   137  					logger.Info(dataid, " 重载完成")
   138  				}
   139  			}
   140  
   141  		},
   142  	})
   143  	if err != nil {
   144  		logger.Error("listen config error,dataid:", dataid, err)
   145  	}
   146  	return err
   147  }
   148  
   149  func saveConfig(data string, dataid string, group string, targetConfig IDataConfig, confDir string) error {
   150  	//线上配置缓存文件
   151  	cacheFile := fmt.Sprintf("%s/%s-%s.yaml", confDir, group, dataid)
   152  	file, err := os.OpenFile(cacheFile, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666)
   153  	if err != nil {
   154  		logger.Error(err)
   155  		return err
   156  	}
   157  	defer file.Close()
   158  	//写入缓存文件
   159  	_, err = file.WriteString(data)
   160  	if err != nil {
   161  		logger.Error(err)
   162  		return err
   163  	}
   164  	//从缓存文件加载配置
   165  	err = config.LoadFile(cacheFile)
   166  	if err != nil {
   167  		logger.Error(err)
   168  		return err
   169  	}
   170  	//接收
   171  	err = config.Scan(targetConfig)
   172  	if err != nil {
   173  		logger.Error(err)
   174  		return err
   175  	}
   176  	return nil
   177  }