Spring Cloud(九):配置中心(消息总线)【Finchley 版】

 发表于 2018-04-19 |  更新于 2018-05-07 | 

我们在 Spring Cloud(七):配置中心(Git、Refresh) 中讲到,如果需要客户端获取到最新的配置信息需要执行refresh,我们可以利用 Webhook 的机制每次提交代码发送请求来刷新客户端,当客户端越来越多的时候,需要每个客户端都执行一遍,这种方案就不太适合了。使用 Spring Cloud Bus 可以完美解决这一问题。

Spring Cloud Bus

Spring Cloud Bus 通过轻量消息代理连接各个分布的节点。这会用在广播状态的变化(例如配置变化)或者其他的消息指令。Spring Bus 的一个核心思想是通过分布式的启动器对 Spring Boot 应用进行扩展,也可以用来建立一个多个应用之间的通信频道。目前唯一实现的方式是用 Amqp 消息代理作为通道,同样特性的设置(有些取决于通道的设置)在更多通道的文档中。

Spring Cloud Bus 被国内很多都翻译为消息总线,也挺形象的。大家可以将它理解为管理和传播所有分布式项目中的消息既可,其实本质是利用了 MQ 的广播机制在分布式的系统中传播消息,目前常用的有 Kafka 和 RabbitMQ。利用 Bus 的机制可以做很多的事情,其中配置中心客户端刷新就是典型的应用场景之一,我们用一张图来描述 Bus 在配置中心使用的机制。

实战

我们选择上一篇文章 Spring Cloud(八):配置中心(服务化与高可用) 版本的示例代码来改造, MQ 我们使用 RabbitMQ 来做示例。

因为用的是 Spring Boot 2.0.1 + Spring Cloud Finchley.RC1,更新较多,坑也比较多,这里就把代码再贴一遍了。

示例代码:GitHub

服务端

POM 配置

在 pom.xml 里添加,这 4 个是必须的

复制

  1. 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
  1. <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-client</artifactId>
    </dependency>
    <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-bus</artifactId>
    </dependency>
    <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-stream-binder-rabbit</artifactId>
    </dependency>

配置文件

application.yml 内容如下

复制

  1. 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
  1. spring:
    application:
    name: config-server
    cloud:
    config:
    server:
    git:
    uri: https://github.com/zhaoyibo/spring-cloud-study
    search-paths: config-repo
    bus:
    enabled: true
    trace:
    enabled: true
    server:
    port: 12000
    eureka:
    client:
    service-url:
    defaultZone: http://localhost:7000/eureka/
    management:
    endpoints:
    web:
    exposure:
    include: bus-refresh

启动类

@EnableConfigServer注解

复制

  1. 1
    2
    3
    4
    5
    6
    7
    8
  1. @SpringBootApplication
    @EnableConfigServer
    public class ConfigServerApplication {
  2.  
  3. public static void main(String[] args) {
    SpringApplication.run(ConfigServerApplication.class, args);
    }
    }

客户端

POM 配置

在 pom.xml 里添加以下依赖,前 5 个是必须的,最后一个 webflux 你可以用 web 来代替

复制

  1. 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
  1. <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-client</artifactId>
    </dependency>
    <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-bus</artifactId>
    </dependency>
    <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-stream-binder-rabbit</artifactId>
    </dependency>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
    </dependency>

这里容易漏掉spring-boot-starter-actuator,如果缺了这个,当对服务端执行/actuator/bus-refresh的时候,客户端接收不到信息,Console 里只会显示以下信息(我就是在这儿被困了好久……)

复制

  1. 1
    2
    3
  1. 2018-04-19 18:50:05.711 INFO 39762 --- [vOu-GI8c8mJtQ-1] o.s.a.r.c.CachingConnectionFactory : Attempting to connect to: [localhost:5672]
    2018-04-19 18:50:05.739 INFO 39762 --- [vOu-GI8c8mJtQ-1] o.s.a.r.c.CachingConnectionFactory : Created new connection: rabbitConnectionFactory.publisher#2bc15b3b:0/SimpleConnection@14eb0d5e [delegate=amqp://guest@127.0.0.1:5672/, localPort= 60107]
    2018-04-19 18:50:05.749 INFO 39762 --- [vOu-GI8c8mJtQ-1] o.s.amqp.rabbit.core.RabbitAdmin : Auto-declaring a non-durable, auto-delete, or exclusive Queue (springCloudBus.anonymous.bOoVqQuSQvOu-GI8c8mJtQ) durable:false, auto-delete:true, exclusive:true. It will be redeclared if the broker stops and is restarted while the connection factory is alive, but all messages will be lost.

配置文件

还是分为两个,分别如下
application.yml

复制

  1. 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
  1. spring:
    application:
    name: config-client
    cloud:
    bus:
    trace:
    enabled: true
    enabled: true
    server:
    port: 13000

