上一章節,我們講解了分布式配置中心spring cloud config,我們把配置項存放在git或者本地,當我們修改配置時,需要重新啟動服務才能生效。但是在生產上,一個服務部署了多台機器,重新啟動比較麻煩且會短暫影響用戶體驗。spring cloud生態在發展,肯定有對應的解決之法,接下來將要講解的Spring Cloud Bus就是為了解決這一難題而存在的。
Spring Cloud Bus(消息總線)通過一個輕量級的消息中間件可以連接分布式系統中的各個節點。使用該總線來廣播某些狀態的改變(比如配置信息發生變更)或其他管理指令。可以說,消息總線是spring boot應用擴展“道路”上的推進器,而且也把它用來作應用間相互通信的消息管道。
一、項目搭建:
1. 環境准備
本章還是基於上一章來實現的,上一章講解了git和本地配置兩種方式,配置刷新原理都是一樣的,這次我們只講git配置修改后進行刷新。
上一章節內容可以參考:一起來學Spring Cloud | 第七章:分布式配置中心(Spring Cloud Config)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.haly</groupId>
<artifactId>springcloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>com.haly</groupId>
<artifactId>springcloud-feign-client</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springcloud-ribbon-client</name>
<description>新建一個springcloud項目</description>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>com.haly</groupId>
<artifactId>springcloud-config</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
3. 在springcloud-feign-client模塊的application.properties中加上RabbitMq的配置,包括RabbitMq的地址、端口,用戶名、密碼。並加上spring.cloud.bus的三個配置:
spring.rabbitmq.host=localhost spring.rabbitmq.port=5672 spring.rabbitmq.username=young spring.rabbitmq.password=young spring.cloud.bus.enabled=true spring.cloud.bus.trace.enabled=true management.endpoints.web.exposure.include=bus-refresh
4. springcloud-feign-client模塊的啟動類上加上注解:@RefreshScope
package com.haly;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableFeignClients
@EnableDiscoveryClient
@RefreshScope
public class SpringcloudFeignClientApplication {
public static void main(String[] args) {
SpringApplication.run(SpringcloudFeignClientApplication.class, args);
}
}
5. springcloud-feign-client模塊的測試類FeignController,測試上一章節的/testconfig方法,具體內容可以參考:一起來學Spring Cloud | 第七章:分布式配置中心(Spring Cloud Config)
package com.haly.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.haly.romote.FeignRemoteService;
@RestController
public class FeignController {
@Autowired
FeignRemoteService feignRemoteService;
@Value("${configword}")
String configword;
@GetMapping(value = "/getHello")
public String getHello(@RequestParam String name) {
return feignRemoteService.hello(name);
}
@GetMapping(value = "/testzuul")
public String testzuul(@RequestParam String name) {
return name +",這是springcloud-feign-client的服務接口";
}
@GetMapping(value = "/testconfig")
public String testconfig(@RequestParam String name) {
return name +",git配置值:" + configword ;
}
}
6. 運行項目
啟動springcloud-eureka-server,啟動springcloud-config-server,啟動springcloud-config,最后啟動springcloud-feign-client模塊
為了測試配置修改,多個服務實例都能更新,就啟動兩個 springcloud-feign-client 實例,端口分別是9600,9601,sts啟動兩個實例(端口為9600時啟動項目,然后將端口改成9601,再啟動項目)。
瀏覽器輸入:http://localhost:9600/testconfig?name=young碼農 或者輸入 http://localhost:9601/testconfig?name=young碼農
頁面展示結果:young碼農,git配置值:NewConfig !
7. 修改git配置,重新運行項目
這時我們去代碼倉庫將configword的值改為“update config”,即改變配置文件configword的值。如果是傳統的做法,需要重啟服務,才能達到配置文件的更新。
現在,我們只需要發送post請求:http://localhost:8881/actuator/bus-refresh,你會發現springcloud-feign-client會重新讀取配置文件,接着我們查看頁面運行結果。
瀏覽器輸入:http://localhost:9600/testconfig?name=young碼農 或者輸入 http://localhost:9601/testconfig?name=young碼農
頁面展示結果:young碼農,git配置值:update config !
二、總結:
使用"destination"參數,/actuator/bus-refresh接口可以指定服務,例如 “/actuator/bus-refresh?destination=client:**”, 即刷新服務名為client的所有服務。
通過上面的測試,我們可以知道當git文件更改的時候,用post 向端口為8882的config-client發送請求/bus/refresh/;此時8882端口會發送一個消息,由消息總線向其他服務傳遞,從而使整個微服務集群都達到更新配置文件。
引入程序猿DD 畫的一張圖片,簡單理解一下刷新原理:

最后項目目錄結構:

