华为技术专家谈微服务分布式架构的服务配置管理

2021-10-18 15:01:41 浏览数 (1)

单体应用只需管理一套配置,而微服务架构后,每个系统都有自己的配置,并且各不相同,有些配置还需要能够动态改变,以动态降级、切流量、扩缩容,那微服务架构下,到底服务配置该如何管理。

本地配置

最简单的,在代码里写配置。

比如下面这段代码用到Hystrix,并且在代码里定义了几个配置:

  • 线程的超时时间是3000ms
  • 熔断器触发的错误比率是60%
代码语言:javascript复制
@HystrixCommand(fallbackMethod = "getDefaultProductInventoryByCode",
    commandProperties = {
       @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000"),
       @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value="60")
    }
)

public Optional<ProductInventoryResponse> getProductInventoryByCode(String productCode)
{
    ....
}

还有一种方式,就是抽取到配置文件

使配置与代码分离,比如下面这段代码。

代码语言:javascript复制
@HystrixCommand(commandKey = "inventory-by-productcode", fallbackMethod = "getDefaultProductInventoryByCode")
public Optional<ProductInventoryResponse> getProductInventoryByCode(String productCode)
{
    ...
}

相应的配置可以抽离到配置文件中,配置文件的内容如下:

代码语言:javascript复制
hystrix.command.inventory-by-productcode.execution.isolation.thread.timeoutInMilliseconds=2000
hystrix.command.inventory-by-productcode.circuitBreaker.errorThresholdPercentage=60

以上方案都相当于把配置存在应用程序的本地。这样如果需要修改配置,就要重新走一遍代码或配置的发布流程。这往往需要一次新的上线发布过程,且权限更繁琐。

倘若能有一个集中管理配置的地方,若要修改配置,只需在这个地方修改一下,线上服务就自动从这个地方同步过去,不需要走代码或配置的发布流程,不就简单多了?

这就是配置中心

设计思想就是把服务的各种配置,如

  • 代码里配置的各种参数
  • 服务降级的开关
  • 依赖的资源等

都集中统一管理。服务启动时,可自动从配置中心中拉取所需配置,且若有配置变更,同样可自动从配置中心拉取最新配置信息,服务无需重新发布。

配置中心一般包含如下功能:

  • 配置注册
  • 配置反注册
  • 配置查看
  • 配置变更订阅

那配置中心的这些功能是如何实现的呢?

配置存储结构

一般配置中心存储配置按Group存的,同类配置放在一个Group下,以K, V键值对存储

配置注册

配置中心对外提供接口/config/service?action=register完成配置的注册功能,需要传递的参数包括配置对应的分组Group,以及对应的Key、Value。

比如调用下面接口请求就会向配置项global.property中添加Key为reload.locations、Value为/data1/confs/system/reload.properties的配置。

代码语言:javascript复制
curl "http://ip:port/config/service?action=register" 
-d "group=global.property&key=reload.locations&value=/data1/confs/system/reload.properties"

配置反注册

配置中心对外提供接口config/service?action=unregister,传递参数包括配置对象的分组Group、对应的Key。 比如调用下面的接口请求就会从配置项global.property中把Key为reload.locations的配置删除。

代码语言:javascript复制
curl "http://ip:port/config/service?action=unregister" -d
"group=global.property&key=reload.locations"

配置查看

配置中心对外提供接口config/service?action=lookup,需传参配置对象的分组Group、对应的Key。 比如调用下面的接口请求就会返回配置项global.property中Key为reload.locations的配置值。

代码语言:javascript复制
curl "http://ip:port/config/service?	
	action=lookup&group=global.property&key=reload.locations"

配置变更订阅

配置中心对外提供接口config/service?action=getSign来完成配置变更订阅接口,客户端本地会保存一个配置对象的分组Group的sign值,同时每隔一段时间去配置中心拉取该Group的sign值,与本地保存的sign值做对比。一旦配置中心中的sign值与本地的sign值不同,客户端就会从配置中心拉取最新的配置信息。比如调用下面的接口请求就会返回配置项global.property中Key为reload.locations的配置值。

代码语言:javascript复制
curl "http://ip:port/config/service?
	action=getSign&group=global.property"

配置中心便于我们管理服务的配置信息,并且如果要修改配置信息,只需要同配置中心交互,应用程序会通过订阅配置中心的配置,自动完成配置更新。

哪些场景适合使用配置中心呢?

资源服务化

应用规模不大时,所依赖的资源如Redis缓存或者RabbitMQ消息队列的数量不多,对应IP可直接写在配置。

但随公司赚到钱后,所依赖资源数量也开始骤增,比如上千个。这时就经常会遇到个别节点不可用,若还采用本地配置,就需要去更改本地配置,把不可用的IP改成可用IP,然后发布新的配置,太麻烦了!

可采用资源服务化,把对应缓存统统归为一类配置,然后若有个别机器不可用,只需在配置中心把对应IP换成可用的IP,应用程序会自动同步到本机,也无须发布。

业务动态降级

微服务架构下,拆分的服务越多,出现故障的概率就越大,因此需要有对应的服务治理手段,比如要具备动态降级能力,在依赖的服务出现故障的情况下,可以快速降级对这个服务的调用,从而保证不受影响。为此,服务消费者可以通过订阅依赖服务是否降级的配置,当依赖服务出现故障的时候,通过向配置中心下达指令,修改服务的配置为降级状态,这样服务消费者就可以订阅到配置的变更,从而降级对该服务的调用。

分组流量切换

为保证异地多活以及本地机房调用,一般服务提供者的部署会按照IDC维度进行部署,每个IDC划分为一个分组。此时,若一个IDC出现故障,可以把故障IDC机房的调用切换到其他正常IDC。为此,服务消费者可以通过订阅依赖服务的分组配置,当依赖服务的分组配置发生变更时,服务消费者就对应的把调用切换到新的分组,从而实现分组流量切换。

开源配置中心选型

  • Spring Cloud Config Spring Cloud中使用的配置中心组件,只支持Java语言,配置存储在git中,变更配置也需要通过git操作,如果配置中心有配置变更,需要手动刷新。 Spring Cloud Config作为配置中心的功能比较弱,只能通过git命令操作,而且变更配置的话还需要手动刷新,如果不是采用Spring Cloud框架,不建议选择。
  • Apollo 携程开源的分布式配置中心,支持Java和.Net语言,客户端和配置中心通过HTTP长连接实现实时推送,并且有统一的管理界面来实现配置管理。 Apollo功能强大,在国内许多互联网公司内部都有大量应用,其中Apollo对Spring Boot的支持比较好,如果应用本身采用的是Spring Boot开发的话,集成Apollo更容易。

0 人点赞