SpringCloudBus介紹
SpringCloudBus:消息總線,可以將分佈式系統的節點與輕量級消息代理連接,然後實現廣播狀態更改(如配置更改)或廣播其他管理指令。總線就像一個分佈式執行器,用於擴展SpringBoot應用程序,但可以用作應用程序之間的通信通道。
消息代理是一種消息驗證、傳輸、路由的架構模式。它是一箇中間產品,核心是一個消息的路由程序,用來實現接收和分發消息,並根據設定好的消息處理流來轉發給正確的應用。通常一下場景需要使用消息代理
- 將消息路由到一個或多個目的地
- 消息轉化爲其他的表達方式
- 執行消息的聚集、消息的分解,並將結果發送到它們的目的地,然後重新組合響應返回給信息用戶
- 調用Web服務來檢索數據
- 響應事件或錯誤
- 使用發佈-訂閱模式提供內容或基於主題的消息內容。
RabbitMQ實現消息總線
RibbitMQ是實現了高級消息隊列協議(AMQP)的開源消息代理軟件,也稱爲面向消息的中間件。這裏假設你已經瞭解RabbitMQ,具體的安裝就不介紹了,可自行Google。
SpringBoot整合RabbitMQ
新建一個SpringBoot項目,這裏命名hello-rabbitmq,然後添加amqp
依賴。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</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-test</artifactId>
<scope>test</scope>
</dependency>
在配置文件application.properties
中添加RabbitMQ
的相關配置
spring.application.name=rabbitmq-hello
#配置rabbitmq的主機
spring.rabbitmq.host=192.168.18.133
#訪問端口
spring.rabbitmq.port=5672
#安裝RabbitMQ時配置的用戶名
spring.rabbitmq.username=wqh
#安裝RabbitMQ時配置的密碼
spring.rabbitmq.password=wqh
然後創建消息生產者Sender,這裏發送一串字符串到hello的消息對列中
/*
*消息生產者Sender使用AmqpTemplate接口的實例來實現消息的發送
*/
@Component
public class Sender {
private final Logger logger = LoggerFactory.getLogger(Sender.class);
@Autowired
private AmqpTemplate amqpTemplate;
public void sender(){
String context = "wqh say hello " + new Date();
logger.info("發送消息=========》》》》{}",context);
this.amqpTemplate.convertAndSend("hello",context);
}
}
消息接收者Receiver,實現了對hello消息隊列的消費
/**
* 消息消費者Receiver 使用@RabbitListener註解定義該類對hello隊列的監聽, 並用@RabbitHandler 註解來指定對消息的處理方法
*
*/
@Component
@RabbitListener(queues = "hello")
public class Receiver {
private final Logger logger = LoggerFactory.getLogger(Receiver.class);
@RabbitHandler
public void receiver(String hello){
logger.info("接收消息=====》》》》》{}",hello);
}
}
創建RabbitMQ的配置類
/**
* RabbitMQ的配置類,用來配隊列、交換器、路由等高級信息
*/
public class RabbitConfig {
@Bean
public Queue helloConfig(){
return new Queue("hello");
}
}
創建測試類
@RunWith(SpringRunner.class)
@SpringBootTest
public class RabbitmqApplicationTests {
@Autowired
private Sender sender;
@Test
public void hello(){
sender.sender();
}
}
上面說到一個hello隊列,所以這裏需要在RabbitMQ中添加一個hello隊列,進入RabbitMQ的管理頁面。
啓動項目,運行測試方法:
SpringCloudBus整合RabbitMQ
前面使用SpringCloudConfig構建了一個配置中心,傳送門 。前面的結構中如果遠程倉庫配置發生改變,我們需要調用每個服務的/refresh
接口或者重啓服務才能獲取到最新的配置信息,這種方法在微服務架構中幾乎是完全不可行的。使用SpringCloudBus和RabbitMQ整合可以優雅的實現應用配置的動態刷新。直接改造之前的config-client項目
- 添加
spring-cloud-starter-bus-amqp
依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
- 在配置文件中添加RabbitMQ的相關配置,這裏需要注意的要忽略權限,不然訪問
/bus/refresh
接口的時候回返回Full authentication is required to access this resource
。
#忽略權限攔截
management.security.enabled=false
spring.rabbitmq.host=192.168.18.133
spring.rabbitmq.port=5672
spring.rabbitmq.username=wqh
spring.rabbitmq.password=wqh
- 將配置文件複製一份,修改端口,然後打包。分別啓動eureka-server服務發現、config-server配置中心、兩個config-client實例。項目結構
- 啓動項目之後訪問
http://localhost:60000/get_name
和http://localhost:60001/get_name
獲取到form屬性。然後修改倉庫中的中屬性的值,會發現獲取的到值並沒有改變 - 然後發出一個post請求到一個config-client,訪問接口
/bus/refresh
,發現這時候兩個服務中都可以獲取打最新的值
在/bus/refresh
接口中有一個參數destination,該參數可以指定具體的實例刷新配置,還可指定具體的服務刷新配置。
指定實例,只會觸發端口號爲60000的
/bus/refresh?destination=config-client:60000
指定服務,這裏會觸發config-client服務的所有實例進行刷新
/bus/refresh?destination=config-client:**
在《SpringCloud微服務實戰》中提到了一個系統架構的優化,就是將消息總線加入到配置中心,然後通過destination參數來指定更新配置的服務或實例。
參考:《SpringCloud微服務實戰》
示例地址:https://gitee.com/wqh3520/
原文地址: SpingCloudBus整合RabbitMQ