bootstrap.yml

复制

  1. 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
  1. spring:
    cloud:
    config:
    name: config-client
    profile: dev
    label: master
    discovery:
    enabled: true
    service-id: config-server
    eureka:
    client:
    service-url:
    defaultZone: http://localhost:7000/eureka/

Controller

复制

  1. 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
  1. @RestController
    @RefreshScope
    public class HelloController {
  2.  
  3. @Value("${info.profile:error}")
    private String profile;
  4.  
  5. @GetMapping("/info")
    public Mono<String> hello() {
    return Mono.justOrEmpty(profile);
    }
  6.  
  7. }

@RefreshScope必须加,否则客户端会受到服务端的更新消息,但是更新不了,因为不知道更新哪里的。

至于启动主类,用默认生成的不用改,就不贴了。

测试

分别启动 eureka、config-server 和两个 config-client

复制

  1. 1
    2
    3
    4
    5
    6
  1. // 打包
    ./mvnw clean package -Dmaven.test.skip=true
  2.  
  3. // 运行两个 client
    java -jar target/spring-cloud-config-client-0.0.1-SNAPSHOT.jar --server.port=13000
    java -jar target/spring-cloud-config-client-0.0.1-SNAPSHOT.jar --server.port=13001

启动后,RabbitMQ 中会自动创建一个 topic 类型的 Exchange 和两个以springCloudBus.anonymous.开头的匿名 Queue

我们访问 http://localhost:13000/info 和 http://localhost:13001/info 返回内容的都是dev
将 Git 中的配置信息由dev改为dev bus,并执行

复制

  1. 1
  1. curl -X POST http://localhost:12000/actuator/bus-refresh/

再次访问 http://localhost:13000/info 和 http://localhost:13001/info 这时返回内容就是修改之后的dev bus了,说明成功了。

服务端在刷新接口产生的的日志:

