本文分享自华为云社区《华为云物联网高级攻城狮的4年配置中心实践分享》,作者:华为云IoT高级工程师 贺张俭。

自 17 年入职华为之后,一直在使用配置中心,4年期间经历了自研配置中心到 Apollo 再到自研配置中心和 Apollo 并存的场景。总结了一下这几年的配置中心演进流程,想把我们在配置中心上的一些实践分享给大家,实现共同进步。Apollo 是一款非常优秀的开源软件,如果对 Apollo 存在理解错误,还望大家不吝赐教,谢谢。

Apollo(阿波罗)是一款开源配置管理中心,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性,适用于微服务配置管理场景。

Github:https://github.com/apolloconfig/apollo

1 使用到的配置分类

1.1 从场景分类

1.1.1 运维配置,即程序只读的配置

人工配置。通过人工在配置中心界面进行配置,而程序只进行读取,如数据库配置、邮箱服务器配置、网卡配置、子网地址配置等。这部分配置数据不要求代码动态写入。

1.1.2 业务配置,即程序可写的配置

我们是一个 SaaS 服务,每个用户在上面都有一些业务配置。如用户的证书配置、用户服务器的流控配置等,这些业务配置相对运维配置来说更加复杂,且可能会有唯一性限制,如按用户 id 唯一。这部分配置数据一般由用户操作触发,代码动态写入,并且通知到各个微服务实例。通常,我们希望这些配置能在界面展示,且支持人为修改。上述逻辑如果由各微服务自己实现,会存在大量重复代码,并且质量无法保证。我们希望由一个公共组件来统一实现这个能力。

1.2 从配置是否会有列表可分为单值配置或多值配置

1.2.1 单值配置

整个配置下只是多对 key、value。value 不是很复杂的格式,往往是整数或字符串。

1.2.2 多值配置

多值配置更加复杂,往往是单值配置在不同的 key 下,有不同的值。比如下面的配置,用户一和用户二的线程池大小和队列不同

2 第一阶段自研配置中心

在做云服务之前,我们的配置中心层级数较少。我们以软件的形式交付给客户,软件运行时分为管理面和业务面,配置中心管理着管理面和业务面的配置,最为复杂的场景是多套业务面,这个时候需要保证不同集群、不同微服务下的配置不冲突,配置层级为集群、微服务、配置。

此时的配置中心是完全自研的,不包含蓝绿、灰度配置这些功能,它独具特色的地方有以下两点:

2.1 单配置单表

  • 在存储模型上,每个配置对应一张数据表。
  • 对多值配置比较友好,尤其是复杂业务配置,可以支持各种主键约束。对单值配置,稍微重型了一些。
  • 配置的强 Schema 限制。这些限制包括类型、大小、长度、是否敏感等限制。这种限制既能为界面修改配置提供良好的体验(如:不同格式不同的输入框、敏感字段,前台输入明文,后台入库加密等),也能在通过接口写入配置时做充分的校验。

2.2 通过回调方式来确保配置的可靠

举个例子,添加一个配置的流程是这样的

可能这里,有读者想要问了,这个流程能确保什么可靠呢。这个流程通过调用微服务接口来校验配置是否可靠,如 IP 地址是否合法、对端地址是否可达、配置数量是否超过规格等等,来保证配置基本可用。

总的来说,这个自研的配置中心在当时综合体验还是不错的。但是也有一些问题有待改进,比如单配置下配置项数量过多时,因为底层有部分接口单配置下所有数据都通过一个 http 请求来承载,会导致响应超时等问题。

3 第二阶段 Apollo

开始第二阶段实践的原因主要是,我们进行了组织切换,业务重心转向做云服务,同时团队进行 DevOps 转型。原先的老配置中心是由另一个团队维护的,组织切换完之后,如果还要使用,就要我们自己维护。所以我们需要在继续维护老配置中心和引入开源 Apollo 中间进行选择。除了上文中提到的运维配置和业务配置,这个时候我们的需求还有改变:

  • 配置的层级愈发丰富了
  • 要构建灰度发布微服务的能力

