关键词:
前言
在上篇中介绍了SpringCloud Config的使用,本篇则介绍基于SpringCloud(基于SpringBoot2.x,.SpringCloud Finchley版)中的分布式配置中心(SpringCloud Config)的配置刷新和消息总线(RabbitMQ和Kafka)使用教程。
SpringCloud Config Refresh
在上一篇中我们介绍了springcloud配置中心的本地使用和Git使用的用法,但是当重新修改配置文件提交后,客户端获取的仍然是修改前的信息,需要客户端重启才可以获取最新的信息。因此我们需要客户端能够动态进行更新,幸好springcloud官方已经给出方案,所以我们只需要使用就行了。
开发准备
开发环境
- JDK:1.8
- SpringBoot:2.0.6.RELEASE
- SpringCloud:Finchley.SR2
注:不一定非要用上述的版本,可以根据情况进行相应的调整。需要注意的是SpringBoot2.x以后,jdk的版本必须是1.8以上!
确认了开发环境之后,我们再来添加相关的pom依赖。
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
服务端
服务端以及注册中心这块配置和代码和之前springcloud-config配置基本一样即可。注册中心新项目的的名称为springcloud-config-bus-eureka
,服务端新项目的的名称为springcloud-config-bus-server
。
注册中心pom
配置、application.properties
配置和代码如下:
pom:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
application.properties:
spring.application.name=springcloud-config-bus-eureka
server.port=8006
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
eureka.client.serviceUrl.defaultZone=http://localhost:$server.port/eureka/
代码:
@SpringBootApplication
@EnableEurekaServer
public class ConfigBusEurekaApplication
public static void main(String[] args)
SpringApplication.run(ConfigBusEurekaApplication.class, args);
System.out.println("config bus 注册中心服务启动...");
服务端pom
配置、application.properties
配置和代码如下:
pom:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
application.properties:
spring.application.name=springcloud-config-server
server.port=9005
eureka.client.serviceUrl.defaultZone=http://localhost:8005/eureka/
spring.cloud.config.server.git.uri = https://github.com/xuwujing/springcloud-study/
spring.cloud.config.server.git.search-paths = /springcloud-config/config-repo
spring.cloud.config.server.git.username =
spring.cloud.config.server.git.password =
代码:
@EnableDiscoveryClient
@EnableConfigServer
@SpringBootApplication
public class ConfigServerApplication
public static void main(String[] args)
SpringApplication.run(ConfigServerApplication.class, args);
System.out.println("配置中心服务端启动成功!");
客户端
客户端这边在之前springcloud-config-client项目中进行改造,新项目的的名称为springcloud-config-bus-client
,在pom文件中新增如下配置:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
spring-boot-starter-actuator
表示对该程序进行监控,可以通过http接口得到该程序的各种信息,详细的使用可以查看我的这个项目springboot-actuator,可以在注释中查询各种接口的使用。
然后再到配置文件application.properties
中添加如下配置:
management.endpoints.web.exposure.include=refresh
该配置表示暴露刷新的地址为refresh。
注:如果是SpringBoot1.x的版本,那么配置改成management.security.enabled=false
即可。
最后在客户端的Controller增加一个@RefreshScope
注解,该注解表示在接到SpringCloud配置中心配置刷新的时候,自动将新的配置更新到该类对应的字段中。
@RestController
@RefreshScope
public class ClientController
@Value("$word")
private String word;
@RequestMapping("/hello")
public String index(@RequestParam String name)
return name+","+this.word;
测试
完成上述的代码开发后,我们来进行测试Spring-Config是否可以进行配置实时更新。
首先依次启动springcloud-config-bus-eureka
、springcloud-config-bus-server
和springcloud-config-bus-client
这三个项目。其中9005是服务端springcloud-config-bus-server
的端口,9006是第一个客户端springcloud-config-bus-client
的端口。
启动成功之后,在浏览器输入:
http://localhost:9006//hello?name=pancm
界面返回:
pancm,hello world!!
可以正常得到服务端configtest-pro.properties
的配置信息。
然后在把configtest-pro.properties
的配置更改为:
word=hello
然后我们再浏览器输入:
http://localhost:9006//hello?name=pancm
界面返回:
pancm,hello world!!
可以发现配置并没有实时的刷新,查阅官方文档得知,需要客户端通过POST方法触发各自的/refresh,所以这里我们就用Postman工具模拟post请求刷新,然后再查看信息。
使用POST请求如下地址:
http://localhost:9006/actuator/refresh
返回:
[
"word"
]
说明完成了word配置的刷新,我们再浏览器输入:
http://localhost:9006//hello?name=pancm
界面返回:
pancm,hello
发现已经成功实现配置刷新了!
示例图:
SpringCloud Config Bus
上述的示例中,我们客户端发现每次获取最新配置都需要手动进行刷新,如果少的的话还可以使用,但是多的话就比较繁琐了,虽然我们可以使用类似Github的WebHook的工具。
WebHook是当某个事件发生时,通过发送http post请求的方式来通知信息接收方。
但是当客户端越来越多的时候WebHook已经不好使用了,每次新增客户端都需要更改WebHook会显得很麻烦,springcloud官方给出了非常好的解决方案,Spring Cloud Bus
。
Spring cloud bus通过轻量消息代理连接各个分布的节点。这会用在广播状态的变化(例如配置变化)或者其他的消息指令。Spring bus的一个核心思想是通过分布式的启动器对spring boot应用进行扩展,也可以用来建立一个多个应用之间的通信频道。目前唯一实现的方式是用AMQP消息代理作为通道,同样特性的设置(有些取决于通道的设置)在更多通道的文档中。
为什么使用Spring Cloud Bus
就可以解决这个问题了呢?
我们不一定非要透彻的理解其原理才可以知道,我们只需要知道它的实现步骤,就可以知道了为什么可以解决了。
步骤如下:
- 首先,在配置中进行更新配置文件信息,它就会自动触发post发送bus/refresh;
- 然后服务端就会将更新的配置并且发送给Spring Cloud Bus;
- 继而Spring Cloud bus接到消息之后并通知给使用该配置的客户端;
- 最后使用该配置的客户端收到通知后,就会获取最新的配置进行更新;
这里我也简单的画了下使用Spring Cloud Bus
之前和之后的流程图,方便进行理解。
不使用Spring Cloud Bus
获取配置信息流程图:
使用Spring Cloud Bus
获取配置信息流程图:
开发准备
和上述的环境一样即可。
RabbitMQ 的安装教程可以看我之前写的这篇文章:RabbitMQ的环境安装及配置。
Kafka 的安装教程可以看我之前写的这篇文章:kafka安装使用教程。
服务端
Spring Cloud Bus 主要的使用的MQ主要使用的是,RabbitMQ和Kafka。至于使用的话就可以根据情况来进行选择,主要使用的是哪个MQ就用哪一个就行了。这里我们就用RabbitMQ作为示例来进行讲解,Kafka的使用也差不多,也无在乎配置更改而已。
首先在springcloud-config-bus-server
服务端的pom文件添加如下配置:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
</dependencies>
注: spring-boot-starter-actuator
这个是必须的,不然是无法在服务端进行配置刷新请求的。如果是使用的kafka的话,只需将spring-cloud-starter-bus-amqp
改成spring-cloud-starter-bus-kafka
即可。
然后再到配置文件中添加如下配置:
配置信息:
spring.application.name=springcloud-config-bus-server
server.port=9005
eureka.client.serviceUrl.defaultZone=http://localhost:8006/eureka/
spring.cloud.config.server.git.uri = https://github.com/xuwujing/springcloud-study/
spring.cloud.config.server.git.search-paths = /springcloud-config/config-repo
spring.cloud.config.server.git.username =
spring.cloud.config.server.git.password =
management.endpoints.web.exposure.include= bus-refresh
spring.cloud.bus.enabled = true
spring.cloud.bus.trace.enabled = true
spring.rabbitmq.host:127.0.0.1
spring.rabbitmq.port:5672
spring.rabbitmq.username:guest
spring.rabbitmq.password:guest
配置说明:
- spring.application.name : 这个是指定服务名称。
- server.port:服务指定的端口。
- eureka.client.serviceUrl.defaultZone: 这个是设置与Eureka Server交互的地址,客户端的查询服务和注册服务都需要依赖这个地址。
- spring.cloud.config.server.git.uri: 配置的Git长裤的地址。
- spring.cloud.config.server.git.search-paths: git仓库地址下的相对地址 多个用逗号","分割。
- spring.cloud.config.server.git.username:git仓库的账号。
- spring.cloud.config.server.git.password:git仓库的密码。
- management.endpoints.web.exposure.include:SpringBoot2.x之后必须添加次配置,和上述的客户端
springcloud-config-bus-client
增加的的配置一样,名称不一样是为了做区分。 - spring.cloud.bus.enabled:是否启用springcloud config bus。
- spring.cloud.bus.trace.enabled:开启跟踪总线事件。
- spring.rabbitmq.host: rabbitmq的地址。
- spring.rabbitmq.port: rabbitmq的端口。
- spring.rabbitmq.username: rabbitmq的用户名。
- spring.rabbitmq.password: rabbitmq的密码。
注:如果是kafka的话,添加kafka的配置信息spring.kafka.bootstrap-servers
,填写kafka的地址和端口即可。
服务端代码和之前一样即可,在程序主类中,额外添加@EnableConfigServer
注解,该注解表示启用config配置中心功能。代码如下:
@EnableDiscoveryClient
@EnableConfigServer
@SpringBootApplication
public class ConfigServerApplication
public static void main(String[] args)
SpringApplication.run(ConfigServerApplication.class, args);
System.out.println("配置中心服务端启动成功!");
完成上述代码之后,我们的配置中心服务端已经构建完成了。
注册中心和之前保持一致就可以了。
客户端
客户端这边的变动基本不大,增加一个rabbitmq的jar包和相应的配置文件即可。
在springcloud-config-bus-clinet
的pom文件添加如下配置:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
</dependencies>
bootstrap.properties
文件的配置信息和之前的基本一样,完整的配置如下:
配置信息:
spring.cloud.config.name=configtest
spring.cloud.config.profile=pro
spring.cloud.config.label=master
spring.cloud.config.discovery.enabled=true
spring.cloud.config.discovery.serviceId=springcloud-config-bus-server
eureka.client.serviceUrl.defaultZone=http://localhost:8006/eureka/
配置说明:
- spring.cloud.config.name: 获取配置文件的名称。
- spring.cloud.config.profile: 获取配置的策略。
- spring.cloud.config.label:获取配置文件的分支,默认是master。如果是是本地获取的话,则无用。
- spring.cloud.config.discovery.enabled: 开启配置信息发现。
- spring.cloud.config.discovery.serviceId: 指定配置中心的service-id,便于扩展为高可用配置集群。
- eureka.client.serviceUrl.defaultZone: 这个是设置与Eureka Server交互的地址,客户端的查询服务和注册服务都需要依赖这个地址。
注:上面这些与spring-cloud相关的属性必须配置在bootstrap.properties中,config部分内容才能被正确加载。因为bootstrap.properties的相关配置会先于application.properties,而bootstrap.properties的加载也是先于application.properties。需要注意的是eureka.client.serviceUrl.defaultZone
要配置在bootstrap.properties,不然客户端是无法获取配置中心参数的,会启动失败!
application.properties
配置文件新增的配置基本和服务端的一样,完整的配置如下:
spring.application.name=springcloud-config-bus-client
server.port=9006
management.endpoints.web.exposure.include=refresh
spring.cloud.config.failFast=true
spring.cloud.bus.trace.enabled = true
spring.rabbitmq.host:127.0.0.1
spring.rabbitmq.port:5672
spring.rabbitmq.username:guest
spring.rabbitmq.password:guest
配置说明:
- spring.application.name: 这个是指定服务名称。
- server.port:服务指定的端口。
- management.endpoints.web.exposure.include:暴露刷新的地址。
- spring.cloud.bus.enabled:是否启用springcloud config bus。
- spring.cloud.bus.trace.enabled:开启跟踪总线事件。
- spring.rabbitmq.host: rabbitmq的地址。
- spring.rabbitmq.port: rabbitmq的端口。
- spring.rabbitmq.username: rabbitmq的用户名。
- spring.rabbitmq.password: rabbitmq的密码。
程序主类代码,和之前的基本一致。代码如下:
主程序代码示例:
@EnableDiscoveryClient
@SpringBootApplication
public class ConfigClientApplication
public static void main(String[] args)
SpringApplication.run(ConfigClientApplication.class, args);
System.out.println("配置中心客户端启动成功!");
控制层代码:
@RestController
@RefreshScope
public class ClientController
@Value("$word")
private String word;
@RequestMapping("/hello")
public String index(@RequestParam String name)
return name+","+this.word;
完成上述的项目开发之后,我们把上面的项目复制一下,项目名称为springcloud-config-bus-client2
,然后把它的端口改为9007即可。
到此,客户端的项目也就构建完成了。
功能测试
完成如上的工程开发之后,我们来进行测试。
我们首先启动RabbitMQ服务,然后再依次启动springcloud-config-bus-eureka
、springcloud-config-bus-server
、springcloud-config-bus-client
和springcloud-config-bus-client2
这四个项目。其中9005是服务端springcloud-config-bus-server
的端口,9006是第一个客户端springcloud-config-bus-client
的端口,9007是是第二个客户端springcloud-config-bus-client2
的端口。
全局刷新测试
启动成功之后,在浏览器输入:
http://localhost:9006//hello?name=pancm
界面返回:
pancm,hello
在浏览器输入:
http://localhost:9007//hello?name=xuwujing
界面返回:
xuwujing,hello
可以正常得到服务端configtest-pro.properties
的配置信息。
然后在把configtest-pro.properties
的配置更改为:
word=hello!!
然后在使用Postman工具进行发起POST请求,只不过这次的地址是服务端的地址和端口。
使用POST请求如下地址:
http://localhost:9005/actuator/bus-refresh
然后我们再浏览器输入:
http://localhost:9006//hello?name=pancm
界面返回:
pancm,hello!!
浏览器输入:
http://localhost:9007//hello?name=pancm
界面返回:
xuwujing,hello!!
示例图:
局部刷新测试
完成上述全局刷新测试之后,有时我们只想刷新部分微服务的配置,那么便可以使用/actuator/bus-refresh/destination
端点的 destination
参数来定位要刷新的应用程序。
我们继续更改configtest-pro.properties
的配置为:
word=hello!!!
然后依旧使用Postman工具发送post请求,地址为:
http://localhost:9005/actuator/bus-refresh/springcloud-config-bus-client2
然后我们再浏览器输入:
http://localhost:9006//hello?name=pancm
界面返回:
pancm,hello!!
浏览器输入:
http://localhost:9007//hello?name=pancm
界面返回:
xuwujing,hello!!!
发现只有springcloud-config-bus-client2
客户端的配置更新,另一个springcloud-config-bus-client
没有进行刷新,达到了我们的目的。
示例图:
上述示例完成之后,我们把SpringCloud Config Refresh
的测试在进行一遍,发现依旧可以实现,因此我们发现只要开启Spring Cloud Bus
后,不管是对服务端还是客户端,执行/actuator/bus-refresh
都是可以更新配置的。
如果我们想进行跟踪总线事件的话,只需要在刷新配置之后,在地址后面添加/trace
或/actuator/httptrace
即可。
其他
项目地址
基于SpringBoot2.x、SpringCloud的Finchley版本开发的地址:https://github.com/xuwujing/springcloud-study
如果感觉项目不错,希望能给个star,谢谢!
音乐推荐
原创不易,如果感觉不错,希望留言推荐!您的支持是我写作的最大动力!
版权声明:
作者:虚无境
博客园出处:http://www.cnblogs.com/xuwujing
CSDN出处:http://blog.csdn.net/qazwsxpcm
个人博客出处:http://www.panchengming.com
reinforcementlearning强化学习系列之五:值近似方法valueapproximation
引言前面说到了强化学习中的蒙特卡洛方法(MC)以及时序差分(TD)的方法,这些方法针对的基本是离散的数据,而一些连续的状态则很难表示,对于这种情况,通常在强化学习里有2中方法,一种是针对valuefunction的方法,也就是本... 查看详情
reinforcementlearning强化学习系列之五:值近似方法valueapproximation
引言前面说到了强化学习中的蒙特卡洛方法(MC)以及时序差分(TD)的方法,这些方法针对的基本是离散的数据,而一些连续的状态则很难表示,对于这种情况,通常在强化学习里有2中方法,一种是针对valuefunction的方法,也就是本... 查看详情
微服务-springcloud学习系列:服务网关springcloudgateway
1.SpringCloudGateWay的使用①创建GateWay网关服务,引入依赖(这里注意GateWay使用netty和WebFlux实现,WebFlux和SpringMvc有冲突,因此不能将web依赖放在父pom中,需要单独的放在需要的子工程中,gateway中不能有mvc的web依赖) ②配置... 查看详情
springcloud学习系列-springcloud
SpringCloud是什么?SpringCloud=分布式微服务架构下的一站式解决方案,是各个微服务架构落地技术的集合体,俗称微服务全家桶 SpringCloud,基于SpringBoot提供了一套微服务解决方案,包括服务注册与发现,配置中心,全... 查看详情
微服务-springcloud学习系列:熔断保护sentinel
Sentinel支持信号量隔离(不支持线程池隔离),多种熔断降级策略,支持QPS流量控制。Sentinel是Hystrix的替代方案。Sentinel的核心概念:资源,规则,检验规则是否生效。1.Sentinel的使用①安装管理控制台(去官网下载对应的jar包,... 查看详情
springcloud学习系列之一-----搭建一个高可用的注册中心(eureka)(代码片段)
前言本篇主要介绍的是SpringCloud相关知识、微服务架构以及搭建一个高可用的服务注册与发现的服务模块(Eureka)。SpringCloud介绍SpringCloud是在SpringBoot的基础上构建的,用于简化分布式系统构建的工具集,为开发人员提供快速建立分... 查看详情
springcloud学习系列-ribbon负载均衡
Ribbon配置初步 1.修改microservicecloud-consumer-dept-80工程 2.修改pom.xml文件 <projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema 查看详情
微服务-springcloud学习系列:抽象中间件springcloudstream
1.SpringCloudStream的使用①安装中间件,根据实际需要安装消息中间件(以RabbitMQ为例介绍)②创建服务生成者引入依赖 编写配置编码 执行流程 ③创建服务消费者引入依赖(同生产者一样的依赖)配置 编码 ... 查看详情
springcloud系列之apollo配置中心
本篇文章为系列文章,未读第一集的同学请猛戳这里:SpringCloud系列之Apollo配置中心(一)本篇文章讲解Apollo部门管理、用户管理、配置管理、集群管理。点击链接观看:Apollo部门管理、用户管理、配置管理、集群管理视频(获... 查看详情
springcloud系列之config配置中心
本篇文章为系列文章,未读前几集的同学请猛戳这里:SpringCloud系列之Config配置中心(一)SpringCloud系列之Config配置中心(二)本篇文章讲解Config如何实现配置中心加解密,配置中心用户安全认证。配置中心加解密考虑这样一个... 查看详情
springcloud系列之config配置中心
本篇文章为系列文章,未读前几集的同学请猛戳这里:SpringCloud系列之Config配置中心(一)SpringCloud系列之Config配置中心(二)本篇文章讲解Config如何实现配置中心加解密,配置中心用户安全认证。配置中心加解密考虑这样一个... 查看详情
微服务-springcloud学习系列:注册中心consul
因为Eureka目前开源版本1.0不再更新(2.0版本没有开源),可以考虑使用其他开源的注册中心替代。1.下载安装Consul的服务端程序启动服务端,访问管理界面http://127.0.0.1:8500通过postman测试Consul提供的httpAPI2.将服务注册到Consul①添加... 查看详情
大屏设计系列之五——大屏设计语言分析
...大屏可视化设计,在积累了一定经验的同时,也在不断的学习和丰富关于大屏设计的特点及数据可视化的表达方式。 数据可视化过滤了非常 查看详情
全网最新springcloud快速练手学习项目——简单超易懂系列(代码片段)
...与未来展望认识微服务单体架构soa架构分布式架构微服务SpringCloud内容知识技术栈对比服务拆分远程调用Eureka注册中心搭建注册中心服务注册服务拉取Ribbon负载均衡源码跟踪流程总结负载均衡策略自定义策略饥饿加载Nacos注册中... 查看详情
springcloud学习系列之七-----zuul路由网关的过滤器和异常处理(代码片段)
前言在上篇中介绍了SpringCloudZuul路由网关的基本使用版本,本篇则介绍基于SpringCloud(基于SpringBoot2.x,.SpringCloudFinchley版)中的路由网关的过滤器Filter以及异常处理的教程。SpringCloudZuulFilter介绍过滤器概述Zuul的中心是一系列过滤器,... 查看详情
springcloud学习--路由网关
在微服务架构中,需要几个基础的微服务,包括服务的注册与发现,服务消费,负载均衡,断路器,咋能路由,配置管理等,由这几几个基础组件相互协作,共用组建一个简单的微服务系统。 -Zuul简介 Zuul是NetFlix开源的... 查看详情
springcloud学习系列之二-----服务消费者(feign)和负载均衡(ribbon)
前言本篇主要介绍的是SpringCloud中的服务消费者(Feign)和负载均衡(Ribbon)功能的实现以及使用Feign结合Ribbon实现负载均衡。SpringCloudFeignFeign介绍Feign是一个声明式的WebService客户端,它使得编写WebSerivce客户端变得更加简单。我们只需... 查看详情
总结学习springcloud系列之深入理解ribbon(代码片段)
一、简介Ribbon是客户端负载均衡方案,主要有三部分:服务发现:能够自动发现所依赖服务的列表服务监听:能够检测到失效的服务,并高效地将失效服务从服务列表中剔除。服务选择策略:负载均衡策略... 查看详情