复制

  1. 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
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
  1. 2018-04-19 18:37:08.034 INFO 38109 --- [io-12000-exec-9] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@371b3397: startup date [Thu Apr 19 18:37:08 CST 2018]; root of context hierarchy
    2018-04-19 18:37:08.148 INFO 38109 --- [io-12000-exec-9] f.a.AutowiredAnnotationBeanPostProcessor : JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
    2018-04-19 18:37:08.163 INFO 38109 --- [io-12000-exec-9] trationDelegate$BeanPostProcessorChecker : Bean 'configurationPropertiesRebinderAutoConfiguration' of type [org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration$$EnhancerBySpringCGLIB$$32744ef0] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
    2018-04-19 18:37:08.294 INFO 38109 --- [io-12000-exec-9] o.s.boot.SpringApplication : No active profile set, falling back to default profiles: default
    2018-04-19 18:37:08.301 INFO 38109 --- [io-12000-exec-9] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@3e669fd6: startup date [Thu Apr 19 18:37:08 CST 2018]; parent: org.springframework.context.annotation.AnnotationConfigApplicationContext@371b3397
    2018-04-19 18:37:08.306 INFO 38109 --- [io-12000-exec-9] f.a.AutowiredAnnotationBeanPostProcessor : JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
    2018-04-19 18:37:08.330 INFO 38109 --- [io-12000-exec-9] o.s.boot.SpringApplication : Started application in 0.391 seconds (JVM running for 511.143)
    2018-04-19 18:37:08.333 INFO 38109 --- [io-12000-exec-9] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@3e669fd6: startup date [Thu Apr 19 18:37:08 CST 2018]; parent: org.springframework.context.annotation.AnnotationConfigApplicationContext@371b3397
    2018-04-19 18:37:08.334 INFO 38109 --- [io-12000-exec-9] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@371b3397: startup date [Thu Apr 19 18:37:08 CST 2018]; root of context hierarchy
    2018-04-19 18:37:08.985 INFO 38109 --- [io-12000-exec-9] com.netflix.discovery.DiscoveryClient : Shutting down DiscoveryClient ...
    2018-04-19 18:37:09.007 INFO 38109 --- [io-12000-exec-9] o.s.c.n.eureka.InstanceInfoFactory : Setting initial instance status as: STARTING
    2018-04-19 18:37:12.012 INFO 38109 --- [io-12000-exec-9] com.netflix.discovery.DiscoveryClient : Unregistering ...
    2018-04-19 18:37:12.019 INFO 38109 --- [io-12000-exec-9] com.netflix.discovery.DiscoveryClient : DiscoveryClient_CONFIG-SERVER/172.16.106.93:config-server:12000 - deregister status: 200
    2018-04-19 18:37:12.030 INFO 38109 --- [io-12000-exec-9] com.netflix.discovery.DiscoveryClient : Completed shut down of DiscoveryClient
    2018-04-19 18:37:12.032 INFO 38109 --- [io-12000-exec-9] com.netflix.discovery.DiscoveryClient : Initializing Eureka in region us-east-1
    2018-04-19 18:37:12.037 INFO 38109 --- [io-12000-exec-9] c.n.d.provider.DiscoveryJerseyProvider : Using JSON encoding codec LegacyJacksonJson
    2018-04-19 18:37:12.037 INFO 38109 --- [io-12000-exec-9] c.n.d.provider.DiscoveryJerseyProvider : Using JSON decoding codec LegacyJacksonJson
    2018-04-19 18:37:12.037 INFO 38109 --- [io-12000-exec-9] c.n.d.provider.DiscoveryJerseyProvider : Using XML encoding codec XStreamXml
    2018-04-19 18:37:12.037 INFO 38109 --- [io-12000-exec-9] c.n.d.provider.DiscoveryJerseyProvider : Using XML decoding codec XStreamXml
    2018-04-19 18:37:12.145 INFO 38109 --- [io-12000-exec-9] c.n.d.s.r.aws.ConfigClusterResolver : Resolving eureka endpoints via configuration
    2018-04-19 18:37:12.146 INFO 38109 --- [io-12000-exec-9] com.netflix.discovery.DiscoveryClient : Disable delta property : false
    2018-04-19 18:37:12.146 INFO 38109 --- [io-12000-exec-9] com.netflix.discovery.DiscoveryClient : Single vip registry refresh property : null
    2018-04-19 18:37:12.146 INFO 38109 --- [io-12000-exec-9] com.netflix.discovery.DiscoveryClient : Force full registry fetch : false
    2018-04-19 18:37:12.146 INFO 38109 --- [io-12000-exec-9] com.netflix.discovery.DiscoveryClient : Application is null : false
    2018-04-19 18:37:12.146 INFO 38109 --- [io-12000-exec-9] com.netflix.discovery.DiscoveryClient : Registered Applications size is zero : true
    2018-04-19 18:37:12.146 INFO 38109 --- [io-12000-exec-9] com.netflix.discovery.DiscoveryClient : Application version is -1: true
    2018-04-19 18:37:12.146 INFO 38109 --- [io-12000-exec-9] com.netflix.discovery.DiscoveryClient : Getting all instance registry info from the eureka server
    2018-04-19 18:37:12.151 INFO 38109 --- [io-12000-exec-9] com.netflix.discovery.DiscoveryClient : The response status is 200
    2018-04-19 18:37:12.152 INFO 38109 --- [io-12000-exec-9] com.netflix.discovery.DiscoveryClient : Starting heartbeat executor: renew interval is: 30
    2018-04-19 18:37:12.152 INFO 38109 --- [io-12000-exec-9] c.n.discovery.InstanceInfoReplicator : InstanceInfoReplicator onDemand update allowed rate per min is 4
    2018-04-19 18:37:12.153 INFO 38109 --- [io-12000-exec-9] com.netflix.discovery.DiscoveryClient : Discovery Client initialized at timestamp 1524134232153 with initial instances count: 3
    2018-04-19 18:37:12.154 INFO 38109 --- [io-12000-exec-9] o.s.c.n.e.s.EurekaServiceRegistry : Unregistering application config-server with eureka with status DOWN
    2018-04-19 18:37:12.154 INFO 38109 --- [io-12000-exec-9] o.s.c.n.e.s.EurekaServiceRegistry : Registering application config-server with eureka with status UP
    2018-04-19 18:37:12.154 WARN 38109 --- [io-12000-exec-9] com.netflix.discovery.DiscoveryClient : Saw local status change event StatusChangeEvent [timestamp=1524134232154, current=UP, previous=DOWN]
    2018-04-19 18:37:12.155 INFO 38109 --- [nfoReplicator-0] com.netflix.discovery.DiscoveryClient : DiscoveryClient_CONFIG-SERVER/172.16.106.93:config-server:12000: registering service...
    2018-04-19 18:37:12.155 INFO 38109 --- [io-12000-exec-9] o.s.cloud.bus.event.RefreshListener : Received remote refresh request. Keys refreshed []
    2018-04-19 18:37:12.165 INFO 38109 --- [nfoReplicator-0] com.netflix.discovery.DiscoveryClient : DiscoveryClient_CONFIG-SERVER/172.16.106.93:config-server:12000 - registration status: 204
    2018-04-19 18:37:14.044 INFO 38109 --- [o-12000-exec-10] .c.s.e.MultipleJGitEnvironmentRepository : Fetched for remote master and found 1 updates
    2018-04-19 18:37:14.105 INFO 38109 --- [o-12000-exec-10] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@5e8ec379: startup date [Thu Apr 19 18:37:14 CST 2018]; root of context hierarchy
    2018-04-19 18:37:14.108 INFO 38109 --- [o-12000-exec-10] f.a.AutowiredAnnotationBeanPostProcessor : JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
    2018-04-19 18:37:14.112 INFO 38109 --- [o-12000-exec-10] o.s.c.c.s.e.NativeEnvironmentRepository : Adding property source: file:/var/folders/rm/v0glpzzn7dxd1nj5nk00ssq00000gn/T/config-repo-520847716419946533/config-repo/config-client-dev.yml
    2018-04-19 18:37:14.112 INFO 38109 --- [o-12000-exec-10] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@5e8ec379: startup date [Thu Apr 19 18:37:14 CST 2018]; root of context hierarchy
    2018-04-19 18:37:15.386 INFO 38109 --- [io-12000-exec-1] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@62062974: startup date [Thu Apr 19 18:37:15 CST 2018]; root of context hierarchy
    2018-04-19 18:37:15.388 INFO 38109 --- [io-12000-exec-1] f.a.AutowiredAnnotationBeanPostProcessor : JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
    2018-04-19 18:37:15.393 INFO 38109 --- [io-12000-exec-1] o.s.c.c.s.e.NativeEnvironmentRepository : Adding property source: file:/var/folders/rm/v0glpzzn7dxd1nj5nk00ssq00000gn/T/config-repo-520847716419946533/config-repo/config-client-dev.yml
    2018-04-19 18:37:15.393 INFO 38109 --- [io-12000-exec-1] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@62062974: startup date [Thu Apr 19 18:37:15 CST 2018]; root of context hierarchy