老配置中心一方面由于组织切换原因不提供维护了,另一方面不能支撑丰富的配置层级,也不具备灰度发布的能力。这个时候,Apollo 的一些特性吸引了我们,这些特性正是老配置中心所缺乏的,例如(部分引用自 Apollogithub 主页)

  • 丰富的层级,从 app_id 到 cluster,namespace,key-value 的层级能满足我们 region、集群、微服务的层级诉求;
  • 支持配置的灰度发布,比如点了发布后,只对部分应用实例生效,等观察一段时间没问题后再推给所有应用实例;
  • 所有的配置发布都有版本概念,从而可以方便的支持配置的回滚;
  • 应用和配置的管理都有完善的权限管理机制,对配置的管理还分为了编辑和发布两个环节,从而减少人为的错误;
  • 所有的操作都有审计日志,可以方便的追踪问题。

因此我们选型引入了 Apollo,我和我的主管,还有一个其他同事参与了这项工作。我们在 Apollo 开源代码的基础上做了比较大的改动,主要原因有以下几点:

  • 节约成本,将注册中心、数据库替换成我们当前正在使用的组件,因为这两个依赖不是 Apollo 的核心依赖
  • 继承老配置中心强 Schema 的优点
  • 保留回调确认配置的流程,提前拦截错误的配置,降低代码处理异常配置的复杂度
  • 通过 spi 或环境变量的方式兼容存量老局点使用老配置中心的场景

结合上述原因,我们最终是这么实践的:

  • 数据库切换为 postgre 数据库、注册中心切换到 servicecomb
  • 在 namespace 上实现了 Schema,每个 namespace 都可以注册对应的 Schema,Schema 要求数据必须是 json 格式,且 json 内对应的 value 必须满足 Schema 定义的规范(如 ip 地址、小数、整数等)

Schema 举例:

[{"name":"name","type":"string"},{"name":"age","type":"int","max":120},{"name":"ip","type":"ipv4"}
]

那么数据应该是这样的:

{"name":"hezhangjian","age":23,"ip":"127.0.0.1"
}
  • 在添加或修改配置的时候,实现了回调功能,由回调业务服务确认配置能否添加或修改;
  • 配置分层:云服务对应 Apollo 的 app_id,把内部的环境对应到 Apollo 上的集群,然后将微服务名+配置名拼接成配置名称。

下图展示了业务概念和 Apollo 概念的对应关系,有些配置是单值配置,有些是多值配置,所以配置项这一层级是可选的。

在这段时间的实践中,我们也发现了如下的一些问题。

3.1 并发问题

其中最致命的就是并发问题,首先 Apollo 所有配置都存在一张表中,其次由于 Apollo 设计之初主要考虑的是运维人员手动在界面上操作,代码无并发语义(或者说没给客户端并发语义),使得我们通过代码写入配置时难以解决并发问题。

3.2 性能问题

打开 namespace 列表页面,需要显示这个 app_id 下的所有 namespace,因为我们单 app_id 会存放单个云服务的所有配置,这个量很大,且界面不支持分页,导致页面加载缓慢。

3.3 体验问题

Apollo 的 namespace 界面未提供搜索功能(可能 Apollo 设计之初也没想支持这么多),想要从 namespace 中定位到我们想要查看或修改的 namespace,只能借助浏览器的搜索能力。

4 第三阶段 Apollo 与自研配置中心并存

除了上述几个问题,还有一些原因使得我们开始了第三阶段的实践:

  • 原来自上而下的配置分层模型,微服务间配置没隔离,不仅不易进行权限管理,而且不适合 DevOps 单微服务自治的发布理念;
  • 第二阶段对 Apollo 改动太多,组织结构变动,没有足够的人力维护;
  • 随着集群越来越多,回调功能需要网络的双向打通,网络维护不太方便;
  • 我们对 Apollo 界面以及接口基于业务做的改动较多,导致其他兄弟部门难以共用 Apollo

