20

Spring-Cloud-Config消息总线和高可用

 5 years ago
source link: http://codingo.xyz/index.php/2018/07/27/c2/?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

前言

上文中简单的介绍了Spring-Cloud-Config如何使用,如何手动更新配置文件,并且在文末提出了几个疑问,其中包括多个Client节点如何更新,Server端如何保证高可用性等;本文将重点介绍通过使用Spring Cloud Bus来批量更新客户端,以及Server如何保证高可用;

Spring Cloud Bus消息总线

Spring Cloud Bus使用轻量级消息代理链接分布式系统的节点,可以用于广播状态改变(例如,配置改变)或其他管理指令;目前唯一实现的方式是用AMQP消息代理作为通道,其实本质是利用了MQ的广播机制在分布式的系统中传播消息,目前常用的有Kafka和RabbitMQ;下面重点使用kafka来实现多客户端刷新配置文件;

1.总体更新流程

大致流程图如下所示:

iqqMfmV.jpg!web

2.kafka安装部署

kafka部署依赖Zookeeper,使用的版本分别是:kafka_2.11-1.0.1和zookeeper-3.4.3,具体如何安装部署可参考:Kafka快速开始

3.server端改造

3.1添加新的依赖

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

3.2application.properties添加配置

#开启消息总线
spring.cloud.bus.trace.enabled=true
spring.cloud.stream.kafka.binder.brokers=192.168.237.128
spring.cloud.stream.kafka.binder.defaultBrokerPort=9092

4.client改造

4.1添加新的依赖

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

4.2application.properties添加配置

#开启消息总线
spring.cloud.bus.trace.enabled=true
spring.cloud.stream.kafka.binder.brokers=192.168.237.128
spring.cloud.stream.kafka.binder.defaultBrokerPort=9092

5.启动测试

5.1启动Server端

观察启动日志,可以发现/actuator/bus-refresh映射

2018-07-18 10:51:44.434  INFO 12532 --- [           main] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/bus-refresh],methods=[POST]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>)

往下可以有如下这行日志:

2018-07-18 10:52:08.803  INFO 6308 --- [           main] o.s.c.s.b.k.p.KafkaTopicProvisioner      : Using kafka topic for outbound: springCloudBus

Server端连接kafka创建了一个名称为springCloudBus的Topic,用来作为配置文件更新的消息通知;可以去kafka上查看:

[root@localhost bin]# ./kafka-topics.sh --list --zookeeper 10.13.83.7:2181
__consumer_offsets
springCloudBus

5.2启动Client

分别指定启动端口为8881和8882,可以看到和Server端类似的日志,订阅了名为springCloudBus的Topic,这样Server端发送消息给kafka,kafka通知client更新数据;

5.3测试

分别访问http://localhost:8881/hello和http://localhost:8882/hello,结果如下:

hello test

更新git中的配置文件为:

foo=hello test update

POST方式请求Server端,用来更新配置文件

c:\curl-7.61.0\I386>curl -X POST http://localhost:8888/actuator/bus-refresh

分别访问http://localhost:8881/hello和http://localhost:8882/hello,结果如下:

hello test update

2个客户端都获取到了最新的数据,表示更新成功;

在上图中我们发现Server端承担了太多的任务,而上图中Server端是一个单点,这样就不能保证系统高可用,下面看一下如何分布式部署Server端;

Server端保证高可用

Server端通过注册中心Eureka来保证高可用,下面看一下具体流程:

EnUjIbv.jpg!web

1.Eureka注册中心

1.1Eureka-Server依赖

<dependency>
		<groupId>org.springframework.cloud</groupId>
		<artifactId>spring-cloud-starter-eureka-server</artifactId>
		<version>1.4.5.RELEASE</version>
</dependency>

1.2启动配置文件

spring.application.name=eureka-server
server.port=8880

eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
eureka.client.serviceUrl.defaultZone=http://localhost:8880/eureka/

eureka.client.register-with-eureka:是否将自己注册到Eureka Server,默认为true

eureka.client.fetch-registry:是否从Eureka Server获取注册信息,默认为true

eureka.client.serviceUrl.defaultZone:Eureka Server交互地址

1.3准备启动类

@SpringBootApplication
@EnableEurekaServer
public class EurekaServer {
	public static void main(String[] args) {
		SpringApplication.run(EurekaServer.class, args);
	}
}

2.改造Server端(服务提供方)

2.1Eureka-Client依赖

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

2.2启动配置文件

eureka.client.serviceUrl.defaultZone=http://localhost:8880/eureka/

指定注册中心地址,也就是Eureka-Server配置的地址

2.3启动类添加@EnableDiscoveryClient注释,实现服务注册和发现

@EnableDiscoveryClient
@EnableConfigServer
@SpringBootApplication
public class ConfigServer {
	public static void main(String[] args) {
		SpringApplication.run(ConfigServer.class, args);
	}
}

3.改造Client端(服务消耗方)

3.1Eureka-Client依赖

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

3.2启动配置文件

#spring.cloud.config.uri= http://localhost:8888/
spring.cloud.config.discovery.enabled=true
spring.cloud.config.discovery.serviceId=config-server
eureka.client.serviceUrl.defaultZone=http://localhost:8880/eureka/

注释掉具体的Server端地址

spring.cloud.config.discovery.enabled:开启服务发现支持

spring.cloud.config.discovery.serviceId:服务提供端的名称

eureka.client.serviceUrl.defaultZone:配置中心的地址

4.测试

首先启动注册中心eurekaServer,端口为8880;然后启动多个config-server端,端口分别为:8887,8888;最后启动多个config-client端,端口分别是:8883,8884;

可以查看注册中心,注册的服务:

qIfy6bM.jpg!web

分别访问http://localhost:8883/hello和http://localhost:8884/hello,结果如下:

hello test

更新git中的配置文件为:

foo=hello test update

POST方式请求Server端,用来更新配置文件

c:\curl-7.61.0\I386>curl -X POST http://localhost:8888/actuator/bus-refresh

这里只是选择了其中一个server端去更新,任意一个都可以;

分别访问http://localhost:8883/hello和http://localhost:8884/hello,结果如下:

hello test update

2个客户端都获取到了最新的数据,表示更新成功;

将8888端口的Server端停掉,再次更新配置文件为

foo=hello test update2

POST方式请求Server端,用来更新配置文件

c:\curl-7.61.0\I386>curl -X POST http://localhost:8887/actuator/bus-refresh

分别访问http://localhost:8883/hello和http://localhost:8884/hello,结果如下:

hello test update2

2个客户端都获取到了最新的数据,表示更新成功;

总结

通过消息总线的方式解决了多个Client更新的问题,以及通过eureka来保证Server的高可用性;当然eureka注册中心和消息总线本身也需要高可用性,这里就不过多介绍了。

示例代码地址

Github: https://github.com/ksfzhaohui/blog


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK