配置中心调研,以及简单的使用

什么是配置

应用程序在启动和运行的时候往往读取一些配置数据,配置程序基本伴随着应用程序的整个声明周期.
比如:数据库的连接参数,启动参数等.

配置的特点

  • 独立于程度的只读变量
  • 伴随应用的整个生命周期
  • 配置可以有多种加载配置方式
    • 配置文件
    • 环境变量
  • 配置需要治理
同一份程序在不同的环境(开发,测试,仿真,生产),经常需要不同的配置,所以需要完善的环境,集群配置管理

什么是配置中心

当系统从一个单体服务拆分成若干个服务节点后,也就是咱们所说的:分布式服务,配置文件也必须跟着迁移,
这样配置也就太分散了,不仅如此,分散中还包含冗余.每个微服务都需要一份配置文件.
配置中心将配置从各应用剥离出来,对配置进行统一管理,应用自身不需要自己再去管理配置

配置中心的服务流程
  • 用户在配置中心发布,更新配置信息.
  • 服务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。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容