SpringCloud-Bus匯流排的其他應用場景(釋出-訂閱)
釋出-訂閱模型
Bus的事件推送由三個角色構成:
- 事件物件:Bus中定義的一個事件類,通常是一個Pojo物件,包含了消費者需要的資訊
- 事件釋出:Bus作為生產者,將事件物件通過廣播的形式釋出出去
- 事件監聽:由消費者主動監聽Bus的事件釋出動作,當獲取到事件物件後會呼叫處理方法進行消費
自定義事件
自定義事件物件
Bus的所有事件物件都繼承自ApplicationEvent或者RemoteApplicationEvent,我們可以仿照bus-refresh功能定義的事件類RefreshRemoteApplicationEvent中的寫法,定義一個MyEvent類
public class MyEvent extends RemoteApplicationEvent {
public MyEvent() {
}
public MyEvent(Object body, String originService, String destinationService) {
super(body, originService, destinationService);
}
}
其中第一個引數可以自定義一個POJO類,大家可以根據自己的需求隨意新增屬性,但是要保證這個類實現了序列化/反序列化介面(implements Serializable)。
配置自定義物件
在建立了MyEvent之後,我們需要將它載入到Bus的上下文中,這裡可以通過@Configuration和@RemoteApplicationEventScan註解將MyEvent載入進來
@Configuration
@RemoteApplicationEventScan(basePackageClasses = MyEvent.class)
public class BusExtConfiguration {
}
監聽事件
我們要在服務節點新增事件監聽器,用來監聽服務釋出動作,這一步可以通過@EventListener方法級別的註解來實現(可以參考RefreshEventListener類),接收的引數就是第一步中建立的EventBody,Bus會幫我們將訊息反序列化為Java類。也可以通過繼承ApplicationListener介面來實現,示例如下:
@Component
public class MyEventListener implements ApplicationListener<MyEvent> {
@Override
public void onApplicationEvent(MyEvent event) {
logger.info("Received MyCustomRemoteEvent - message: ");
}
}
釋出事件
萬事俱備之後,我們只需要一個釋出事件的地方了(在訊息生產者處實現),我們可以建立一個簡單的Controller,然後對外提供一個POST方法,比如:
@PostMapping("/bus/publish/myevent")
public boolean publishMyEvent(@RequestBody EventBody body) {
MyEvent event = new MyEvent(body, applicationContext.getId(), "");
try {
// 可以注入ApplicationEventPublisher來發送event
eventPublisher.publishEvent(event);
// 也可以直接使用
// applicationContext.publishEvent(event)
return true;
} catch (Exception e) {
log.error("failed in publishing event", e);
}
return false;
}
我們有兩種方式傳送event,一種是通過依賴注入ApplicationEventPublisher的例項來發送,現有的bus-refresh功能也是使用這種方式。另一種是直接通過ApplicationContext來發送,由於前面我們通過@RemoteApplicationEventScan註解已經將MyEvent註冊為Bus的一個事件,這樣ApplicationContext會把MyEvent當做一個Bus匯流排事件,而不是在Context範圍內釋出一個Regular Event。
應用場景
通過上面的方式我們可以將自定義事件廣播到所有監聽該事件的節點,讓所有消費者觸發事件響應。訊息廣播的使用場景非常多,我們隨便舉兩個實際應用中的例子:
- 清空快取:通知所有服務監聽者清空某項業務的本地快取資訊,我們也可以在自定義的訊息體中加業務屬性,事件監聽邏輯可以根據這些屬性來定點清除某個特定業務物件的快取
- 資料同步:子系統依賴實時的資料庫記錄變動觸發相應的業務邏輯,我們這裡就可以將資料庫的binlog抓取出來,通過廣播功能同步到所有監聽器,起到資料同步的作用
小結
這一節我們學習了Bus中自定義事件的實現方式,到這裡Bus章節就算告一段落了,下一章我們將去學習微服務架構中的一個重要模組-閘道器層Gateway。
學習Tips:有的時候看圖文教程和視訊會感覺知識很好理解,但是一上手寫程式就要各種求助百度。沒有下手練習的話,所有學習都是紙上談兵,尤其對於實戰技術來說。只要搞懂不要動手的只有一個場景,那就是面試前的知識突擊。所以大家一定要多動手,把每個小Demo都自己去實現一遍,我們的課程專案也給大家留了很大的操作空間,同學們可以把每一章學到的內容應用在更多的模組中。