一个配置中心一般含以下基本功能:
- 配置更新、发布
- 灰度发布
- 权限控制
- 版本控制
- 配置回滚
- 配置推送
阿波罗
Apollo(阿波罗)是一款可靠的分布式配置管理中心,诞生于携程框架研发部,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性,适用于微服务配置管理场景。
阿波罗的架构和工作原理
上图简要描述了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进程中
阿波罗的客户端设计
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中拉取最新配置,并更新到本地缓存中。
- 无db模式 采用了Raft协议保证了数据一致性。
客户端与服务端的一致性协议
- nacos1.x
通过短连接轮训取代长轮训,每30s发送一次心跳, 比对本地的配置与服务端的配置的md5是否一致。 若一致,则维持长轮训。 若不一致,服务端则把不一致的配置返回到客户端,客户端获取最新的配置值。
- nacos2.x
相比nacos1.x的30s一次的长轮训,nacos2.x升级为长连接模式,配置变更了, 则启用长连接,服务端推送变更列表到客户端,客户端负责拉取变更的配置,大大提升了通讯效率。
资料:
阿波罗官方文档: www.apolloconfig.com/#/zh/README