客户端在刷新接口产生的的日志:

复制

  1. 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
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
  1. 2018-04-19 18:35:45.899 INFO 38808 --- [x6SsSoOn6XStg-1] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@43b9bce7: startup date [Thu Apr 19 18:35:45 CST 2018]; root of context hierarchy
    2018-04-19 18:35:46.292 INFO 38808 --- [x6SsSoOn6XStg-1] f.a.AutowiredAnnotationBeanPostProcessor : JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
    2018-04-19 18:35:46.448 INFO 38808 --- [x6SsSoOn6XStg-1] trationDelegate$BeanPostProcessorChecker : Bean 'configurationPropertiesRebinderAutoConfiguration' of type [org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration$$EnhancerBySpringCGLIB$$494fdb28] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
    2018-04-19 18:35:46.778 INFO 38808 --- [x6SsSoOn6XStg-1] o.s.c.n.eureka.InstanceInfoFactory : Setting initial instance status as: STARTING
    2018-04-19 18:35:46.819 INFO 38808 --- [x6SsSoOn6XStg-1] com.netflix.discovery.DiscoveryClient : Initializing Eureka in region us-east-1
    2018-04-19 18:35:46.828 INFO 38808 --- [x6SsSoOn6XStg-1] c.n.d.provider.DiscoveryJerseyProvider : Using JSON encoding codec LegacyJacksonJson
    2018-04-19 18:35:46.828 INFO 38808 --- [x6SsSoOn6XStg-1] c.n.d.provider.DiscoveryJerseyProvider : Using JSON decoding codec LegacyJacksonJson
    2018-04-19 18:35:46.828 INFO 38808 --- [x6SsSoOn6XStg-1] c.n.d.provider.DiscoveryJerseyProvider : Using XML encoding codec XStreamXml
    2018-04-19 18:35:46.829 INFO 38808 --- [x6SsSoOn6XStg-1] c.n.d.provider.DiscoveryJerseyProvider : Using XML decoding codec XStreamXml
    2018-04-19 18:35:47.017 INFO 38808 --- [x6SsSoOn6XStg-1] c.n.d.s.r.aws.ConfigClusterResolver : Resolving eureka endpoints via configuration
    2018-04-19 18:35:47.019 INFO 38808 --- [x6SsSoOn6XStg-1] com.netflix.discovery.DiscoveryClient : Disable delta property : false
    2018-04-19 18:35:47.019 INFO 38808 --- [x6SsSoOn6XStg-1] com.netflix.discovery.DiscoveryClient : Single vip registry refresh property : null
    2018-04-19 18:35:47.019 INFO 38808 --- [x6SsSoOn6XStg-1] com.netflix.discovery.DiscoveryClient : Force full registry fetch : false
    2018-04-19 18:35:47.019 INFO 38808 --- [x6SsSoOn6XStg-1] com.netflix.discovery.DiscoveryClient : Application is null : false
    2018-04-19 18:35:47.019 INFO 38808 --- [x6SsSoOn6XStg-1] com.netflix.discovery.DiscoveryClient : Registered Applications size is zero : true
    2018-04-19 18:35:47.019 INFO 38808 --- [x6SsSoOn6XStg-1] com.netflix.discovery.DiscoveryClient : Application version is -1: true
    2018-04-19 18:35:47.019 INFO 38808 --- [x6SsSoOn6XStg-1] com.netflix.discovery.DiscoveryClient : Getting all instance registry info from the eureka server
    2018-04-19 18:35:47.031 INFO 38808 --- [x6SsSoOn6XStg-1] com.netflix.discovery.DiscoveryClient : The response status is 200
    2018-04-19 18:35:47.034 INFO 38808 --- [x6SsSoOn6XStg-1] com.netflix.discovery.DiscoveryClient : Not registering with Eureka server per configuration
    2018-04-19 18:35:47.035 INFO 38808 --- [x6SsSoOn6XStg-1] com.netflix.discovery.DiscoveryClient : Discovery Client initialized at timestamp 1524134147035 with initial instances count: 3
    2018-04-19 18:35:47.287 INFO 38808 --- [x6SsSoOn6XStg-1] c.c.c.ConfigServicePropertySourceLocator : Fetching config from server at: http://172.16.106.93:12000/
    2018-04-19 18:35:51.550 INFO 38808 --- [x6SsSoOn6XStg-1] c.c.c.ConfigServicePropertySourceLocator : Located environment: name=config-client, profiles=[dev], label=master, version=77913e8aed0054fd05fe6889db20baf96e781632, state=null
    2018-04-19 18:35:51.550 INFO 38808 --- [x6SsSoOn6XStg-1] b.c.PropertySourceBootstrapConfiguration : Located property source: CompositePropertySource {name='configService', propertySources=[MapPropertySource {name='configClient'}, MapPropertySource {name='https://github.com/zhaoyibo/spring-cloud-study/config-repo/config-client-dev.yml'}]}
    2018-04-19 18:35:51.553 INFO 38808 --- [x6SsSoOn6XStg-1] o.s.boot.SpringApplication : No active profile set, falling back to default profiles: default
    2018-04-19 18:35:51.557 INFO 38808 --- [x6SsSoOn6XStg-1] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@5c32759e: startup date [Thu Apr 19 18:35:51 CST 2018]; parent: org.springframework.context.annotation.AnnotationConfigApplicationContext@43b9bce7
    2018-04-19 18:35:51.569 INFO 38808 --- [x6SsSoOn6XStg-1] f.a.AutowiredAnnotationBeanPostProcessor : JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
    2018-04-19 18:35:51.626 INFO 38808 --- [x6SsSoOn6XStg-1] o.s.boot.SpringApplication : Started application in 6.011 seconds (JVM running for 312.876)
    2018-04-19 18:35:51.627 INFO 38808 --- [x6SsSoOn6XStg-1] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@5c32759e: startup date [Thu Apr 19 18:35:51 CST 2018]; parent: org.springframework.context.annotation.AnnotationConfigApplicationContext@43b9bce7
    2018-04-19 18:35:51.630 INFO 38808 --- [x6SsSoOn6XStg-1] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@43b9bce7: startup date [Thu Apr 19 18:35:45 CST 2018]; root of context hierarchy
    2018-04-19 18:35:51.630 INFO 38808 --- [x6SsSoOn6XStg-1] com.netflix.discovery.DiscoveryClient : Shutting down DiscoveryClient ...
    2018-04-19 18:35:51.641 INFO 38808 --- [x6SsSoOn6XStg-1] com.netflix.discovery.DiscoveryClient : Completed shut down of DiscoveryClient
    2018-04-19 18:35:51.839 INFO 38808 --- [x6SsSoOn6XStg-1] com.netflix.discovery.DiscoveryClient : Shutting down DiscoveryClient ...
    2018-04-19 18:35:51.840 INFO 38808 --- [x6SsSoOn6XStg-1] o.s.c.n.eureka.InstanceInfoFactory : Setting initial instance status as: STARTING
    2018-04-19 18:35:54.848 INFO 38808 --- [x6SsSoOn6XStg-1] com.netflix.discovery.DiscoveryClient : Unregistering ...
    2018-04-19 18:35:54.854 INFO 38808 --- [x6SsSoOn6XStg-1] com.netflix.discovery.DiscoveryClient : DiscoveryClient_CONFIG-CLIENT/172.16.106.93:config-client:13001 - deregister status: 200
    2018-04-19 18:35:54.863 INFO 38808 --- [x6SsSoOn6XStg-1] com.netflix.discovery.DiscoveryClient : Completed shut down of DiscoveryClient
    2018-04-19 18:35:54.865 INFO 38808 --- [x6SsSoOn6XStg-1] com.netflix.discovery.DiscoveryClient : Initializing Eureka in region us-east-1
    2018-04-19 18:35:54.867 INFO 38808 --- [x6SsSoOn6XStg-1] c.n.d.provider.DiscoveryJerseyProvider : Using JSON encoding codec LegacyJacksonJson
    2018-04-19 18:35:54.867 INFO 38808 --- [x6SsSoOn6XStg-1] c.n.d.provider.DiscoveryJerseyProvider : Using JSON decoding codec LegacyJacksonJson
    2018-04-19 18:35:54.867 INFO 38808 --- [x6SsSoOn6XStg-1] c.n.d.provider.DiscoveryJerseyProvider : Using XML encoding codec XStreamXml
    2018-04-19 18:35:54.867 INFO 38808 --- [x6SsSoOn6XStg-1] c.n.d.provider.DiscoveryJerseyProvider : Using XML decoding codec XStreamXml
    2018-04-19 18:35:54.937 INFO 38808 --- [x6SsSoOn6XStg-1] c.n.d.s.r.aws.ConfigClusterResolver : Resolving eureka endpoints via configuration
    2018-04-19 18:35:54.938 INFO 38808 --- [x6SsSoOn6XStg-1] com.netflix.discovery.DiscoveryClient : Disable delta property : false
    2018-04-19 18:35:54.938 INFO 38808 --- [x6SsSoOn6XStg-1] com.netflix.discovery.DiscoveryClient : Single vip registry refresh property : null
    2018-04-19 18:35:54.938 INFO 38808 --- [x6SsSoOn6XStg-1] com.netflix.discovery.DiscoveryClient : Force full registry fetch : false
    2018-04-19 18:35:54.938 INFO 38808 --- [x6SsSoOn6XStg-1] com.netflix.discovery.DiscoveryClient : Application is null : false
    2018-04-19 18:35:54.938 INFO 38808 --- [x6SsSoOn6XStg-1] com.netflix.discovery.DiscoveryClient : Registered Applications size is zero : true
    2018-04-19 18:35:54.939 INFO 38808 --- [x6SsSoOn6XStg-1] com.netflix.discovery.DiscoveryClient : Application version is -1: true
    2018-04-19 18:35:54.939 INFO 38808 --- [x6SsSoOn6XStg-1] com.netflix.discovery.DiscoveryClient : Getting all instance registry info from the eureka server
    2018-04-19 18:35:54.949 INFO 38808 --- [x6SsSoOn6XStg-1] com.netflix.discovery.DiscoveryClient : The response status is 200
    2018-04-19 18:35:54.951 INFO 38808 --- [x6SsSoOn6XStg-1] com.netflix.discovery.DiscoveryClient : Starting heartbeat executor: renew interval is: 30
    2018-04-19 18:35:54.952 INFO 38808 --- [x6SsSoOn6XStg-1] c.n.discovery.InstanceInfoReplicator : InstanceInfoReplicator onDemand update allowed rate per min is 4
    2018-04-19 18:35:54.953 INFO 38808 --- [x6SsSoOn6XStg-1] com.netflix.discovery.DiscoveryClient : Discovery Client initialized at timestamp 1524134154953 with initial instances count: 3
    2018-04-19 18:35:54.954 INFO 38808 --- [x6SsSoOn6XStg-1] o.s.c.n.e.s.EurekaServiceRegistry : Unregistering application config-client with eureka with status DOWN
    2018-04-19 18:35:54.975 INFO 38808 --- [x6SsSoOn6XStg-1] o.s.c.n.e.s.EurekaServiceRegistry : Registering application config-client with eureka with status UP
    2018-04-19 18:35:54.977 WARN 38808 --- [x6SsSoOn6XStg-1] com.netflix.discovery.DiscoveryClient : Saw local status change event StatusChangeEvent [timestamp=1524134154977, current=UP, previous=DOWN]
    2018-04-19 18:35:54.980 INFO 38808 --- [nfoReplicator-0] com.netflix.discovery.DiscoveryClient : DiscoveryClient_CONFIG-CLIENT/172.16.106.93:config-client:13001: registering service...
    2018-04-19 18:35:54.986 INFO 38808 --- [x6SsSoOn6XStg-1] o.s.cloud.bus.event.RefreshListener : Received remote refresh request. Keys refreshed [config.client.version, info.profile]
    2018-04-19 18:35:54.999 INFO 38808 --- [nfoReplicator-0] com.netflix.discovery.DiscoveryClient : DiscoveryClient_CONFIG-CLIENT/172.16.106.93:config-client:13001 - registration status: 204

