Spring Cloud Config Server和Spring Cloud Bus以及Kafka和数据库动态刷新配置

  Spring cloud config server如果不结合Spring cloud bus,那么就无法实现动态更新,只能重启服务才能生效新的配置,比如我们的注册服务器(Eureka)是整个Spring cloud系统中的单点风险,在正常运营过程中或测试环境切换到正式环境时,我们准备了两套注册服务器,希望在这两者之间不停机进行动态切换。

    Spring cloud bus支持RabbitMQ和Kafka两种方式,RabbitMQ安装需要先安装erlang,linux和windows下erlang安装方式不一样,linux下需要源码编译,如果缺失组件需要升级,会折腾半天,而Kafka直接下载压缩包用Java命令启动即可,且支持事务性消息,其日志方式的机制更灵活强大,可以根据CAP定理在高可用性和高一致性灵活选择,当然用在配置更新方面是可用性重要还是一致性重要,这与注册服务器考量原则是一样的,服务注册一定是注重高可用性,而不是高一致性,如果这个问题不考虑清楚,设计再强大的分布式注册框架也是走错方向。配置更新方面使用异步总线其实已经是一种最终一致性,但是这种最终一致性也不能不一致时间太长,否则影响功能正常运行,比如1000个服务中已经有800个服务改变到新的注册服务器配置,而其他200个还没有,在这种情况下,两者之间存在相互找不到对方,网络存在分区了,业务上是否容许?当然Kafka会将这种不一致延迟降低到最低。

   废话少说,Spring cloud配置服务器和其客户端之间通讯如果系统通过Spring cloud bus很简单,只要在pom.xml增加:

<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-kafka</artifactId>
</dependency>

然后在服务端的application .properties中加入:

spring.cloud.bus.enabled=true
spring.kafka.bootstrap-servers=localhost:9092

激活bus通讯,默认是关闭的。告知Kafka的服务器地址。

下面我们需要激活动态刷新功能,这个过程有点小复杂,Spring cloud不同版本变化有点大,首先,在服务器端我们要引入actuator

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator</artifactId>
</dependency>

actuator在Spring 2.0以后改变很大,我们为了调用其刷新url :/actuator/bus-refresh,需要将其暴露,在application.properties配置:


management.endpoints.web.exposure.include=*

 

  我们在上一篇使用Oracle作为我们配置信息存储库的案例,如果数据库中配置信息更改,我们通过主动post刷新配置服务器的/actuator/bus-refresh将新的配置信息广播给相关者,这里我们还是使用前面几篇一个应用用例,微服务需要指导注册服务器的地址,这个地址信息我们存储到配置服务器的Oracle中,当我们想切换注册服务器的IP地址时,通过Spring cloud bus+kafka通知各个微服务。

在配置服务器三步配置,第一步pom.xml:

<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc8</artifactId>
<version>12.2.0.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-kafka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

在application.properties配置:

spring.application.name=config-server-jdbc
server.port=8888


spring.profiles.active=jdbc
spring.datasource.url=jdbc:oracle:thin:@//localhost:1521/pengpdborcl
spring.datasource.username=scottpeng
spring.datasource.password=scottpeng

spring.cloud.config.label=master
spring.cloud.bus.enabled=true
spring.kafka.bootstrap-servers=localhost:9092


management.endpoints.web.exposure.include=*

 

第二段是有关将Oracle作为配置存储库,第三段有关bus总线配置,第三段也就是最后一样是有关主动刷新的。

以上是Spring cloud config服务器端配置,那么客户端也就是需要向注册服务器注册自身的微服务怎么配置?只要加上pom.xml:

<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-kafka</artifactId>
</dependency>

如果Kafka是在默认localhost:9092就不需要配置了,否则要配置spring.kafka.bootstrap-servers=XXX:9092

这就是客户端的配置了,好了,我们现在试验运行。

首先运行好eureka注册服务器,启动kafka,然后启动Spring cloud config server,然后再启动客户端Producer的应用,它的注册服务器配置信息:


#eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/

需要通过配置服务器获得,这条信息保存在oracle数据库中:

 

如果我们更换注册服务器ip地址从localhost:1111更换到localhost:1112,当然我们也要事先启动eureka在1112端口:

java -jar - Dserver.port=1112 registry-0.0.1-SNAPSHOT.jar

通过localhost:1111和localhost:1112可以发现,在前者页面发现有一个PengProducerService注册其中,后者没有,那么如果将数据库中localhost:1111更换到localhost:1112,然后用post方式访问/actuator/bus-refresh主动刷新这一变动:

 

在配置服务器控制台立即出现:

Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@7688c373: startup date [Sun Jul 15 21:57:11 CST 2018]; root of context hierarchy

表示配置服务器端刷新激活,在客户端Producer控制台则出现:

Received remote refresh request. Keys refreshed []

表示都已经激活新的配置,再访问localhost:1111和localhost:1112可以发现,可以发现PengProducerService已经更换注册地了。

本文源码:百度网盘

spring cloud专题