Spring Cloud Bus将分布式系统的节点与轻量级消息代理链接。可以用于通知状态更改(例如配置更改)或其他管理指令。一个关键的地方是,Bus就像一个分布式执行器,用于扩展的Spring Boot应用程序,同时还可以用作应用程序之间的通信通道…

- Bus

Spring Cloud Bus是通过添加Spring Boot自动配置(Auto Configuration),如果它在class path中被检测到,则可以工作。所有启用Spring Cloud Bus的都需要添加spring-cloud-starter-bus-amqpspring-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-serverbattcn-config-client

3.访问:http://localhost:9001/test 会看到如下内容,表示服正常

1
client ====>>> My Name's Order Service,Are you Afraid?

4.修改battcn-config-serverconfig-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参数除了可以定位具体的实例之外,还可以用来定位具体的服务。定位服务的原理是通过使用SpringPathMatecher(路径匹配)来实现,比如:/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/

最新文章

  1. 免费SSL证书 之Let’s Encrypt申请与部署(Windows Nginx)
  2. OData V4 系列 Ajax请求 CRUD
  3. 【转】Weblogic的集群
  4. IE8下调用Active控件
  5. Entity Framework Code First (六)存储过程
  6. JAXB命名空间及命名空间前缀处理
  7. 模拟Select-Options对象实现多项数据输入功能
  8. git总结
  9. android解析json包(接口)
  10. Delphi CxGrid 汇总(4)
  11. Multiple View Geometry in Computer Vision Second Edition by Richard Hartley 读书笔记(二)
  12. ThinkPHP自动验证
  13. Java IO学习笔记三
  14. 自定义InputFormat和OutputFormat案例
  15. MVC4 中的Model显示设置(含显示Shared/DisplayTemplates和编辑Shared/EditorTemplates)
  16. 模仿jQuery的ajax的封装
  17. 一个简单的dropdown(CSS+jquery)
  18. 简单实现&quot;Tomcat&quot;
  19. jquery ajax中事件的执行顺序
  20. Python学习---基于JQuery的Ajax实现[快捷+底层$.ajax]

热门文章

  1. Java实现 LeetCode 257 二叉树的所有路径
  2. Java实现 LeetCode 82 删除排序链表中的重复元素 II(二)
  3. Java实现 LeetCode 10 正则表达式匹配
  4. Java实现 蓝桥杯 算法提高 歌唱比赛
  5. java实现蓝桥杯密码脱落
  6. effictive c++
  7. Maven发布Release到中心仓库历程记录(无个人域名)
  8. 浅谈Unity的脚本执行顺序
  9. GPIO功能框图
  10. Nice Jquery Validator 方法