思考

这里我们再想一个问题:如果对客户端使用 /actuator/bus-refresh会发生什么呢?是只刷新了当前客户端还是刷新全部客户端,还是一个都没刷新呢?

不如来试一下吧:

首先我们需要把客户端上的bus-refresh端点给放出来

复制

  1. 1
    2
    3
    4
    5
  1. management:
    endpoints:
    web:
    exposure:
    include: bus-refresh

重启客户端,这时候访问 http://localhost:13000/info 和 http://localhost:13001/info 返回的都是dev bus

去 Git 里把配置信息由dev bus改为dev,然后执行

复制

  1. 1
  1. curl -X POST http://localhost:13000/actuator/bus-refresh/

再次访问 http://localhost:13000/info 和 http://localhost:13001/info 发现这时返回的都是dev了,说明只要开启 Spring Cloud Bus 后,不管是对 config-server 还是 config-client 执行/actuator/bus-refresh都是可以更新配置的。

其它

因为版本问题,以下两部分还未在该版本进行验证。待有时间了试一下。

局部刷新

某些场景下(例如灰度发布),我们可能只想刷新部分微服务的配置,此时可通过/actuator/bus-refresh/{destination}端点的 destination 参数来定位要刷新的应用程序。

例如:/actuator/bus-refresh/customers:8000,这样消息总线上的微服务实例就会根据 destination 参数的值来判断是否需要要刷新。其中,customers:8000指的是各个微服务的 ApplicationContext ID。

