官方文档 链接
分布式服务需要对各个环境的配置文件进行统一管理,支持配置的实时生效,可以通过配置界面方便的管理配置文件。在生产中,我们使用的是 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进程中
项目使用
依赖:
<dependency>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo-client</artifactId>
<version>${apollo-client.version}</version>
</dependency>
配置文件中配置 apollo.bootstrap.enabled = true,配置类:
@Configuration
@EnableApolloConfig
@ConditionalOnProperty(value = "apollo.bootstrap.enabled", havingValue = "true", matchIfMissing = true)
public class ApolloConfig {
Logger logger = LoggerFactory.getLogger(ConfigChangeService.class);
/**
* 检测配置变化
* @param changeEvent
*/
@ApolloConfigChangeListener
public void configChangeListener(ConfigChangeEvent changeEvent) {
//配置变化处理
ConfigChange change = changeEvent.getChange(key);
logger.info("发现变化 - key: {}, oldValue: {}, newValue: {}, changeType: {}",
change.getPropertyName(),
change.getOldValue(),
change.getNewValue(),
change.getChangeType());
}
}
当 配置修改时,会回调 ApolloConfigChangeListener 注解对应的方法,可以在该方法中根据变动的配置进行相应的业务处理。
部署架构
何为长轮询?链接
长轮询的客户端不做轮询,客户端在发起一次请求后立即挂起,一直到服务器端有更新的时候,服务器端才会返回信息到客户端。在服务器端有关系推送信息过来之前。客户端不会有多余的请求发生,只保留最基础的连接信息。长轮询特点:
- 服务器端会阻塞请求直到有数/据传递或超时才返回.
- 客户端响应处理函数会在处理完服务器返回的信息后,再次发出请求,重新建立连接.
- 当客户端处理接收的数据、重新建立连接时,服务器端可能有新的数据到达;这些信息会被服务器端保存直到客户端重新建立连接,客户端会一次把当前服务器端所有的信息取回
消息通知机制
发布配置时序图
上图简要描述了配置发布的大致过程:
- 用户在Portal操作配置发布
- Portal调用Admin Service的接口操作发布
- Admin Service发布配置后,发送ReleaseMessage给各个Config Service
- Config Service收到ReleaseMessage后,通知对应的客户端
长轮询 RemoteConfigLongPollService
apollo client 会向 config server 发起http长轮询, config server 使用 spring DeferredResult 进行异步化处理,如果配置没有修改,在请求到了超时时间会返回 304,un modified 给 client。如果配置在超时之前有修改,则会立即返回。返回的不是配置信息,而是哪些 namespaceName 有改动,client 会再发请求去拉取配置信息。
定时 RemoteConfigRepository
防止长轮询失败,有个定时任务会定时到 config server 查询配置信息。