抽离配置到nacos里
This commit is contained in:
+61
-85
@@ -6,7 +6,7 @@ import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@@ -14,137 +14,119 @@ import (
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
// 外部传入Nacos参数结构体
|
||||
type NacosConfig struct {
|
||||
Hosts []string
|
||||
NamespaceId string
|
||||
Group string
|
||||
ConfigID string
|
||||
}
|
||||
|
||||
var (
|
||||
localViper = viper.New()
|
||||
runViper = viper.New()
|
||||
loadOnce sync.Once
|
||||
nacosHost string
|
||||
namespace string
|
||||
dataId string
|
||||
group string
|
||||
nacosCfg NacosConfig
|
||||
currentMd5 string
|
||||
)
|
||||
|
||||
func GetConfig(key string) interface{} { return runViper.Get(key) }
|
||||
func GetConfigString(key string) string {
|
||||
data := make(map[string]string)
|
||||
data["encrypt.data_key"] = "u2t9T3luZtoRfhBstkFN6TiIMW38BA8a"
|
||||
data["encrypt_key"] = "M17fcaPeHDr05H17fcaPH1deDH17l3Bd"
|
||||
return data[key]
|
||||
}
|
||||
func GetConfigInt(key string) int {
|
||||
data := make(map[string]int)
|
||||
data["base.login_out_time"] = 60 * 24 * 30 //分
|
||||
data["base.login_refresh_out_time"] = 60 * 24 * 30 * 2 //分
|
||||
return data[key]
|
||||
}
|
||||
func GetConfigInt64(key string) int64 { return runViper.GetInt64(key) }
|
||||
func GetConfigBool(key string) bool {
|
||||
data := make(map[string]bool)
|
||||
data["mysql.debug"] = true
|
||||
return runViper.GetBool(key)
|
||||
}
|
||||
func GetConfig(key string) interface{} { return runViper.Get(key) }
|
||||
func GetConfigString(key string) string { return runViper.GetString(key) }
|
||||
func GetConfigInt(key string) int { return runViper.GetInt(key) }
|
||||
func GetConfigInt64(key string) int64 { return runViper.GetInt64(key) }
|
||||
func GetConfigBool(key string) bool { return runViper.GetBool(key) }
|
||||
|
||||
func InitConfig() {
|
||||
// 初始化入口
|
||||
func InitConfig(cfg NacosConfig) {
|
||||
loadOnce.Do(func() {
|
||||
autoLoadLocalConfig()
|
||||
nacosCfg = cfg
|
||||
|
||||
// 初始化尝试拉取Nacos,失败降级本地缓存
|
||||
err := fetchNacosAndSaveRunToml()
|
||||
if err != nil {
|
||||
Logger.Error("初始化拉取Nacos配置失败,降级使用本地run.toml缓存", err)
|
||||
if len(nacosCfg.Hosts) == 0 || nacosCfg.ConfigID == "" {
|
||||
panic("nacos Hosts 与 ConfigID 不能为空")
|
||||
}
|
||||
|
||||
// 加载配置文件(不管Nacos成功与否,一定加载本地run.toml)
|
||||
// 尝试拉取远端配置
|
||||
pullErr := fetchNacosAndSaveRunToml()
|
||||
if pullErr != nil {
|
||||
fmt.Printf("【警告】Nacos远程拉取失败: %v\n尝试加载本地run.toml缓存启动\n", pullErr)
|
||||
}
|
||||
|
||||
// 加载配置,容错:无缓存文件不直接panic,打印提示
|
||||
loadRunToml()
|
||||
|
||||
// 启动定时后台重试协程
|
||||
// 后台定时同步
|
||||
startFixedIntervalSync()
|
||||
})
|
||||
}
|
||||
|
||||
func autoLoadLocalConfig() {
|
||||
localViper.SetConfigName("env")
|
||||
localViper.SetConfigType("toml")
|
||||
|
||||
paths := []string{
|
||||
"./",
|
||||
"./config",
|
||||
}
|
||||
|
||||
for _, p := range paths {
|
||||
fullPath := filepath.Join(getWorkDir(), p)
|
||||
if _, err := os.Stat(fullPath); err == nil {
|
||||
localViper.AddConfigPath(fullPath)
|
||||
}
|
||||
}
|
||||
|
||||
err := localViper.ReadInConfig()
|
||||
if err != nil {
|
||||
Logger.Panic("找不到 env.toml")
|
||||
}
|
||||
|
||||
nacosHost = localViper.GetString("rnacos.host")
|
||||
namespace = localViper.GetString("rnacos.namespace")
|
||||
dataId = localViper.GetString("rnacos.dataid")
|
||||
group = localViper.GetString("rnacos.group")
|
||||
|
||||
// 修复大概率遗漏http://,curl请求会直接失败
|
||||
if nacosHost != "" && nacosHost[:7] != "http://" && nacosHost[:8] != "https://" {
|
||||
nacosHost = "http://" + nacosHost
|
||||
// 标准URL解析,彻底解决重复拼接http://BUG
|
||||
func getNacosBaseUrl() string {
|
||||
addr := nacosCfg.Hosts[0]
|
||||
// 判断开头有没有http/https协议
|
||||
if strings.HasPrefix(addr, "http://") || strings.HasPrefix(addr, "https://") {
|
||||
return addr
|
||||
}
|
||||
// 无协议强制加上 http://
|
||||
return "http://" + addr
|
||||
}
|
||||
|
||||
func fetchNacosConfig() (string, string, error) {
|
||||
uri := fmt.Sprintf(
|
||||
"nacos/v1/cs/configs?dataId=%s&group=%s&tenant=%s",
|
||||
url.QueryEscape(dataId),
|
||||
url.QueryEscape(group),
|
||||
url.QueryEscape(namespace),
|
||||
// 请求Nacos配置接口
|
||||
func fetchNacosConfig() (content string, md5Str string, err error) {
|
||||
baseUrl := getNacosBaseUrl()
|
||||
fullUrl := fmt.Sprintf(
|
||||
"%s/nacos/v1/cs/configs?dataId=%s&group=%s&tenant=%s",
|
||||
baseUrl,
|
||||
url.QueryEscape(nacosCfg.ConfigID),
|
||||
url.QueryEscape(nacosCfg.Group),
|
||||
url.QueryEscape(nacosCfg.NamespaceId),
|
||||
)
|
||||
|
||||
body, err := Curl(nacosHost).Get(uri)
|
||||
body, err := Curl(fullUrl).Get("")
|
||||
if err != nil {
|
||||
return "", "", fmt.Errorf("curl请求nacos失败: %w", err)
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
hash := md5.Sum([]byte(body))
|
||||
md5Str := hex.EncodeToString(hash[:])
|
||||
md5Str = hex.EncodeToString(hash[:])
|
||||
return body, md5Str, nil
|
||||
}
|
||||
|
||||
// MD5比对写入本地文件
|
||||
func fetchNacosAndSaveRunToml() error {
|
||||
body, newMd5, err := fetchNacosConfig()
|
||||
content, newMd5, err := fetchNacosConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// MD5一致无需更新
|
||||
if currentMd5 == newMd5 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 写入本地文件
|
||||
err = os.WriteFile("run.toml", []byte(body), 0644)
|
||||
err = os.WriteFile("run.toml", []byte(content), 0644)
|
||||
if err != nil {
|
||||
return fmt.Errorf("写入run.toml失败: %w", err)
|
||||
}
|
||||
|
||||
currentMd5 = newMd5
|
||||
fmt.Println("Nacos配置拉取成功,已缓存至本地run.toml")
|
||||
return nil
|
||||
}
|
||||
|
||||
// 加载本地配置,增加降级容错
|
||||
func loadRunToml() {
|
||||
runViper.SetConfigFile("run.toml")
|
||||
if err := runViper.ReadInConfig(); err != nil {
|
||||
panic(fmt.Sprintf("run.toml 缺失 %s ", err))
|
||||
err := runViper.ReadInConfig()
|
||||
if err != nil {
|
||||
fmt.Printf("run.toml本地缓存不存在: %v\n当前仅内置默认密钥、超时配置生效,数据库等远端配置缺失,服务无法正常运行\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
runViper.WatchConfig()
|
||||
runViper.OnConfigChange(func(e fsnotify.Event) {
|
||||
fmt.Println("run.toml文件变更,自动重载配置")
|
||||
_ = runViper.ReadInConfig()
|
||||
})
|
||||
}
|
||||
|
||||
// 5分钟定时同步远端配置
|
||||
func startFixedIntervalSync() {
|
||||
go func() {
|
||||
ticker := time.NewTicker(5 * time.Minute)
|
||||
@@ -153,14 +135,8 @@ func startFixedIntervalSync() {
|
||||
for range ticker.C {
|
||||
err := fetchNacosAndSaveRunToml()
|
||||
if err != nil {
|
||||
fmt.Errorf("run.toml 缺失 %w ", err)
|
||||
continue
|
||||
fmt.Printf("定时同步Nacos异常: %v\n", err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func getWorkDir() string {
|
||||
dir, _ := os.Getwd()
|
||||
return dir
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user