配置中心調研,以及簡單的使用

什么是配置

應用程序在啟動和運行的時候往往讀取一些配置數據,配置程序基本伴隨著應用程序的整個聲明周期.
比如:數據庫的連接參數,啟動參數等.

配置的特點

  • 獨立于程度的只讀變量
  • 伴隨應用的整個生命周期
  • 配置可以有多種加載配置方式
    • 配置文件
    • 環境變量
  • 配置需要治理
同一份程序在不同的環境(開發,測試,仿真,生產),經常需要不同的配置,所以需要完善的環境,集群配置管理

什么是配置中心

當系統從一個單體服務拆分成若干個服務節點后,也就是咱們所說的:分布式服務,配置文件也必須跟著遷移,
這樣配置也就太分散了,不僅如此,分散中還包含冗余.每個微服務都需要一份配置文件.
配置中心將配置從各應用剝離出來,對配置進行統一管理,應用自身不需要自己再去管理配置

配置中心的服務流程
  • 用戶在配置中心發布,更新配置信息.
  • 服務A和服務B及時得到配置更新通知,從配置中心獲取配置.
    • 總的來說,配置中心就是一種統一管理各種應用配置的基礎服務組件.
為什么需要配置中心

隨著分布式微服務的發展,服務節點越來越多,配置問題逐漸顯現出來.

  • 隨著程序功能的日益復雜,程序的配置也越來越復雜,各種配置,服務器之間的地址.
  • 大量模塊使用各自的配置,會導致運維管理繁瑣,各個節點配置不一致等問題.
  • 對配置的期望也越來越高,配置修改后,實時生效,灰度發布,版本管理,環境區分等

在這樣的大環境下,傳統的通過修改配置文件,數據庫等方式已經越來越無法滿足開發人員對配置管理的需求.

配置中心要滿足如下特性
  • 配置項容易修改和讀取
  • 遠程管理配置的功能
  • 支持對配置的修改內容的監視,把控風險.
  • 可以查看配置的修改記錄
  • 不同環境下,應用配置之間的隔離性.

開源的配置中心

  • disconf(百度)--官方已經不維護
  • Spring Cloud Config
Spring Cloud開源組件,可以和Spring Cloud無縫整合,但需以來git或者svn
  • Apollo
攜程開源配置中心,具備規范的權限,流程治理等特性
  • Nacos
阿里開源配置中心,其中包含注冊中心和配置中心.

下面只說nacos和apollo

Nacos

Ncos官方文檔

  • 動態服務配置可以讓你以中心化,外部化和動態化的方式管理所有環境的應用配置和服務配置.
  • 動態部署消除了配置變更時重新部署應用和服務的需要,讓配置管理變得更加高效和便捷.
  • 配置中心化管理,讓實現無狀態服務變得更加簡單,讓服務按需彈性擴展變得更容易.
  • 提供了簡潔易用的ui界面,幫助管理所有的服務和應用配置.
  • 還提供了包括版本跟蹤,灰度發布,一鍵回滾配置以及客戶端配置更新狀態跟蹤在內的一系列開箱即用的配置管理特性.幫助你更安全的在生產環境中管理配置變更和降低配置變更帶來的風險.
架構

Nacos配置中心分為server和client,server采用javab編寫,為client提供服務配置.
Client可以用多種語言實現,Nacos提供Sdk和OpenApi,如果沒有SDK也可用OpenApi手寫服務注冊與發現和配置拉取的邏輯.

1.jpeg
  • 用戶通過控制臺集中對多個服務的配置進行管理配置
  • 各個服務統一從Nacos server集群中獲取各自的配置,并監聽配置的變化.
Nacos的安裝部署
config.jpg
  • 編輯配置頁面
edit_config.jpg
  • 權限控制
power.jpg
  • 命名空間,可根據命名空間,區分:測試,灰度,生產
namespace.jpg
  • 集群節點管理:分布式部署,高可用
