Apollo的介绍和一些不生效问题

声明:
本文参考文章:
https://www.apolloconfig.com/#/zh/design/apollo-introduction
https://blog.csdn.net/lvshu_yuan/article/details/109768060
https://blog.csdn.net/Edward_hjh/article/details/123925114


一、apollo介绍

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

Apollo支持4个维度管理Key-Value格式的配置:

  • application (应用)
  • environment (环境)
  • cluster (集群)
  • namespace (命名空间)
二、总体设计
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

上图简要描述了Apollo客户端的实现原理:

1、客户端和服务端保持了一个长连接,从而能第一时间获得配置更新的推送。
2、客户端还会定时从Apollo配置中心服务端拉取应用的最新配置。
  这是一个fallback机制,为了防止推送机制失效导致配置不更新
  客户端定时拉取会上报本地版本,所以一般情况下,对于定时拉取的操作,服务端都会返回304 - Not Modified
  定时频率默认为每5分钟拉取一次,客户端也可以通过在运行时指定System Property: apollo.refreshInterval来覆盖,单位为分钟。
3、客户端从Apollo配置中心服务端获取到应用的最新配置后,会保存在内存中
4、客户端会把从服务端获取到的配置在本地文件系统缓存一份
  在遇到服务不可用,或网络不通的时候,依然能从本地恢复配置/5、应用程序从Apollo客户端获取最新的配置、订阅配置更新通知

四、配置更新和推送实现

前面提到了Apollo客户端和服务端保持了一个长连接,从而能第一时间获得配置更新的推送。

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

1、客户端发起一个Http请求到服务端
2、服务端会保持住这个连接60秒
  如果在60秒内有客户端关心的配置变化,被保持住的客户端请求会立即返回,并告知客户端有配置变化的namespace信息,客户端会据此拉取对应namespace的最新配置
  如果在60秒内没有客户端关心的配置变化,那么会返回Http状态码304给客户端
3、客户端在收到服务端请求后会立即重新发起连接,回到第一步
考虑到会有数万客户端向服务端发起长连,在服务端我们使用了async servlet(Spring DeferredResult)来服务Http Long Polling请求。

五、apollo配置不生效问题

1、API方式获取的配置,实时更新;
2、@Value方式注入的配置,实时更新;
3、@ConfigurationProperties方式注入的配置,启动时注入,后续需要重新注入的话,需要自己处理一下,可以使用RefreshScope,也可以使用EnvironmentChangeEvent
数据源、zookeeper这类有状态的组件,需要自己监听配置变化,在配置变化时重连远端的数据库或zk,可以参考dynamic-datasource;
4、日志级别也是类似的,可以参考spring-cloud-logger;
5、配置类的变量用static修饰:
  当apollo监听到某个配置类的属性修改了,就会在springioc容器中清除这个配置bean。那么下次再次使用的时候就会重新对这个配置bean初始化(懒加载的方式)。而此案例需要使用的配置属性是被static修饰的。使用的时候是通过类名.属性,并不需要生成配置类对象,所以springioc容器也就不会对其进行初始化,那么就还是使用原来的值,所以导致了配置不生效。

你可能感兴趣的:(Apollo的介绍和一些不生效问题)