Go 語言微服務(wù)框架 Kratos 怎么讀取配置?
1.介紹
微服務(wù)框架 Kratos 提供了一個(gè)強(qiáng)大的配置管理模塊 - config 組件,它支持加載、解析、動態(tài)更新配置。
它支持多種配置源,例如文件(JSON、YAML、TOML 等格式)、環(huán)境變量、遠(yuǎn)程配置中心(如 Apollo、Etcd)等。
2.config 組件
Kratos 的 config 組件的核心功能包括支持多種配置源、動態(tài)更新、類型安全、擴(kuò)展性。
其中,類型安全是指通過結(jié)構(gòu)體綁定,將配置數(shù)據(jù)加載到 Go 的結(jié)構(gòu)體中;擴(kuò)展性是指可以通過實(shí)現(xiàn) config.Source 接口,擴(kuò)展自定義配置源。
此外,它還有 config.Decoder 解析器接口,可以將配置內(nèi)容解析為結(jié)構(gòu)化數(shù)據(jù);config.Loader 管理配置的核心組件,可以從多個(gè)配置源加載和合并配置。
3.配置源
我們通過示例代碼,分別介紹通過 config 組件管理的多種配置源。
文件
func init() {
flag.StringVar(&flagconf, "conf", "../../configs", "config path, eg: -conf config.yaml")
}
func main() {
flag.Parse()
// 加載配置文件
c := config.New(
config.WithSource(
file.NewSource(flagconf),
),
)
defer c.Close()
// 加載配置
if err := c.Load(); err != nil {
panic(err)
}
// 獲取配置
var bc conf.Bootstrap
if err := c.Scan(&bc); err != nil {
panic(err)
}
// ...
}
閱讀上面這段代碼,我們可以發(fā)現(xiàn)使用 config 組件讀取配置,總共需要三步,一是使用 config.New() 加載配置文件,返回一個(gè) Config 接口,示例代碼中使用 file.NewSource() 獲取 blog/configs 目錄中的配置文件。
// Config is a config interface.
type Config interface {
Load() error
Scan(v interface{}) error
Value(key string) Value
Watch(key string, o Observer) error
Close() error
}
二是使用 Load() 方法加載配置,也就是讀取配置內(nèi)容。
三是使用 Scan() 方法獲取配置,也就是將配置內(nèi)容解析為結(jié)構(gòu)化數(shù)據(jù)。
需要注意的是,不要忘記執(zhí)行 Close() 方法。
環(huán)境變量
使用 Karatos 的 config 組件讀取環(huán)境變量中的配置,只需要在 config.WithSource() 方法中,添加環(huán)境變量配置源。
// 加載配置文件
c := config.New(
config.WithSource(
file.NewSource(flagconf),
env.NewSource(),
),
)
defer c.Close()
讀取環(huán)境變量中的配置,一般不會使用 Scan() 方法,將獲取到的配置解析到結(jié)構(gòu)體中。
一般是使用 Value() 方法,直接讀取鍵值對,例如:
// 讀取環(huán)境變量
port, err := c.Value("PORT").String() // 讀取環(huán)境變量 PORT
if err != nil || port == "" {
port = "8080" // 默認(rèn)值
}
fmt.Println("Port:", port)
// 讀取其他配置
dbHost, err := c.Value("DB_HOST").String() // 讀取環(huán)境變量 DB_HOST
if err == nil {
fmt.Println("Database Host:", dbHost)
}
需要注意的是,使用 Value() 方法,讀取環(huán)境變量值,key 區(qū)分大小寫。
遠(yuǎn)程配置中心
我們以 apolloconfig 為例,介紹怎么使用 Kartos 的 config 組件讀取遠(yuǎn)程配置中心的配置。
首先,我們需要安裝依賴。
go get github.com/go-kratos/kratos/contrib/config/apollo/v2
因?yàn)?Kratos 為我們提供了讀取 apolloconfig 的依賴庫,所以我們只需使用依賴庫初始化 apolloconfig 配置源。
// 初始化 Apollo 配置源
apolloSource := apollo.NewSource(
apollo.WithEndpoint("http://192.168.110.209:8080"), // Apollo 服務(wù)地址
apollo.WithAppID("SampleApp"), // 應(yīng)用 ID
apollo.WithCluster("default"), // 集群
apollo.WithNamespace("application.properties"), // Namespace
apollo.WithEnableBackup(), // 啟用本地備份
)
然后,將配置源 apolloSource,添加進(jìn)去。
// 加載配置文件
c := config.New(
config.WithSource(
file.NewSource(flagconf),
env.NewSource(),
apolloSource,
),
)
最后,我們可以使用 Scan() 方法,解析到結(jié)構(gòu)體中。也可以直接讀取鍵值,此處,我們以直接讀取鍵值為例,示例代碼:
timeout, err := c.Value("application.timeout").String()
if err != nil {
panic(err)
}
fmt.Printf("timeout: %s\n", timeout)
運(yùn)行項(xiàng)目,輸出結(jié)果:
kratos run
timeout: 100
當(dāng)然,我們每次修改配置時(shí),都需要重啟項(xiàng)目,為了避免重啟項(xiàng)目,我們可以使用 Watch() 方法,動態(tài)監(jiān)聽配置變化,示例代碼:
// 動態(tài)監(jiān)聽配置變化
err = c.Watch("application", myObserver)
if err != nil {
fmt.Println("Error watching config:", err)
return
}
閱讀上面這段代碼,我們可以發(fā)現(xiàn) Watch() 方法的參數(shù)有 2 個(gè),分別是 application 和 myObserver。
其中,application 是 apolloconfig 的 Namespace,myObserver 是監(jiān)聽函數(shù)。
// Observer 函數(shù)
func myObserver(key string, value config.Value) {
fmt.Printf("Config updated! Key: %s, New Value: %v\n", key, value.Load())
}
重新運(yùn)行項(xiàng)目,每次修改 apolloconfig 中的配置,我們可以看到以下打印結(jié)果:
Config updated! Key: application, New Value: map[timeout:200]
4.總結(jié)
本文介紹了 Kartos 怎么使用 config 組件,讀取配置。
通過示例代碼,分別介紹了讀取配置文件、環(huán)境變量和遠(yuǎn)程配置中心 apolloconfig 的實(shí)現(xiàn)方式。
當(dāng)然,如果我們不想使用 Kartos 的 config 組件讀取 apolloconfig 配置,而是想使用 Viper 讀取 apolloconfig 配置。
可以使用 apolloconfig 的客戶端 API 或三方庫,比如:github.com/apolloconfig/agollo/v4,將 apolloconfig 的配置加載到 Viper 中。
限于篇幅,本文沒有介紹怎么使用 Viper 讀取 apolloconfig 中的配置,感興趣的讀者朋友們,可以自行嘗試實(shí)現(xiàn)。