destination 参数也可以用来定位特定的微服务。例如:/actuator/bus-refresh/customers:**,这样就可以触发 customers 微服务所有实例的配置刷新。

跟踪总线事件

一些场景下,我们可能希望知道 Spring Cloud Bus 事件传播的细节。此时,我们可以跟踪总线事件(RemoteApplicationEvent 的子类都是总线事件)。

跟踪总线事件非常简单,只需设置spring.cloud.bus.trace.enabled=true,这样在/actuator/bus-refresh端点被请求后,访问 /trace (现在好像是/actuator/httptrace)端点就可获得 类似如下的结果

复制

  1. 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
    26
    27
    28
    29
    30
  1. {
    "timestamp": 1495851419032,
    "info": {
    "signal": "spring.cloud.bus.ack",
    "type": "RefreshRemoteApplicationEvent",
    "id": "c4d374b7-58ea-4928-a312-31984def293b",
    "origin": "stores:8002",
    "destination": "*:**"
    }
    },
    {
    "timestamp": 1495851419033,
    "info": {
    "signal": "spring.cloud.bus.sent",
    "type": "RefreshRemoteApplicationEvent",
    "id": "c4d374b7-58ea-4928-a312-31984def293b",
    "origin": "spring-cloud-config-client:8001",
    "destination": "*:**"
    }
    },
    {
    "timestamp": 1495851422175,
    "info": {
    "signal": "spring.cloud.bus.ack",
    "type": "RefreshRemoteApplicationEvent",
    "id": "c4d374b7-58ea-4928-a312-31984def293b",
    "origin": "customers:8001",
    "destination": "*:**"
    }
    }