node.jpg
  • golang 配置讀取以及動態更新
// @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請求超時時間,單位毫秒
        ListenInterval:       30 * 1000, //監聽間隔時間,單位毫秒(僅在ConfigClient中有效)
        BeatInterval:         5 * 1000,  //心跳間隔時間,單位毫秒(僅在ServiceClient中有效)
        NamespaceId:          "",        //nacos命名空間
        Endpoint:             "",        //獲取nacos節點ip的服務地址
        CacheDir:             "",        //緩存目錄
        LogDir:               "",        //日志目錄
        UpdateThreadNum:      20,        //更新服務的線程數
        NotLoadCacheAtStart:  true,      //在啟動時不讀取本地緩存數據,true--不讀取,false--讀取
        UpdateCacheWhenEmpty: true,      //當服務列表為空時是否更新本地緩存,true--更新,false--不更新
    }

    // 至少一個(集群可以多個)
    serverConfigs := []constant.ServerConfig{
        {
            IpAddr:      "127.0.0.1", // nacos節點配置
            ContextPath: "/nacos", // contextPath
            Port:        8848, // 端口號
        },
    }

    // 創建動態配置客戶端的另一種方式 (推薦)
    configClient, err := clients.NewConfigClient(
        vo.NacosClientParam{
            ClientConfig:  &clientConfig,
            ServerConfigs: serverConfigs,
        },
    )
    if err != nil {
        panic(err)
        return ""
    }

    // 監控配置更新
    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) // 這里可以發送郵件
            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
}

  • 總結
    • Nacos使用簡單、部署方便、性能較高,能夠實現基本的配置管理,提供的控制臺也非常簡潔。
    • 權限方面控制粒度較粗,且沒有審核機制

Apollo

簡介

Apollo:分布式配置中心,能夠集中化管理應用的不同環境,不同集群的配置,配置修改后能實時推送到應用端,并且具備規范的權限,流程治理等特性,適用于微服務配置管理場景.
Apollo包括服務端和客戶端兩部分.

特性
  • 統一管理不同環境,不同集群配置
  • 配置修改實時生效(熱更新)
用戶在Apollo修改完配置并發布后,客戶端能實時(1秒)接收到最新的配置,并通知到應用程序
  • 版本發布管理
配置發布都有版本概念,從而可以方便地支持配置的回滾 
  • 測試,灰度,生產等多環境配置
支持配置的灰度發布,比如點了發布后,只對部分應用實例生效,等觀察一段時間沒問題后再推給所有應用實例 
  • 權限管理,發布審核,操作審計(比nacos好).
應用和配置的管理都有完善的權限管理機制,對配置的管理還分為了編輯和發布兩個環節,從而減少人為的錯誤。 
所有的操作都有審計日志,可以方便的追蹤問題 
  • 客戶端配置信息監控
可以在界面上方便地看到配置在被哪些實例使用 
  • 提供開發平臺api和sdk(第三方的)

  • Apollo支持4個維度管理Key-Value格式的配置:

    • application (應用)
    • environment (環境)
    • cluster (集群)
    • namespace (命名空間)
      通過命名空間(namespace)可以很方便的支持多個不同應用共享同一份配置,同時還允許應用對共享的配置進行覆蓋
文檔中心

文檔中心

基礎模型
  • 用戶在配置中心對配置進行修改并發布
  • 配置中心通知Apollo客戶端有配置更新
  • Apollo客戶端從配置中心拉取最新的配置、更新本地配置并通知到應用
image
服務端設計

[站外圖片上傳中...(image-9d0374-1631951517555)]

  • 用戶在Portal操作配置發布
  • Portal調用Admin Service的接口操作發布
  • Admin Service發布配置后,發送ReleaseMessage給各個Config Service
  • Config Service收到ReleaseMessage后,通知對應的客戶端
客戶端設計

