(Viii) distribution center (Message Bus)

I. Introduction

We  (six) distribution center (Git version and dynamic refresh)  mentioned, if the client needs to get the latest configuration information needed to perform  refresh, we can use every mechanism Webhook code sends a request submitted to refresh the client, when the client end more and more, the need for each client to perform again, this program not for you. Use Spring Cloud Bus can be the perfect solution to this problem.

 

Spring Cloud Bus

Each distribution node via Spring Cloud Bus lightweight message broker. This change in status with the broadcast (e.g., configuration change) command, or other messages. Spring Bus a core idea is to extend the Spring Boot application distributed by the starter, it can also be used to establish a communication channel between multiple applications. The only way to achieve is to use Amqp message broker as a channel, the same set of characteristics (some depending on the channel settings) in the document more channels.

Spring Cloud Bus have been translated into many domestic message bus, but also very image. It can be understood as all distributed project management and dissemination of information can, in fact, the essence is to use a broadcast mechanism MQ spread messages in a distributed system, currently used have Kafka and RabbitMQ. The use of Bus mechanism can do a lot of things, where the configuration center client refresh one is a typical application scenarios, we Bus mechanisms used in the configuration center by a diagram to describe.

 

 

 

Second, combat

You need to download and install rabbit.

We chose the article  (vii) distribution center (of service and high availability)  sample code version to transform, MQ do we use RabbitMQ example.

 

Server

Add in pom.xml, the four is a must

<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 follows

spring:
  application:
    name: config-server
  cloud:
    config:
      server:
        git:
          uri: https://github.com/liazhan/test-cloud # 配置git仓库的地址
          search-paths: config-repo # git仓库地址下的相对地址,可以配置多个,用,分割。
    bus:
      enabled: true
      trace:
        enabled: true
  rabbitmq:
      host: localhost
      port: 5672
      username: guest
      password: guest
server:
  port: 12000
eureka:
  client:
    service-url:
      defaultZone: http://localhost:7000/eureka/
management:
  endpoints:
    web:
      exposure:
        include: bus-refresh

 

 

Start class plus  @EnableConfigServer notes

package com.example.configservergit;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;

@EnableConfigServer
@SpringBootApplication
public class ConfigServerGitApplication {

    public static void main(String[] args) {
        SpringApplication.run(ConfigServerGitApplication.class, args);
    }

}

 

 

Client

Add the following in the pom.xml dependency, the first five is a must, the last webflux you can use to replace the web

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

Here it is easy to miss  spring-boot-starter-actuator, if the lack of this, when executed on the server  /actuator/bus-refresh when the client can not receive information, Console will display the following information in (I'm trapped in here for a long time ......)

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://[email protected]: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 follows

spring:
  application:
    name: config-git
  cloud:
    bus:
      trace:
        enabled: true
      enabled: true
server:
  port: 13000

 

bootstrap.yml follows

spring:
  cloud:
    config:
      name: config-client # 对应 {application} 部分
      profile: dev # 对应 {profile} 部分
      label: master # 对应 {label} 部分,即 Git 的分支。如果配置中心使用的是本地存储,则该参数无用
      discovery:
        enabled: true
        service-id: config-server
  rabbitmq:
    host: localhost
    port: 5672
    username: guest
    password: guest
eureka:
  client:
    service-url:
      defaultZone: http://localhost:7000/eureka/





 

controller as follows

package com.example.configclient.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;

@RestController
@RefreshScope
public class HelloController {

    @Value("${neo.hello:error}")
    private String profile;

    @GetMapping("/info")
    public Mono<String> hello(){
        return Mono.justOrEmpty(profile);
    }
}

 

@RefreshScope Must be added, otherwise the client will receive an update message server, but can not be updated, because they do not know where the update.

As to start the main class, do not change the default generated, not posted.

 

 

Third, the test

We do not profile with rabbit-related configuration, springboot default configuration of the local rabbit.

Each start eureka, config-server and two config-client (13000,13001).

After starting, RabbitMQ will automatically create a topic and two types of Exchange at  springCloudBus.anonymous. the beginning of the anonymous Queue

We open HTTP: // localhost: 15672 , can be seen in the following figure

We visit  http: // localhost: 13000 / info  and  http: // localhost: 13001 info /  returns the contents are  dev.

Git configuration information in the  dev read  dev busand executed

POST http://localhost:12000/actuator/bus-refresh/

If the reported 405 errors, you can be exposed to the configuration file configuration change it, do not know why. . . . To "*" on it

management:
  endpoints:
    web:
      exposure:
        include: "*"


 

Another visit  http: // localhost: 13000 / info  and  http: // localhost: 13001 / info  after then returns the content is modified  dev bus , indicating a success.

 

It is worth mentioning that, as long as the open Spring Cloud Bus, or whether it is config-server config-client performs  /actuator/bus-refresh all updates can all be configured.

 

 

Fourth, the partial refresh

Under certain scenarios (eg gray-release), we may want to refresh the configuration section micro services, this time through  /actuator/bus-refresh/{destination} to locate the application you want to refresh the destination endpoint parameters.

For example: /actuator/bus-refresh/customers:8000such micro service instance on the message bus will be based on the value of the parameter to determine whether the destination need to be refreshed. Wherein, customers:8000 referring to each micro ApplicationContext ID services.

destination parameters may also be used to locate specific widget service. For example: /actuator/bus-refresh/customers:**so that you can trigger micro-services customers all instances of configuration refresh.

 

 

Fifth, the tracking bus event

Under some scenarios, we may want to know the details of Spring Cloud Bus event propagation. At this point, we can track bus event (RemoteApplicationEvent subclasses are bus event).

Trace Bus event is very simple, just set  spring.cloud.bus.trace.enabled=true, so that  /actuator/bus-refresh the endpoint is requested, access to  /actuator/httptracethe endpoint should obtain results similar to the following:

{
  "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": "*:**"
  }
}

The log shows  spring-cloud-config-client:8001 issued RefreshRemoteApplicationEvent event, broadcast to all the services, was  customers:8001 and  stores:8002 received a. Want message received customize your approach, you can add  @EventListener annotations AckRemoteApplicationEvent and SentApplicationEvent type into your own applications. TraceRepository class or to directly process the data.

In this way, we can clearly know the details of the incident spread.

 

but. . .

In my tests, it was found that the following results:

There is no information. . .

 

Learn from https://windmt.com/2018/04/19/spring-cloud-9-config-eureka-bus/

Published 111 original articles · won praise 1 · views 5441

Guess you like

Origin blog.csdn.net/daziyuanazhen/article/details/104994384