这个日志显示了customers:8001发出了 RefreshRemoteApplicationEvent 事件,广播给所有的服务,被customers:9000stores:8081接受到了。想要对接受到的消息自定义自己的处理方式的话,可以添加@EventListener注解的 AckRemoteApplicationEvent 和 SentApplicationEvent 类型到你自己的应用中。或者到 TraceRepository 类中,直接处理数据。

这样,我们就可清晰地知道事件的传播细节。

相关阅读

Spring Cloud(一):服务治理技术概览
Spring Cloud(二):服务注册与发现 Eureka
Spring Cloud(三):服务提供与调用 Eureka
Spring Cloud(四):服务容错保护 Hystrix
Spring Cloud(五):Hystrix 监控面板
Spring Cloud(六):Hystrix 监控数据聚合 Turbine
Spring Cloud(七):配置中心(Git 版与动态刷新)
Spring Cloud(八):配置中心(服务化与高可用)
Spring Cloud(九):配置中心(消息总线)
Spring Cloud(十):服务网关 Zuul(路由)
Spring Cloud(十一):服务网关 Zuul(过滤器)
Spring Cloud(十二):分布式链路跟踪(Sleuth 与 Zipkin)

示例代码:GitHub

参考

springcloud(九):配置中心和消息总线(配置中心终结版)
Spring Cloud - Push Notifications and Spring Cloud Bus
Refreshable Configuration using Spring Cloud Config Server, Spring Cloud Bus, RabbitMQ and Git
springboot 2.0.0.RELEASE +spring cloud Finchley.M7 +springcloud bus+kafka 实现配置动态刷新
Config Server——使用 Spring Cloud Bus 自动刷新配置