[站外圖片上傳中...(image-73fdb5-1631951517555)]

  • 客戶端和服務端保持了一個長連接,從而能第一時間獲得配置更新的推送。(通過Http Long Polling實現)
  • 客戶端還會定時從Apollo配置中心服務端拉取應用的最新配置。
    • 這是一個fallback機制,為了防止推送機制失效導致配置不更新
    • 客戶端定時拉取會上報本地版本,所以一般情況下,對于定時拉取的操作,服務端都會返回304 - Not Modified
    • 定時頻率默認為每5分鐘拉取一次,客戶端也可以通過在運行時指定System Property: apollo.refreshInterval來覆蓋,單位為分鐘。
  • 客戶端從Apollo配置中心服務端獲取到應用的最新配置后,會保存在內存中
  • 客戶端會把從服務端獲取到的配置在本地文件系統緩存一份
  • 在遇到服務不可用,或網絡不通的時候,依然能從本地恢復配置
  • 應用程序可以從Apollo客戶端獲取最新的配置、訂閱配置更新通知
部署文檔

部署文檔

使用
  • 訪問鏈接

  • 首頁


    shouye.jpg
  • 系統配置管理


    system.jpg
  • 應用配置-配置部門


    appconfig.jpg
  • namespace 創建-私有的才能自定義文件格式,否則默認properties格式


    namespace.jpg
  • 創建配置文件-點擊對號保存,點擊發布則更新到app里


    config.jpg
  • 歷史版本回滾-可以diff
    rollback.jpg
  • 查看實例


    node.jpg
  • 權限管理


    power.jpg
  • golang 配置讀取以及動態更新

// @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(
        // 默認讀取Namespace:application下key: foo的value
        a.Get("app_name"),

        // 獲取namespace為test.json的所有配置項
        a.GetNameSpace("avtivity1.txt"),

        // 當key:foo不存在時,提供一個默認值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監聽變化,并更新agollo對象內的配置cache
    // 或者忽略錯誤處理直接 a.Start()
    watchCh := a.Watch()
    // 啟動監聽配置變化
    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) // 這里可以發送郵件
                fmt.Println(viper.GetString("app_name"))
            }
        }
    }()

}

  • 總結
    • Apollo在配置管理流程上比較完善,相應配置的發布審核、權限管理等、配置的繼承等,但Apollo需要使用人員進行簡單學習,存在學習成本。
    • Appollo部署較為復雜需要3個模塊同時工作,部署一套生產高可用集群至少需要7
      個節點。(可使用docker解決)

nacos和apollo總結

對比項目 nacos apollo
配置實時推送 支持(1s) 支持(1s內)
版本管理(回滾) 支持 支持
權限管理 支持(粗顆粒度) 支持(細顆粒度)
灰度發布 支持 支持
集群 支持 支持
監聽查詢 支持 支持
多語言 Go,Java,Python,C++,.Net,OpenApi Java,Python,Nodejs,OpenApi
配置格式校驗 支持 支持
通信協議 http http
單機讀(tps) 15000 9000
單機寫(tps) 1800 1100

nacos官方支持go sdk
apollo第三方go sdk

結論

從配置中心角度來看,性能方面Nacos的讀寫性能最高,Apollo次之;功能方面Apollo最為完善,但Nacos具有Apollo大部分配置管理功能。Nacos的一大優勢是整合了注冊中心、配置中心功能,部署和操作相比 Apollo都要直觀簡單,因此它簡化了架構復雜度,并減輕運維及部署工作。

總的來看,Apollo和Nacos生態支持都很廣泛,在配置管理流程上做的都很好。Apollo相對于Nacos在配置管理做的更加全面;Nacos則使用起來相對比較簡潔,在對性能要求比較高的大規模場景更適合。

對于修改配置的次數不是特別的頻繁,對于配置權限的管理不是特別嚴格的,且對讀寫性能有一定要求的,可采用Nacos,反之使用Apollo。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容