一、實現原理
1、ConfigServer(配置中心服務端)從遠端git拉取配置文件並在本地git一份,ConfigClient(微服務)從ConfigServer端獲取自己對應 配置文件;
2、當遠端git倉庫配置文件發生改變,ConfigServer如何通知到ConfigClient端,即ConfigClient如何感知到配置發生更新?
Spring Cloud Bus會向外提供一個http接口,即圖中的/bus/refresh。我們將這個接口配置到遠程的git的webhook上,當git上的文件內容發生變動時,就會自動調用/bus-refresh接口。Bus就會通知config-server,config-server會發布更新消息到消息總線的消息隊列中,其他服務訂閱到該消息就會信息刷新,從而實現整個微服務進行自動刷新。
二:實現方式
實現方式一:某個微服務承擔配置刷新的職責

1、提交配置觸發post調用客戶端A的bus/refresh接口
2、客戶端A接收到請求從Server端更新配置並且發送給Spring Cloud Bus總線
3、Spring Cloud bus接到消息並通知給其它連接在總線上的客戶端,所有總線上的客戶端均能收到消息
4、其它客戶端接收到通知,請求Server端獲取最新配置
5、全部客戶端均獲取到最新的配置
存在問題:
1、打破了微服務的職責單一性。微服務本身是業務模塊,它本不應該承擔配置刷新的職責。2、破壞了微服務各節點的對等性。3、有一定的局限性。WebHook的配置隨着承擔刷新配置的微服務節點發生改變。
改進如下方式二:配置中心Server端承擔起配置刷新的職責,原理圖如下:

1、提交配置觸發post請求給server端的bus/refresh接口
2、server端接收到請求並發送給Spring Cloud Bus總線
3、Spring Cloud bus接到消息並通知給其它連接到總線的客戶端
4、其它客戶端接收到通知,請求Server端獲取最新配置
5、全部客戶端均獲取到最新的配置

第一種配置:
啟動rabbitmq
rabbitmq: docker run -d -p 5672:5672 -p 15672:15672 rabbitmq:management
-
product-service
-
pom.xml
<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> -
bootstrap.yml
spring: rabbitmq: host: 192.168.180.112 port: 5672 username: guest password: guest #暴露全部的監控信息 management: endpoints: web: exposure: include: "*"
-
web層
@RestController @RequestScope @RequestMapping("/api/v1/product") public class ProductController { @Value("${server.port}") private String port; @Autowired private ProductService productService; /** * 獲取所有商品列表 * @return */ @RequestMapping("list") public Object list(){ return productService.listProduct(); } /** * 根據id查找商品詳情 * @param id * @return */ @RequestMapping("find") public Object findById(int id){ // try { // TimeUnit.SECONDS.sleep(2); // } catch (InterruptedException e) { // e.printStackTrace(); // } Product product = productService.findById(id); Product result = new Product(); BeanUtils.copyProperties(product,result); result.setName( result.getName() + " data from port="+port ); return result; } }
-
測試,要手動發送POST http://localhost:8773/actuator/bus-refresh
就會發現控制台會重新加載配置信息
-

第二種配置:
其實也是把config-server連到Bus和mq中,然后去請求它,其他服務才進行重新加載。
-
config-server
-
pom.xml
1 <dependency> 2 <groupId>org.springframework.boot</groupId> 3 <artifactId>spring-boot-starter-actuator</artifactId> 4 </dependency> 5 6 <dependency> 7 <groupId>org.springframework.cloud</groupId> 8 <artifactId>spring-cloud-starter-bus-amqp</artifactId> 9 </dependency> 10 <dependency> 11 <groupId>org.springframework.cloud</groupId> 12 <artifactId>spring-cloud-config-server</artifactId> 13 </dependency>
-
application.yml
#服務名稱 spring: application: name: config-server cloud: config: server: git: uri: http://192.168.180.112/root/test.git username: root password: *********** default-label: master rabbitmq: host: 192.168.180.112 username: guest password: guest port: 5672 management: endpoints: web: exposure: include: "*" #服務的端口號 server: port: 9100 #指定注冊中心地址 eureka: client: serviceUrl: defaultZone: http://localhost:8761/eureka/
-
-
發送請求:http://192.168.137.1:9100/actuator/bus-refresh,會發現所有的服務都會拉取信息。