当时大家对是否保留 Schema回调检查代码写配置这三个功能点有较大的争议。我个人最希望保留 Schema回调检查,因为它们优点显著,而且接口是兼容的,可以与其他部门共用,但是增加了 Schema 这个概念和回调检查这个流程,会增加学习成本。而代码写配置,由于要解决并发问题,代码改动量较大,我不建议保留。

大家经过激烈的讨论,最终还是废弃了 Schema回调检查代码写配置这三个功能点,仅仅把运维配置放在 Apollo。

然后,我们把业务配置,放在了一个自研的强 Schema 的配置中心上,这个配置中心,仅负责单集群的配置,每个集群部署一套,满足了我们的业务需求。自研强 Schema 配置中心的核心要点有,单配置单表、通过注册中心回调来检测配置是否合法、借助 mqtt 协议来实现长链接推送,无单点瓶颈。

而我们的运维配置中心 Apollo 回归到了开源的版本,重整了配置的结构,

对运维配置而言好处有:

  • 配置模型适合单微服务发布;
  • 配置按微服务组织,一个页面上的 namespace 不会很多。

缺点:

  • Schema 缺失后,不会对操作人员在界面的配置进行校验,即使配置格式或者内容错误也能配置成功。界面上配置密码不支持明文(Apollo 无法感知是否为敏感字段),必须提前使用其他工具将明文转换为密文,然后再进行配置;
  • 回调检查功能去掉后,有些配置,如网卡网段配错,操作人员不能即时得到响应。

4.1 最佳实践

业务配置经过我们的实践,确实不适合使用开源的 Apollo。运维配置使用原生的 Apollo,但是现在还不具备回调检查和 Schema 的功能,希望 Apollo 能在后续版本中支持 Schema,或者弱化的 json 格式检查功能。下面是我们在如下场景下的最佳实践。

4.1.1 SRE 在界面上的运维配置

通过 Apollo 来实现功能,至于配置如何组织,根据大家的组织结构、技术架构来对应 Apollo 上的概念,可按照微服务->部署环境或部署环境->微服务的层级来组织配置。

4.1.2 复杂的参数校验

建议在 Apollo 上面自建 portal 包裹一层,后端服务可先进行一层处理,这一层处理可以做比较复杂的格式化校验甚至回调检查,再调用 Apollo OpenApi 将配置写入 Apollo。

4.1.3 业务配置的技术选型

最大的挑战是业务配置由用户触发,请求的并发不易处理。思路有两个,一个是在 Apollo 原生代码的基础上,通过数据库分布式锁来解决并发问题。第二个是借鉴我们的思路,通过单配置单表、mqtt 协议实现通知等核心技术点,自研业务配置中心。

4.1.4 业务配置的部署

需要根据业务配置的数量来考虑是否合设业务配置中心。单集群场景下,毫无疑问只需要一个业务配置中心,甚至如果使用 Apollo 实现,可以考虑和运维配置中心合设。多集群场景下,部署一个业务配置中心,还是多个业务配置中心,我们自己的实践中,一个集群往往要支撑数万用户,我们采取了每个业务集群部署一套业务配置中心的策略。

更多学习内容,请前往IoT物联网社区

点击关注,第一时间了解华为云新鲜技术~

