配置中心調(diào)研,以及簡單的使用

什么是配置

應(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

Ncos官方文檔

  • 動態(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)和配置拉取的邏輯.

1.jpeg
  • 用戶通過控制臺集中對多個(gè)服務(wù)的配置進(jìn)行管理配置
  • 各個(gè)服務(wù)統(tǒng)一從Nacos server集群中獲取各自的配置,并監(jiān)聽配置的變化.
Nacos的安裝部署
config.jpg
  • 編輯配置頁面
edit_config.jpg
  • 權(quán)限控制
power.jpg
  • 命名空間,可根據(jù)命名空間,區(qū)分:測試,灰度,生產(chǎn)
namespace.jpg
  • 集群節(jié)點(diǎn)管理:分布式部署,高可用
node.jpg
  • 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)用
image
服務(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腻格。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市啥繁,隨后出現(xiàn)的幾起案子菜职,更是在濱河造成了極大的恐慌,老刑警劉巖旗闽,帶你破解...
    沈念sama閱讀 219,539評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件酬核,死亡現(xiàn)場離奇詭異,居然都是意外死亡适室,警方通過查閱死者的電腦和手機(jī)嫡意,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評論 3 396
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來亭病,“玉大人鹅很,你說我怎么就攤上這事∽锾” “怎么了促煮?”我有些...
    開封第一講書人閱讀 165,871評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長整袁。 經(jīng)常有香客問我菠齿,道長,這世上最難降的妖魔是什么坐昙? 我笑而不...
    開封第一講書人閱讀 58,963評論 1 295
  • 正文 為了忘掉前任绳匀,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘疾棵。我一直安慰自己戈钢,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,984評論 6 393
  • 文/花漫 我一把揭開白布是尔。 她就那樣靜靜地躺著殉了,像睡著了一般。 火紅的嫁衣襯著肌膚如雪拟枚。 梳的紋絲不亂的頭發(fā)上薪铜,一...
    開封第一講書人閱讀 51,763評論 1 307
  • 那天,我揣著相機(jī)與錄音恩溅,去河邊找鬼隔箍。 笑死,一個(gè)胖子當(dāng)著我的面吹牛脚乡,可吹牛的內(nèi)容都是我干的蜒滩。 我是一名探鬼主播,決...
    沈念sama閱讀 40,468評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼每窖,長吁一口氣:“原來是場噩夢啊……” “哼帮掉!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起窒典,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎稽莉,沒想到半個(gè)月后瀑志,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,850評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡污秆,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,002評論 3 338
  • 正文 我和宋清朗相戀三年劈猪,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片良拼。...
    茶點(diǎn)故事閱讀 40,144評論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡战得,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出庸推,到底是詐尸還是另有隱情常侦,我是刑警寧澤,帶...
    沈念sama閱讀 35,823評論 5 346
  • 正文 年R本政府宣布贬媒,位于F島的核電站聋亡,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏际乘。R本人自食惡果不足惜坡倔,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,483評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧罪塔,春花似錦投蝉、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至请契,卻和暖如春咳榜,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背爽锥。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評論 1 272
  • 我被黑心中介騙來泰國打工涌韩, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人氯夷。 一個(gè)月前我還...
    沈念sama閱讀 48,415評論 3 373
  • 正文 我出身青樓臣樱,卻偏偏與公主長得像,于是被迫代替她去往敵國和親腮考。 傳聞我的和親對象是個(gè)殘疾皇子雇毫,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,092評論 2 355

推薦閱讀更多精彩內(nèi)容