Bus 簡介
Spring Cloud Bus 是 Spring Cloud 體系內的消息總線,支持 RabbitMQ 和 Kafka 兩種消息中間件。所謂消息總線,簡單理解就是一個消息中心,衆多微服務實例都可以連接到總線上,實例可以往消息中心發送或接收信息,例如:實例 A 發送一條消息到總線上,總線上的實例 B 可以接收到信息(實例 B 訂閱了實例 A),消息總線充當一箇中間者的角色,使得實例 A 和實例 B 解耦
Spring Cloud Bus 實戰
Spring Cloud Bus 可以將 Spring 事件機制和 Stream 結合在一起,具體機制如下:
- 在需要發佈或者監聽事件的應用中增加
@RemoteApplicationEventScan
註解,通過該註解
可以啓動 Stream 中消息通道的綁定 - 對於事件發佈,需要承
ApplicationEvent
的擴展類RemoteApplicationEvent
,通過ApplicationContext.publishEvent()
發佈事件時,Spring Cloud Bus 會對所要發佈的事件進行包裝,形成消息,通過默認的 Spring Cloud Bus 消息通道發送到消息中間件 - 對於事件監聽者,則不需要進行任何變更,仍舊按照 Spring 的方式實現消息的監聽i
安裝並啓動 ZooKeeper 和 Kafka,創建事件發佈者項目,引入依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-kafka</artifactId>
</dependency>
定義用戶事件類 UserEvent,實現 RemoteApplicationEvent
@Data
@Slf4j
@EqualsAndHashCode(callSuper = true)
public class UserEvent extends RemoteApplicationEvent {
public UserEvent(Object source, String originService, String destination) {
super(source, originService, destination);
}
}
- originService:對於事件發佈者來說 originService 就是自己
- destinationService:將事件發佈到哪些微服務實例,配置的格式爲
{serviceld):{appContextId)
,在配置時 serviceld 和 appContextld 可以使用通配符,比如userservice:**
會將事件發佈給 userservice 微服務
發佈消息代碼如下
@Slf4j
@RestController
public class TestCon {
@Autowired
private ApplicationContextHolder holder;
@GetMapping("/test/userEvent")
public void userAdd() {
User user = new User();
user.setId("2");
user.setName("tom");
user.setAge(50);
ApplicationContext ctx = ApplicationContextHolder.getApplicationContext();
UserEvent event = new UserEvent(user, ctx.getId(), "*:**");
ctx.publishEvent(event);
}
}
在配置文件中添加如下配置:
spring:
cloud:
stream:
default-binder: kafka
kafka:
binder:
brokers: localhost:9092
在啓動類添加 @RemoteApplicationEventScan
註解
@SpringBootApplication
@RemoteApplicationEventScan
public class Server01Application {
public static void main(String[] args) {
SpringApplication.run(Server01Application.class, args);
}
}
創建事件接收者項目,引入和事件發佈者同樣的依賴,將 UserEvent 類複製到該模塊下,實現事件監聽類UserEventListener
@Slf4j
@Component
public class UserEventListener implements ApplicationListener<UserEvent> {
@Override
public void onApplicationEvent(UserEvent event) {
log.info("收到用戶事件: {}", event);
}
}
加上事件發佈者同樣的配置和啓動類註解
啓動兩個項目,請求事件發佈者的 /test/userEvent
接口,即可發佈和接收事件