分布式配置中心的工作原理

126 阅读4分钟

一个配置中心一般含以下基本功能:

  • 配置更新、发布
  • 灰度发布
  • 权限控制
  • 版本控制
  • 配置回滚
  • 配置推送

阿波罗

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

阿波罗的架构和工作原理

image.png 上图简要描述了Apollo的总体设计,我们可以从下往上看:

  • Config Service提供配置的读取、推送等功能,服务对象是Apollo客户端
  • Admin Service提供配置的修改、发布等功能,服务对象是Apollo Portal(管理界面)
  • Config Service和Admin Service都是多实例、无状态部署,所以需要将自己注册到Eureka中并保持心跳
  • 在Eureka之上我们架了一层Meta Server用于封装Eureka的服务发现接口
  • Client通过域名访问Meta Server获取Config Service服务列表(IP+Port),而后直接通过IP+Port访问服务,同时在Client侧会做load balance、错误重试
  • Portal通过域名访问Meta Server获取Admin Service服务列表(IP+Port),而后直接通过IP+Port访问服务,同时在Portal侧会做load balance、错误重试
  • 为了简化部署,我们实际上会把Config Service、Eureka和Meta Server三个逻辑角色部署在同一个JVM进程中

阿波罗的客户端设计

image.png

1、客户端与服务端(configServer)维护了一个长连接,当服务端配置发送变更,推送变更消息到客户端,客户端实现配置的拉取,并更新到缓存和文件(/opt/data/appId)。

2、本地文件是为了避免apollo服务端不可用,导致配置丢失,直接从客户端的文件中获取配置,是客户端实现高可用的手段。

3、客户端定时(5min)拉取服务端的配置与本地配置是否一致,若不一致则更新本地缓存和文件。

  • 这是一个fallback机制,为了防止推送机制失效导致配置不更新

阿波罗的配置变更推送实现:

长连接实际上我们是通过Http Long Polling实现的,具体而言:

1、客户端每个5秒会发起http请求到服务端

2、服务端会保持这个请求60s

当60s内有配置变更,则直接返回namespace,客户端会根据namespace去拉取配置。

当60s内无配置变更,服务端会返回304给客户端,客户端重新发起http请求。

3、考虑到会有数万客户端向服务端发起长连,在服务端我们使用了async servlet(Spring DeferredResult)来服务Http Long Polling请求。

Nacos

nacos是阿里开源产品,针对微服务,提供服务发现/配置管理/服务治理的解决方案

基本概念

  • 命名空间 命名空间是nacos用于隔离不同环境的配置,不同的命名空间可以存在相同的dataId和group
  • dataId 某个配置集的id,用于划分系统的配置集,一个系统可以包含多个配置集。
  • group 配置集的分组,用于区分DataId相同的配置,当未填写配置分组时,分组名会默认采用 Default_Group。例如公用的数据库连接等。

快速入门

  • 导入相关依赖
<dependencies>

    <dependency>

        <groupId>com.alibaba.cloud</groupId>

        <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>

    </dependency>

    <dependency>

        <groupId>com.alibaba.cloud</groupId>

        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>

    </dependency>

    <dependency>

        <groupId>org.springframework.boot</groupId>

        <artifactId>spring-boot-starter-web</artifactId>

    </dependency>

    <dependency>

        <groupId>org.springframework.boot</groupId>

        <artifactId>spring-boot-starter-actuator</artifactId>

    </dependency>

    <dependency>

        <groupId>org.springframework.boot</groupId>

        <artifactId>spring-boot-starter-test</artifactId>

        <scope>test</scope>

    </dependency>

    <dependency>

        <groupId>com.atguigu.springcloud</groupId>

        <artifactId>cloud-api-commons</artifactId>

        <version>${project.version}</version>

    </dependency>

</dependencies>
  • 编写bootstrp配置文件
server:

    port: 3377


spring:

    application:

        name: nacos-config-client // 注册的微服务名,消费者可通过该服务名进行调用

    cloud:

    nacos:

        discovery:

            server-addr: localhost:8848 #Nacos服务注册中心地址

        config:

            server-addr: localhost:8848 #Nacos作为配置中心地址

            file-extension: yaml #指定yaml格式的配置

            // 指定namespace,用于环境区分

            namespace: 7a901d46-e75e-4e6a-b186-5980cca4249b

            // 指定分组

            group: dev-group



// dataId命名:

${spring.application.name}-${spring.profile.active}.${spring.cloud.nacos.config.file-extension}

#nacos-config-client-dev.yaml


  • 启动类添加服务发现注解
@SpringBootApplication

@EnableDiscoveryClient

public class ConfigNacosMain3377 {


    public static void main(String[] args) {

        SpringApplication.run(ConfigNacosMain3377.class,args);

    }

}


  • 实现配置获取
@RestController

@RefreshScope //支持nacos的动态刷新功能

public class ConfigClientController {


    @Value("${config.info}")

    private String configInfo;



    @GetMapping("/config/info")

    public String getConfigInfo() {

        return configInfo;

    }

}

配置一致性原理

一致性模型:

nacos作为分布式配置中心,一致性协议分为两个部分。
第一部分:为server间的一致性协议。
第二部分:为客户端与服务端的一致性协议。
nacos作为配置未采用强一致性,nacos采用的ap模型,保证了高可用。

server间的一致性

  • 有db模式 server1持久化配置到db中,并给sdk响应成功,此时异步广播配置变更事件到其他的server端,其他server接受到事件广播后,从db中拉取最新配置,并更新到本地缓存中。

image.png

  • 无db模式 采用了Raft协议保证了数据一致性。

客户端与服务端的一致性协议

  • nacos1.x

通过短连接轮训取代长轮训,每30s发送一次心跳, 比对本地的配置与服务端的配置的md5是否一致。 若一致,则维持长轮训。 若不一致,服务端则把不一致的配置返回到客户端,客户端获取最新的配置值。

image.png

  • nacos2.x

相比nacos1.x的30s一次的长轮训,nacos2.x升级为长连接模式,配置变更了, 则启用长连接,服务端推送变更列表到客户端,客户端负责拉取变更的配置,大大提升了通讯效率。

资料:

阿波罗官方文档: www.apolloconfig.com/#/zh/README