一起来学SpringCloud之 - 消息总线(Bus)

文章目录

  1. 1. - Bus

  2. 2. - RabbitMQ搭建

  3. 3. - 开始

    1. 3.3.1. - 优化方案

    2. 3.1. - 测试

    3. 3.2. - 疑问解答

    4. 3.3. - 刷新范围

  4. 4. - 说点什么

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包

<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注解

@RestController
@RefreshScope
public class TestController {

    @Value("${order.name}")
    String orderName;

    @RequestMapping("/test")
    public String test() {
        return "client ====>>> " + orderName;
    }
}

 

4.给battcn-config-client配置rabbitmq信息

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 会看到如下内容,表示服正常

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

 

4.修改battcn-config-serverconfig-server-order-default.yml文件的内容

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 会看到如下内容,表示服正常

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

 

battcn-config-server日志

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日志

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,三个实例的结果都是一样

一起来学SpringCloud之 - 消息总线(Bus)-图片-1架构图

- 刷新范围

上面的例子中,我们通过向服务实例请求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-amqprabbitmq的配置信息,访问:http://localhost:9000/bus/refresh?destination=battcn-config-client:**  结果一样,battcn-config-client依然会去读取最新配置

一起来学SpringCloud之 - 消息总线(Bus)-图片-2优化后

主要做了这些改动:

1.在Config Server中也引入Spring Cloud Bus,将配置服务端也加入到消息总线中来。
2./bus/refresh请求不在发送到具体服务实例上,而是发送给Config Server,并通过destination参数来指定需要更新配置的服务或实例。

参考博客:http://blog.didispace.com/springcloud7/

- 说点什么

本章代码(battcn-config-server/battcn-config-client):https://git.oschina.net/battcn/battcn-cloud/tree/master/battcn-cloud-bus


推荐教程

Java设计模式

创建模式、结构模式、行为模式

Maven教程

Maven是一个项目管理和构建工具

Lucene教程

Lucene是一个开源的基于Java的搜索库

JUnit教程

JUnit是Java编程语言的单元测试框架

Java算法

排序、二叉树、红黑树

Log4j教程

log4j是一种用Java编写的可靠,快速和灵活的日志框架(API)

StringBoot教程

StringBoot实战操作演练

mybatis文档手册

Mybatis基础语法、实例讲解

SpringCloud教程

服务发现、断路器、智能路由

Guava教程

Guava是开源的Java工具库

Elasticsearch教程

一款强大的搜索引擎