华为云物联网高级攻城狮的4年配置中心实践分享相关推荐

  1. 剑指offer笔记(三)菜鸟程序猿和高级攻城狮码赋值运算符函数的区别

    赋值运算符函数 小小的一个赋值运算符函数的写法完全可以区分出一个程序猿的功底 运算符函数是C++中经典的运算符重载函数 对于给定一个类: class my_string { public:my_str ...

  2. 华为云CSE关键特性,支持托管Nacos注册配置中心

    什么是Nacos Nacos是 Dynamic Naming and Configuration Service的首字母简称,相较之下,它更易于构建云原生应用的动态服务发现.配置管理和服务管理平台. ...

  3. 写给即将/正在找工作的Android攻城狮

    写给即将/正在找工作的Android攻城狮 版权声明:转载必须注明本文转自严振杰的博客:http://blog.yanzhenjie.com 这段时间从北上广深杭不断传来一两个月找不到工作的消息,我一 ...

  4. “攻城狮”手把手教你物联网智能生活-内网穿透技术

    "攻城狮"手把手教你物联网智能生活-内网穿透技术 内网穿透技术,即实现外网IP访问内网IP而发展起来的一种计算机技术.在了解内网穿透技术之前,我们需要先了解IP和内网外网的概念. ...

  5. 一位Java开发攻城狮的自我修养之项目篇

    攻城狮的自我修养之项目篇 基础知识 Java基础 SpingBoot SpringCloud LeetCode题库 大数据 项目实战 商城系统 权限管理系统 脚手架系统 人事管理系统 论坛系统 博客系 ...

  6. 【网易云信招聘啦】216位攻城狮,呼唤7个好基友

    Hi,猿 过年了 年终奖拿了没 老板给加薪没 耿耿于怀的你 是否各种隐忍沮丧 以下代表,你属于哪一个? 猿A 公司是创业公司,还未盈利,为了产品上线,付出很多,能力提升了很多.不过,项目不赚钱,没人在 ...

  7. 如何极速极速搭建个人博客?Copy攻城狮用的这一招很优秀!

    摘要:在中国功夫中,"天下武功,无坚不摧,唯快不破",在编程的世界里,如何快速搭建一个属于自己的博客呢?那么 Pagic + Vercel 应该是个不错的选择!接下来,由Copy攻 ...

  8. Copy攻城狮的年度之“战”|回顾2020

    过去的一年,很少在CSDN上发表文章,此处留下了没有技术的眼泪(争取2021年多水一些文章).主要是感觉没啥总结的,因为本身技术实在太水,枉称为"技术人",还是习惯"Co ...

  9. 秋招攻略—如何成为一名图像算法攻城狮(上篇)—知识学习篇

    秋招攻略-如何成为一名图像算法攻城狮(上篇)-知识学习篇 从6月份开始一直到现在,5个月的秋招历程让我成长了许多,最终收到了华为.荣耀.vivo.科大讯飞.奥比中光.汇川等10余家公司的图像算法off ...

最新文章

  1. Cell子刊:根瘤菌微生物群落的模块化特征及其与共生根瘤菌的进化关系
  2. php中添加访问器,php – 结合访问器和mutator逻辑,为模型添加自定义属性
  3. 中国程序员如何升职加薪,也许我们该学学印度人
  4. python中字母大小写的转换,和一些字典的常规操作
  5. 每个[NET]开发人员现在应该下载的十种必备工具
  6. Java Runtime.exec()的使用
  7. Linux pid_t 类型的定义
  8. HTTP 304状态码
  9. OAI LTE系统搭建 -- OAI EPC
  10. excel教程自学网_收藏!这37个自学网站,一年让你省下十几万
  11. 千万不要急着 返城上班!
  12. 红包码收款码合二为一
  13. 宋江是怎么当上老大的
  14. 普通二本从小白到加入鹅厂的通关秘籍
  15. 《深入理解计算机系统》——低谷中的重新振作
  16. 一个拥抱ARVR热点机会
  17. 微软证实10月25日正式发布Windows8系统
  18. Uniapp 制作海报功能
  19. V4L2+QT视频优化策略
  20. 防火墙导致mysql登录不上_防火墙导致MySQL无法访问的问题解决案例

热门文章

  1. Hadoop1.X 与 Hadoop2.X区别及改进
  2. vue中通过css实现旋转地球
  3. 小程序粉墨登场 --奉上开发教程及书籍合集
  4. xpath语法大全(转载)
  5. gps定位服务器文件,通用GPS配置文件 GPS.conf 文件配置详解(转载)
  6. 腾讯项目总结报告模板
  7. Windows下Poco库的编译和安装
  8. WPF学习笔记:XAML入门
  9. 市场调研-临床前医疗设备检测服务市场现状及未来发展趋势
  10. 关于VS找不到“服务器资源管理器”的问题