Spring Cloud Bus
将分布式系统的节点与轻量级消息代理链接。可以用于通知状态更改(例如配置更改)或其他管理指令。一个关键的地方是,Bus
就像一个分布式执行器,用于扩展的Spring Boot
应用程序,同时还可以用作应用程序之间的通信通道…
- Bus
Spring Cloud Bus
是通过添加Spring Boot自动配置(Auto Configuration),如果它在class path
中被检测到,则可以工作。所有启用Spring Cloud Bus
的都需要添加spring-cloud-starter-bus-amqp
或spring-cloud-starter-bus-kafka
依赖管理,并且Spring Cloud负责其余部分。确保代理(RabbitMQ或Kafka)可用和配置:在本地主机上运行,您不应该做任何事情,但如果您远程运行使用Spring Cloud连接器或Spring Boot定义经纪人凭据的约定,例如Rabbit
官方文档:http://cloud.spring.io/spring-cloud-static/Dalston.SR2/#_spring_cloud_bus
- RabbitMQ搭建
RabbitMQ搭建:http://blog.battcn.com/2017/08/20/linux/linux-centos7-ribbitmq/
- 开始
1.拷贝battcn-cloud-config
代码进行改造,其中battcn-config-server
不需要动
2.pom.xml
导入AMQP包
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-consul-discovery</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-config-client</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>
|
3.添加@RefreshScope
注解
1 2 3 4 5 6 7 8 9 10 11 12
|
@RestController @RefreshScope public class TestController {
@Value("${order.name}") String orderName;
@RequestMapping("/test") public String test() { return "client ====>>> " + orderName; } }
|
4.给battcn-config-client
配置rabbitmq
信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
server: port: 9001 spring: application: name: battcn-config-client cloud: config: name: config-server profile: order-default uri: http://localhost:9000 consul: host: localhost port: 8500 enabled: true discovery: enabled: true prefer-ip-address: true rabbitmq: addresses: 192.168.31.86 port: 5672 username: guest password: guest management: security: enabled: false
|
- 测试
1.启动consul
2.启动battcn-config-server
和battcn-config-client
3.访问:http://localhost:9001/test 会看到如下内容,表示服正常
1
|
client ====>>> My Name's Order Service,Are you Afraid?
|
4.修改battcn-config-server
中config-server-order-default.yml
文件的内容
1 2
|
order: name: My Name's Order Service,Are you Afraid?123
|
5.只重启battcn-config-server
同时发送POST
请求:http://localhost:9001/bus/refresh 通知服务刷新配置
6.再次访问:http://localhost:9001/test 会看到如下内容,表示服正常
1
|
client ====>>> My Name's Order Service,Are you Afraid?123
|
battcn-config-server
日志
1 2 3 4
|
2017-08-21 20:45:09.048 INFO 11420 --- [nio-9000-exec-3] o.s.cloud.commons.util.InetUtils : Cannot determine local hostname 2017-08-21 20:45:09.074 INFO 11420 --- [nio-9000-exec-3] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@5e6721d9: startup date [Mon Aug 21 20:45:09 CST 2017]; root of context hierarchy 2017-08-21 20:45:09.080 INFO 11420 --- [nio-9000-exec-3] o.s.c.c.s.e.NativeEnvironmentRepository : Adding property source: classpath:/config-server-order-default.yml 2017-08-21 20:45:09.080 INFO 11420 --- [nio-9000-exec-3] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@5e6721d9: startup date [Mon Aug 21 20:45:09 CST 2017]; root of context hierarchy
|
battcn-config-client
日志
1 2 3 4 5 6 7 8 9 10 11 12 13
|
2017-08-21 20:45:54.896 INFO 16768 --- [nio-9001-exec-8] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@7dc4513: startup date [Mon Aug 21 20:45:54 CST 2017]; root of context hierarchy 2017-08-21 20:45:54.906 INFO 16768 --- [nio-9001-exec-8] f.a.AutowiredAnnotationBeanPostProcessor : JSR-330 'javax.inject.Inject' annotation found and supported for autowiring 2017-08-21 20:45:54.907 INFO 16768 --- [nio-9001-exec-8] trationDelegate$BeanPostProcessorChecker : Bean 'configurationPropertiesRebinderAutoConfiguration' of type [org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration$$EnhancerBySpringCGLIB$$6f70a08a] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2017-08-21 20:45:55.973 INFO 16768 --- [nio-9001-exec-8] o.s.cloud.commons.util.InetUtils : Cannot determine local hostname 2017-08-21 20:45:55.994 INFO 16768 --- [nio-9001-exec-8] c.c.c.ConfigServicePropertySourceLocator : Fetching config from server at: http://localhost:9000 2017-08-21 20:45:57.093 INFO 16768 --- [nio-9001-exec-8] c.c.c.ConfigServicePropertySourceLocator : Located environment: name=config-server, profiles=[order-default], label=null, version=null, state=null 2017-08-21 20:45:57.093 INFO 16768 --- [nio-9001-exec-8] b.c.PropertySourceBootstrapConfiguration : Located property source: CompositePropertySource [name='configService', propertySources=[MapPropertySource [name='classpath:/config-server-order-default.yml']]] 2017-08-21 20:45:57.094 INFO 16768 --- [nio-9001-exec-8] o.s.boot.SpringApplication : No active profile set, falling back to default profiles: default 2017-08-21 20:45:57.095 INFO 16768 --- [nio-9001-exec-8] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@676107bb: startup date [Mon Aug 21 20:45:57 CST 2017]; parent: org.springframework.context.annotation.AnnotationConfigApplicationContext@7dc4513 2017-08-21 20:45:57.096 INFO 16768 --- [nio-9001-exec-8] f.a.AutowiredAnnotationBeanPostProcessor : JSR-330 'javax.inject.Inject' annotation found and supported for autowiring 2017-08-21 20:45:57.099 INFO 16768 --- [nio-9001-exec-8] o.s.boot.SpringApplication : Started application in 3.294 seconds (JVM running for 1514.761) 2017-08-21 20:45:57.099 INFO 16768 --- [nio-9001-exec-8] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@676107bb: startup date [Mon Aug 21 20:45:57 CST 2017]; parent: org.springframework.context.annotation.AnnotationConfigApplicationContext@7dc4513 2017-08-21 20:45:57.217 INFO 16768 --- [nio-9001-exec-8] o.s.cloud.bus.event.RefreshListener : Received remote refresh request. Keys refreshed []
|
通过日志可以分析出,battcn-config-server
重新加载了classpath:/config-server-order-default.yml
文件,并且客户端重新读取了[name='configService', propertySources=[MapPropertySource [name='classpath:/config-server-order-default.yml']]]
,有兴趣的可以DEBUG
源码看详细的处理过程…
- 疑问解答
在测试第四步中,之所以修改yaml
后重启,是因为我们的config
是本地的而不是GIT
仓库,所以项目没法加载,但是这种方式即使关闭了config
,调用过的服务依旧是可以正常使用的,包括旧的配置依旧正常读取使用,Config做了本地缓存
博客只演示了一个battcn-config-client
的情况,多个client
其实效果一样只需要刷新其中一个,剩下的都会跟着刷新,比如battcn-config-client
启动了3个实例,分别是9001,9002,9003
,访问:http://localhost:9001/bus/refresh,三个实例的结果都是一样
架构图
- 刷新范围
上面的例子中,我们通过向服务实例请求Spring Cloud Bus
的/bus/refresh
接口,从而触发总线上其他服务实例的/refresh
。但是有些特殊场景下(比如:灰度发布),我们希望可以刷新微服务中某个具体实例的配置。
Spring Cloud Bus
对这种场景也有很好的支持:/bus/refresh
接口还提供了destination
参数,用来定位具体要刷新的应用程序。比如,我们可以请求/bus/refresh?destination=customers:9000
,此时总线上的各应用实例会根据destination
属性的值来判断是否为自己的实例名,若符合才进行配置刷新,若不符合就忽略该消息。
destination
参数除了可以定位具体的实例之外,还可以用来定位具体的服务。定位服务的原理是通过使用Spring
的PathMatecher
(路径匹配)来实现,比如:/bus/refresh?destination=customers:**
(以冒号的路径分隔符:)来确定一个实例是否处理该消息,该配置的请求会触发customers
服务的所有实例进行刷新。
- 优化方案
既然访问任意端口都可以通知全部实例,那么我们利用刷新范围的方式,将battcn-config-server
也添加上spring-cloud-starter-bus-amqp
和 rabbitmq
的配置信息,访问:http://localhost:9000/bus/refresh?destination=battcn-config-client:** 结果一样,battcn-config-client
依然会去读取最新配置
优化后
主要做了这些改动:
1.在Config Server中也引入Spring Cloud Bus,将配置服务端也加入到消息总线中来。
2./bus/refresh
请求不在发送到具体服务实例上,而是发送给Config Server,并通过destination参数来指定需要更新配置的服务或实例。
参考博客:http://blog.didispace.com/springcloud7/
最新文章
- 免费SSL证书 之Let’s Encrypt申请与部署(Windows Nginx)
- OData V4 系列 Ajax请求 CRUD
- 【转】Weblogic的集群
- IE8下调用Active控件
- Entity Framework Code First (六)存储过程
- JAXB命名空间及命名空间前缀处理
- 模拟Select-Options对象实现多项数据输入功能
- git总结
- android解析json包(接口)
- Delphi CxGrid 汇总(4)
- Multiple View Geometry in Computer Vision Second Edition by Richard Hartley 读书笔记(二)
- ThinkPHP自动验证
- Java IO学习笔记三
- 自定义InputFormat和OutputFormat案例
- MVC4 中的Model显示设置(含显示Shared/DisplayTemplates和编辑Shared/EditorTemplates)
- 模仿jQuery的ajax的封装
- 一个简单的dropdown(CSS+jquery)
- 简单实现";Tomcat";
- jquery ajax中事件的执行顺序
- Python学习---基于JQuery的Ajax实现[快捷+底层$.ajax]
热门文章
- Java实现 LeetCode 257 二叉树的所有路径
- Java实现 LeetCode 82 删除排序链表中的重复元素 II(二)
- Java实现 LeetCode 10 正则表达式匹配
- Java实现 蓝桥杯 算法提高 歌唱比赛
- java实现蓝桥杯密码脱落
- effictive c++
- Maven发布Release到中心仓库历程记录(无个人域名)
- 浅谈Unity的脚本执行顺序
- GPIO功能框图
- Nice Jquery Validator 方法