什么是配置
應(yīng)用程序在啟動和運(yùn)行的時(shí)候往往讀取一些配置數(shù)據(jù),配置程序基本伴隨著應(yīng)用程序的整個(gè)聲明周期.
比如:數(shù)據(jù)庫的連接參數(shù),啟動參數(shù)等.
配置的特點(diǎn)
- 獨(dú)立于程度的只讀變量
- 伴隨應(yīng)用的整個(gè)生命周期
- 配置可以有多種加載配置方式
- 配置文件
- 環(huán)境變量
- 配置需要治理
同一份程序在不同的環(huán)境(開發(fā),測試,仿真,生產(chǎn)),經(jīng)常需要不同的配置,所以需要完善的環(huán)境,集群配置管理
什么是配置中心
當(dāng)系統(tǒng)從一個(gè)單體服務(wù)拆分成若干個(gè)服務(wù)節(jié)點(diǎn)后,也就是咱們所說的:分布式服務(wù),配置文件也必須跟著遷移,
這樣配置也就太分散了,不僅如此,分散中還包含冗余.每個(gè)微服務(wù)都需要一份配置文件.
配置中心將配置從各應(yīng)用剝離出來,對配置進(jìn)行統(tǒng)一管理,應(yīng)用自身不需要自己再去管理配置
配置中心的服務(wù)流程
- 用戶在配置中心發(fā)布,更新配置信息.
- 服務(wù)A和服務(wù)B及時(shí)得到配置更新通知,從配置中心獲取配置.
- 總的來說,配置中心就是一種統(tǒng)一管理各種應(yīng)用配置的基礎(chǔ)服務(wù)組件.
為什么需要配置中心
隨著分布式微服務(wù)的發(fā)展,服務(wù)節(jié)點(diǎn)越來越多,配置問題逐漸顯現(xiàn)出來.
- 隨著程序功能的日益復(fù)雜,程序的配置也越來越復(fù)雜,各種配置,服務(wù)器之間的地址.
- 大量模塊使用各自的配置,會導(dǎo)致運(yùn)維管理繁瑣,各個(gè)節(jié)點(diǎn)配置不一致等問題.
- 對配置的期望也越來越高,配置修改后,實(shí)時(shí)生效,灰度發(fā)布,版本管理,環(huán)境區(qū)分等
在這樣的大環(huán)境下,傳統(tǒng)的通過修改配置文件,數(shù)據(jù)庫等方式已經(jīng)越來越無法滿足開發(fā)人員對配置管理的需求.
配置中心要滿足如下特性
- 配置項(xiàng)容易修改和讀取
- 遠(yuǎn)程管理配置的功能
- 支持對配置的修改內(nèi)容的監(jiān)視,把控風(fēng)險(xiǎn).
- 可以查看配置的修改記錄
- 不同環(huán)境下,應(yīng)用配置之間的隔離性.
開源的配置中心
- disconf(百度)--官方已經(jīng)不維護(hù)
- Spring Cloud Config
Spring Cloud開源組件,可以和Spring Cloud無縫整合,但需以來git或者svn
- Apollo
攜程開源配置中心,具備規(guī)范的權(quán)限,流程治理等特性
- Nacos
阿里開源配置中心,其中包含注冊中心和配置中心.
下面只說nacos和apollo
Nacos
- 動態(tài)服務(wù)配置可以讓你以中心化,外部化和動態(tài)化的方式管理所有環(huán)境的應(yīng)用配置和服務(wù)配置.
- 動態(tài)部署消除了配置變更時(shí)重新部署應(yīng)用和服務(wù)的需要,讓配置管理變得更加高效和便捷.
- 配置中心化管理,讓實(shí)現(xiàn)無狀態(tài)服務(wù)變得更加簡單,讓服務(wù)按需彈性擴(kuò)展變得更容易.
- 提供了簡潔易用的ui界面,幫助管理所有的服務(wù)和應(yīng)用配置.
- 還提供了包括版本跟蹤,灰度發(fā)布,一鍵回滾配置以及客戶端配置更新狀態(tài)跟蹤在內(nèi)的一系列開箱即用的配置管理特性.幫助你更安全的在生產(chǎn)環(huán)境中管理配置變更和降低配置變更帶來的風(fēng)險(xiǎn).
架構(gòu)
Nacos配置中心分為server和client,server采用javab編寫,為client提供服務(wù)配置.
Client可以用多種語言實(shí)現(xiàn),Nacos提供Sdk和OpenApi,如果沒有SDK也可用OpenApi手寫服務(wù)注冊與發(fā)現(xiàn)和配置拉取的邏輯.
- 用戶通過控制臺集中對多個(gè)服務(wù)的配置進(jìn)行管理配置
- 各個(gè)服務(wù)統(tǒng)一從Nacos server集群中獲取各自的配置,并監(jiān)聽配置的變化.
Nacos的安裝部署
- docker-compose安裝
- 微服務(wù)引擎 阿里云服務(wù)
- 安裝界面
- 配置管理頁面
- 編輯配置頁面
- 權(quán)限控制
- 命名空間,可根據(jù)命名空間,區(qū)分:測試,灰度,生產(chǎn)
- 集群節(jié)點(diǎn)管理:分布式部署,高可用
- golang 配置讀取以及動態(tài)更新
// @Author: chimojiacai
// @Description: nacos 配種中心
// @File: nacos
// @Date: 2021/8/15 21:18
package config
import (
"fmt"
"github.com/nacos-group/nacos-sdk-go/clients"
"github.com/nacos-group/nacos-sdk-go/common/constant"
"github.com/nacos-group/nacos-sdk-go/vo"
)
func NewNacosConfig() string {
clientConfig := constant.ClientConfig{
TimeoutMs: 10 * 1000, //http請求超時(shí)時(shí)間,單位毫秒
ListenInterval: 30 * 1000, //監(jiān)聽間隔時(shí)間框杜,單位毫秒(僅在ConfigClient中有效)
BeatInterval: 5 * 1000, //心跳間隔時(shí)間旅敷,單位毫秒(僅在ServiceClient中有效)
NamespaceId: "", //nacos命名空間
Endpoint: "", //獲取nacos節(jié)點(diǎn)ip的服務(wù)地址
CacheDir: "", //緩存目錄
LogDir: "", //日志目錄
UpdateThreadNum: 20, //更新服務(wù)的線程數(shù)
NotLoadCacheAtStart: true, //在啟動時(shí)不讀取本地緩存數(shù)據(jù)枣申,true--不讀取岸啡,false--讀取
UpdateCacheWhenEmpty: true, //當(dāng)服務(wù)列表為空時(shí)是否更新本地緩存塘匣,true--更新,false--不更新
}
// 至少一個(gè)(集群可以多個(gè))
serverConfigs := []constant.ServerConfig{
{
IpAddr: "127.0.0.1", // nacos節(jié)點(diǎn)配置
ContextPath: "/nacos", // contextPath
Port: 8848, // 端口號
},
}
// 創(chuàng)建動態(tài)配置客戶端的另一種方式 (推薦)
configClient, err := clients.NewConfigClient(
vo.NacosClientParam{
ClientConfig: &clientConfig,
ServerConfigs: serverConfigs,
},
)
if err != nil {
panic(err)
return ""
}
// 監(jiān)控配置更新
err = configClient.ListenConfig(vo.ConfigParam{
DataId: "ceshi",
Group: "DEFAULT_GROUP",
OnChange: func(namespace, group, dataId, data string) {
// 合并配置
buffer := bytes.NewBuffer([]byte(data))
err2 := viper.MergeConfig(buffer)
fmt.Println(err2) // 這里可以發(fā)送郵件
fmt.Println(viper.GetString("app_name"))
fmt.Println("group:" + group + ", dataId:" + dataId + ", data:\n" + data)
},
})
if err != nil {
panic(err)
return ""
}
// 獲取配置
content, err := configClient.GetConfig(vo.ConfigParam{
DataId: "ceshi",
Group: "DEFAULT_GROUP",
OnChange: func(namespace, group, dataId, data string) {
fmt.Println("group:" + group + ", dataId:" + dataId + ", data:" + data)
},
})
if err != nil || content == "" {
panic(err)
return ""
}
fmt.Println("content:" + content)
return content
}
- 總結(jié)
- Nacos使用簡單硕盹、部署方便内斯、性能較高,能夠?qū)崿F(xiàn)基本的配置管理净薛,提供的控制臺也非常簡潔汪榔。
- 權(quán)限方面控制粒度較粗,且沒有審核機(jī)制
Apollo
簡介
Apollo:分布式配置中心,能夠集中化管理應(yīng)用的不同環(huán)境,不同集群的配置,配置修改后能實(shí)時(shí)推送到應(yīng)用端,并且具備規(guī)范的權(quán)限,流程治理等特性,適用于微服務(wù)配置管理場景.
Apollo包括服務(wù)端和客戶端兩部分.
特性
- 統(tǒng)一管理不同環(huán)境,不同集群配置
- 配置修改實(shí)時(shí)生效(熱更新)
用戶在Apollo修改完配置并發(fā)布后肃拜,客戶端能實(shí)時(shí)(1秒)接收到最新的配置痴腌,并通知到應(yīng)用程序
- 版本發(fā)布管理
配置發(fā)布都有版本概念雌团,從而可以方便地支持配置的回滾
- 測試,灰度,生產(chǎn)等多環(huán)境配置
支持配置的灰度發(fā)布,比如點(diǎn)了發(fā)布后士聪,只對部分應(yīng)用實(shí)例生效锦援,等觀察一段時(shí)間沒問題后再推給所有應(yīng)用實(shí)例
- 權(quán)限管理,發(fā)布審核,操作審計(jì)(比nacos好).
應(yīng)用和配置的管理都有完善的權(quán)限管理機(jī)制,對配置的管理還分為了編輯和發(fā)布兩個(gè)環(huán)節(jié)剥悟,從而減少人為的錯誤灵寺。
所有的操作都有審計(jì)日志,可以方便的追蹤問題
- 客戶端配置信息監(jiān)控
可以在界面上方便地看到配置在被哪些實(shí)例使用
提供開發(fā)平臺api和sdk(第三方的)
-
Apollo支持4個(gè)維度管理Key-Value格式的配置:
- application (應(yīng)用)
- environment (環(huán)境)
- cluster (集群)
- namespace (命名空間)
通過命名空間(namespace)可以很方便的支持多個(gè)不同應(yīng)用共享同一份配置懦胞,同時(shí)還允許應(yīng)用對共享的配置進(jìn)行覆蓋
文檔中心
基礎(chǔ)模型
- 用戶在配置中心對配置進(jìn)行修改并發(fā)布
- 配置中心通知Apollo客戶端有配置更新
- Apollo客戶端從配置中心拉取最新的配置替久、更新本地配置并通知到應(yīng)用
服務(wù)端設(shè)計(jì)
[站外圖片上傳中...(image-9d0374-1631951517555)]
- 用戶在Portal操作配置發(fā)布
- Portal調(diào)用Admin Service的接口操作發(fā)布
- Admin Service發(fā)布配置后,發(fā)送ReleaseMessage給各個(gè)Config Service
- Config Service收到ReleaseMessage后躏尉,通知對應(yīng)的客戶端
客戶端設(shè)計(jì)
[站外圖片上傳中...(image-73fdb5-1631951517555)]
- 客戶端和服務(wù)端保持了一個(gè)長連接,從而能第一時(shí)間獲得配置更新的推送后众。(通過Http Long Polling實(shí)現(xiàn))
- 客戶端還會定時(shí)從Apollo配置中心服務(wù)端拉取應(yīng)用的最新配置胀糜。
- 這是一個(gè)fallback機(jī)制,為了防止推送機(jī)制失效導(dǎo)致配置不更新
- 客戶端定時(shí)拉取會上報(bào)本地版本蒂誉,所以一般情況下教藻,對于定時(shí)拉取的操作,服務(wù)端都會返回304 - Not Modified
- 定時(shí)頻率默認(rèn)為每5分鐘拉取一次右锨,客戶端也可以通過在運(yùn)行時(shí)指定System Property: apollo.refreshInterval來覆蓋括堤,單位為分鐘。
- 客戶端從Apollo配置中心服務(wù)端獲取到應(yīng)用的最新配置后绍移,會保存在內(nèi)存中
- 客戶端會把從服務(wù)端獲取到的配置在本地文件系統(tǒng)緩存一份
- 在遇到服務(wù)不可用悄窃,或網(wǎng)絡(luò)不通的時(shí)候,依然能從本地恢復(fù)配置
- 應(yīng)用程序可以從Apollo客戶端獲取最新的配置蹂窖、訂閱配置更新通知
部署文檔
使用
-
首頁
shouye.jpg -
系統(tǒng)配置管理
system.jpg -
應(yīng)用配置-配置部門
appconfig.jpg -
namespace 創(chuàng)建-私有的才能自定義文件格式,否則默認(rèn)properties格式
namespace.jpg -
創(chuàng)建配置文件-點(diǎn)擊對號保存,點(diǎn)擊發(fā)布則更新到app里
config.jpg -
歷史版本回滾-可以diff rollback.jpg
-
查看實(shí)例
node.jpg -
權(quán)限管理
power.jpg golang 配置讀取以及動態(tài)更新
// @Author: chimojiacai
// @Description:
// @File: apollo2
// @Date: 2021/8/22 00:23
package config
import (
"bytes"
"fmt"
"github.com/shima-park/agollo"
"github.com/spf13/cast"
"github.com/spf13/viper"
)
func NewApollo2Config() {
a, err := agollo.New("127.0.0.1:81", "123456", agollo.DefaultNamespace("avtivity1.txt"),agollo.AccessKey("1ae5a4a672db4526a726355f87336f58"))
if err != nil {
panic(err)
}
fmt.Println(
// 默認(rèn)讀取Namespace:application下key: foo的value
a.Get("app_name"),
// 獲取namespace為test.json的所有配置項(xiàng)
a.GetNameSpace("avtivity1.txt"),
// 當(dāng)key:foo不存在時(shí)轧抗,提供一個(gè)默認(rèn)值bar
a.Get("foo", agollo.WithDefault("bar")),
//// 讀取Namespace為other_namespace, key: foo的value
//a.Get("foo", agollo.WithNamespace("other_namespace")),
)
errorCh := a.Start() // Start后會啟動goroutine監(jiān)聽變化,并更新agollo對象內(nèi)的配置cache
// 或者忽略錯誤處理直接 a.Start()
watchCh := a.Watch()
// 啟動監(jiān)聽配置變化
go func() {
for{
select{
case err := <- errorCh:
fmt.Println(err) // 處理異常
case resp := <-watchCh:
//fmt.Println(
// "Namespace:", resp.Namespace,
// "OldValue:", resp.OldValue,
// "NewValue:", resp.NewValue,
// "Error:", resp.Error,
//)
// 合并配置
buffer := bytes.NewBuffer([]byte(cast.ToString(resp.NewValue["content"])))
err2 := viper.MergeConfig(buffer)
fmt.Println(err2) // 這里可以發(fā)送郵件
fmt.Println(viper.GetString("app_name"))
}
}
}()
}
- 總結(jié)
- Apollo在配置管理流程上比較完善瞬测,相應(yīng)配置的發(fā)布審核横媚、權(quán)限管理等、配置的繼承等月趟,但Apollo需要使用人員進(jìn)行簡單學(xué)習(xí)灯蝴,存在學(xué)習(xí)成本。
- Appollo部署較為復(fù)雜需要3個(gè)模塊同時(shí)工作孝宗,部署一套生產(chǎn)高可用集群至少需要7
個(gè)節(jié)點(diǎn)穷躁。(可使用docker解決)
nacos和apollo總結(jié)
對比項(xiàng)目 | nacos | apollo |
---|---|---|
配置實(shí)時(shí)推送 | 支持(1s) | 支持(1s內(nèi)) |
版本管理(回滾) | 支持 | 支持 |
權(quán)限管理 | 支持(粗顆粒度) | 支持(細(xì)顆粒度) |
灰度發(fā)布 | 支持 | 支持 |
集群 | 支持 | 支持 |
監(jiān)聽查詢 | 支持 | 支持 |
多語言 | Go,Java,Python,C++,.Net,OpenApi | Java,Python,Nodejs,OpenApi |
配置格式校驗(yàn) | 支持 | 支持 |
通信協(xié)議 | http | http |
單機(jī)讀(tps) | 15000 | 9000 |
單機(jī)寫(tps) | 1800 | 1100 |
nacos官方支持go sdk
apollo第三方go sdk
結(jié)論
從配置中心角度來看,性能方面Nacos的讀寫性能最高碳褒,Apollo次之;功能方面Apollo最為完善折砸,但Nacos具有Apollo大部分配置管理功能看疗。Nacos的一大優(yōu)勢是整合了注冊中心、配置中心功能睦授,部署和操作相比 Apollo都要直觀簡單两芳,因此它簡化了架構(gòu)復(fù)雜度,并減輕運(yùn)維及部署工作去枷。
總的來看怖辆,Apollo和Nacos生態(tài)支持都很廣泛,在配置管理流程上做的都很好删顶。Apollo相對于Nacos在配置管理做的更加全面;Nacos則使用起來相對比較簡潔竖螃,在對性能要求比較高的大規(guī)模場景更適合。
對于修改配置的次數(shù)不是特別的頻繁逗余,對于配置權(quán)限的管理不是特別嚴(yán)格的特咆,且對讀寫性能有一定要求的,可采用Nacos录粱,反之使用Apollo腻格。