Spring Cloud(九):配置中心(消息总线)【Finchley 版】的更多相关文章

  1. Spring Cloud 系列之 Bus 消息总线

    什么是消息总线 消息代理中间件构建一个共用的消息主题让所有微服务实例订阅,当该消息主题产生消息时会被所有微服务实例监听和消费. 消息代理又是什么?消息代理是一个消息验证.传输.路由的架构模式,主要用来 ...

  2. 跟我学SpringCloud | 第七篇:Spring Cloud Config 配置中心高可用和refresh

    SpringCloud系列教程 | 第七篇:Spring Cloud Config 配置中心高可用和refresh Springboot: 2.1.6.RELEASE SpringCloud: Gre ...

  3. 微服务SpringCloud之Spring Cloud Config配置中心Git

    微服务以单个接口为颗粒度,一个接口可能就是一个项目,如果每个项目都包含一个配置文件,一个系统可能有几十或上百个小项目组成,那配置文件也会有好多,对后续修改维护也是比较麻烦,就和前面的服务注册一样,服务 ...

  4. 微服务SpringCloud之Spring Cloud Config配置中心服务化

    在前面两篇Spring Cloud Config配置中心的博客中都是需要指定配置服务的地址url:spring.cloud.config.uri,客户端都是直接调用配置中心的server端来获取配置文 ...

  5. spring cloud --- config 配置中心 [本地、git获取配置文件]

    spring boot      1.5.9.RELEASE spring cloud    Dalston.SR1 1.前言 spring cloud config 配置中心是什么? 为了统一管理配 ...

  6. Spring Cloud Config 配置中心实践过程中,你需要了解这些细节!

    本文导读: Spring Cloud Config 基本概念 Spring Cloud Config 客户端加载流程 Spring Cloud Config 基于消息总线配置 Spring Cloud ...

  7. 一起来学Spring Cloud | 第八章:消息总线(Spring Cloud Bus)

    上一章节,我们讲解了分布式配置中心spring cloud config,我们把配置项存放在git或者本地,当我们修改配置时,需要重新启动服务才能生效.但是在生产上,一个服务部署了多台机器,重新启动比 ...

  8. 玩转Spring Cloud之配置中心(config server &config client)

     本文内容导航: 一.搭建配置服务中心(config server) 1.1.git方式 1.2.svn方式 1.3.本地文件方式 1.4.解决配置中包含中文内容返回乱码问题 二.搭建配置消费客户端( ...

  9. Spring Cloud之配置中心搭建

    一.配置中心服务端搭建 1)引入相关Maven坐标 <dependency> <groupId>org.springframework.cloud</groupId> ...

  10. Spring Cloud Config 配置中心高可用

    详细参见 <Spring Cloud 与 Docker微服务架构实战> p163-9.10 Spring Cloud Config 与 Eureka 配合使用 p163-9.12 Conf ...

随机推荐

  1. ffmpeg 从mp4上提取H264的nalu

    转自http://blog.csdn.net/gavinr/article/details/7183499 1.获取数据 ffmpeg读取mp4中的H264数据,并不能直接得到NALU,文件中也没有储 ...

  2. iOS应用软件沙盒sandbox相关知识(整理)

    1.iOS沙盒机制原理 iOS应用程序只能在该程序创建的文件系统中读取文件,不可以去其它地方访问,此区域被成为沙盒,所以所有的非代码文件都要保存在此,例如图像,图标,声音,映像,属性列表,文本文件等. ...

  3. 用javascript编写简单银行取钱存钱流程(函数)

    const readline = require('readline-sync')//引用readline-sync let arr = [[], []]; //登陆 let add = functi ...

  4. JAVA揭竿而起总要有名号

    古代揭竿而起总要有个响亮的名号,这可不是随便的哦,比如  苍天已死,黄天当立... 玩JAVA里面形形色色的名字,都是有套路的,至于名字怎么起法,那得问问标识符 标识符 用作给变量.类和方法命名.注意 ...

  5. Oracle常用内置函数

    转换函数 to_char(d|n,fmt):把日期和数字转换为指定格式的字符串: to_number(x,fmt):把一个字符串转换为一个指定格式的数字:   判空函数 nvl(x,value):如果 ...

  6. IPC进程间通信---共享内存

    共享内存 共享内存:共享内存就是分配一块能被其它进程访问的内存.每个共享内存段在内核中维护着一个内部结构shmid_ds, 该结构定义在头文件linux/shm.h中,其结构如下: struct sh ...

  7. getline的字符串读入

    也许是最近模拟题打多了的缘故,我发现自己渐渐变得比较毒瘤起来,当然这也是有一定的好处的,因为从中我也学到了一些处理字符串的正确姿势,今天我们就来讲一 讲如何用函数getline来读入一整行字符串进行处 ...

  8. python开发的学生管理系统

    python开发的学生管理系统(基础版) #定义一个函数,显示可以使用的功能列表给用户 def showInfo(): print("-"*30) print(" 学生管 ...

  9. mysql 主主架构,多入口 互为备份

    ,中小企业很多都是使用mysql主从方案,一主多从,读写分离等,但是单主存在单点故障,从库切换成主库需要作改动.因此,如果是双主或者多主,就会增加mysql入口,增加高可用.不过多主需要考虑自增长ID ...

  10. Hive(4)-Hive的数据类型

    一. 基本数据类型 Hive数据类型 Java数据类型 长度 例子 TINYINT byte 1byte有符号整数 20 SMALINT short 2byte有符号整数 20 INT int 4by ...