Apache ServiceComb Kie----一个语义型配置中心

此次我想分享如何管理分布式应用系统中的配置项,咱们的实践与遇到的问题java


为何要用配置中心

我相信你们在开发的过程当中,常常会遇到的问题是git

  • 我有个新的特性,可是我须要对其进行控制,在必要时能将功能关闭或打开
  • 连接数据库的线程池须要调整
  • 访问某个目标的超时时间须要调整
  • 调节任务执行器的线程池大小
  • 随着业务发展,几百,几千的虚机或是容器实例配置须要管理

难道每次配置我都要去代码库中改变而后从新发布版本么?我在曾经的项目中就是这么作的,得益于当时完善的CICD,咱们只须要几分钟就能够完成这样的一次变动,可是依然要面临进程的重启,因此以后的实践中咱们直接将配置管理放入到了编程框架中,并配以中心式的配置管理服务github

使用编程框架

我在这篇分享中有大量分享欢迎参考,Go语言分布式系统配置管理实践--go archaius
数据库

有了此次改变后咱们就作到了在运行时让配置生效,不用经过流水线从新发布新版本。apache

在流水线中能作的只是在发布一个服务时,对接配置中心的API,对相关配置进行变动。。好比进行一次新版本的发布,更改金丝雀发布策略。编程

配置逐渐变得难以管理

配置中心的数据模型逐渐没法知足需求json

Dimension概念

配置项以Dimension划分 Dimension由{service}@{app}#{version}表示,也就是服务相关信息拼接而成的字符串。bash

Dimension就是一个惟一的ID,关联各个配置项,也就是一段json结构体app

{
"timout":"1s",
"pool_size":"10",
}复制代码

也就是说咱们对着微服务,版本,所属应用3个维度来下发信息
负载均衡

若是要更改微服务级别的服务,即不区分版本,咱们就对{service}@{app}这个dimension进行变动。

能力就仅限于这两个层级了。

随着业务的发展咱们发现这样的结构体不能知足一些场景

  • 配置中心围绕微服务的治理概念进行设计(超时,熔断,负载均衡策略等配置),可是用户的业务系统配置也使用这套配置中心和开发框架管理(好比我说的某个功能开关),不应让用户去理解微服务,版本,app的概念,而是直白的,让用户更改配置,好比按照环境去下发environment=test或者production
  • 服务的元数据不仅是version,app,可能还有instance,也就是对着服务进程,只改变某个进程的配置进行小范围测试,除了instance还有更多元数据须要考虑,咱们没法作到精准控制,好比按照project

key变得复杂

因为json结构体的局限性配置项的key愈来愈不易理解,key愈来愈长,好比

{
"ServiceB.timeout":"1s",
"ServiceB.user.getUser.timeout":"10",
}复制代码

第一行表示访问服务B时超时是多少

第二行表示到服务B的getUser API超时是多少

这还远远不够,服务还有版本,环境,所属app等多个字段,以下配置,因为每一个字段没有语义,咱们已经没法知道第二个字段究竟是什么意思了。

{
"ServiceB.v1.timeout":"1s",
"ServiceB.user.getUser.timeout":"10",
}复制代码

难道咱们都要继续拼接下去?咱们来看看问题

  • key语义学习成本高,语义容易混乱
  • 全部的key集中在一个列表中管理,管理成本高。
  • 当拼接规则复杂起来,人类不可读。
  • Key设计几乎没法扩展或者变动(须要极高成本才能变动)
固然咱们能够给json的value传入个json,yaml,java properties值,key用更大的维度来表示,好比文件名,可是一个围绕微服务概念设计的配置中心作不到通用,Dimension须要更加灵活,让人易于理解。


Apache ServiceComb Kie

在发展的过程当中,咱们从新设计了配置中心,不仅围绕微服务场景,或者像kubernetes的config map围绕容器,而是但愿可以成为一个通用的配置中心,让更多的生态接入。

项目地址:github.com/apache/serv…

从新设计的结构体。

kie取自key的谐音

正如名字所突出的,key成为了同等公民,一个文件名"xxx,yaml",一个传统的key“timeout” 均可以是一个key,咱们但愿key简单,易理解。而后围绕key定义labels以表示复杂的语义

直接演示下运行效果:


key就在API path中(timeout),label与value在request body中定义

这句话的意思是,在对订单服务进行访问时,超时是1s

返回的respsonse body中,能够看到版本号“revision”是2,这说明,label是第二次被使用(之间labels的历史记录已经被储存了)

value具有type,不传就是plain text,在前台显示是能够根据类型作展现,更易读

最重要的是labels,你能够为key定义多个labels,只有label彻底一致,才认为这是个惟一的“Dimension”,我用label概念来代替了过去定死的Dimension。有了labels与key,你已经能够自由的去定义本身的配置,表达本身的语义


我接着新建了一个配置,表示访问该服务,要使用会话粘纸,可是能够看到,revison是3,由于历史管理是根据label记录的,以让用户能够根据labels来将全部key快速回滚到某个历史状态中,单一的回滚key来试图恢复系统也许会引发更大的混乱。

咱们再来个稍微复杂的



此次咱们新建了一个复杂语义的label,表示:若是前台访问订单服务的1.0.1,那么负载均衡策略是round robin。


今天的介绍就简单到这里,后面会持续对kie的新特性进行分享,经过这篇我但愿经过分享让你们对复杂分布式系统中的配置管理实践有些了解。

相关文章
相关标签/搜索