Spring Cloud Stream同一通道根據訊息內容分發不同的消費邏輯
應用場景
有的時候,我們對於同一通道中的訊息處理,會通過判斷頭資訊或者訊息內容來做一些差異化處理,比如:可能在訊息頭資訊中帶入訊息版本號,然後通過if判斷來執行不同的處理邏輯,其程式碼結構可能是這樣的:
@StreamListener(value = TestTopic.INPUT)
public void receiveV1(String payload, @Header("version") String version) {
if("1.0".equals(version)) {
// Version 1.0
}
if("2.0".equals(version)) {
// Version 2.0
}
}
那麼當訊息處理邏輯複雜的時候,這段邏輯就會變得特別複雜。針對這個問題,在@StreamListener註解中提供了一個不錯的屬性condition,可以用來優化這樣的處理結構。
動手試試
下面通過編寫一個簡單的例子來具體體會一下這個屬性的用法:
@EnableBinding(TestApplication.TestTopic.class)
@SpringBootApplication
public class TestApplication {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
@RestController
static class TestController {
@Autowired
private TestTopic testTopic;
/**
* 訊息生產介面
*
* @param message
* @return
*/
@GetMapping("/sendMessage")
public String messageWithMQ(@RequestParam String message) {
testTopic.output().send(MessageBuilder.withPayload(message).setHeader("version", "1.0").build());
testTopic.output().send(MessageBuilder.withPayload(message).setHeader("version", "2.0").build());
return "ok";
}
}
/**
* 訊息消費邏輯
*/
@Slf4j
@Component
static class TestListener {
@StreamListener(value = TestTopic.INPUT, condition = "headers['version']=='1.0'")
public void receiveV1(String payload, @Header("version") String version) {
log.info("Received v1 : " + payload + ", " + version);
}
@StreamListener(value = TestTopic.INPUT, condition = "headers['version']=='2.0'")
public void receiveV2(String payload, @Header("version") String version) {
log.info("Received v2 : " + payload + ", " + version);
}
}
interface TestTopic {
String OUTPUT = "example-topic-output";
String INPUT = "example-topic-input";
@Output(OUTPUT)
MessageChannel output();
@Input(INPUT)
SubscribableChannel input();
}
}
內容很簡單,既包含了訊息的生產,也包含了訊息消費。在/sendMessage介面的定義中,傳送了兩條訊息,一條訊息的頭資訊中包含version=1.0,另外一條訊息的頭資訊中包含version=2.0。在訊息監聽類TestListener中,對TestTopic.INPUT通道定義了兩個@StreamListener,這兩個監聽邏輯有不同的condition,這裡的表示式表示會根據訊息頭資訊中的version值來做不同的處理邏輯分發。
在啟動應用之前,還要記得配置一下輸入輸出通道對應的物理目標(exchange或topic名),比如:
spring.cloud.stream.bindings.example-topic-input.destination=test-topic
spring.cloud.stream.bindings.example-topic-input.group=stream-content-route
spring.cloud.stream.bindings.example-topic-output.destination=test-topic
完成了上面配置之後,就可以啟動應用,並嘗試訪問localhost:8080/sendMessage?message=hello介面來傳送一個訊息到MQ中了。此時可以看到類似下面的日誌:
2018-12-24 15:50:33.361 INFO 17683 --- [content-route-1] c.d.stream.TestApplication$TestListener : Received v1 : hello, 1.0
2018-12-24 15:50:33.363 INFO 17683 --- [content-route-1] c.d.stream.TestApplication$TestListener : Received v2 : hello, 2.0
從日誌中可以看到,兩條帶有不同頭資訊的訊息,分別通過不同的監聽處理邏輯輸出了對應的日誌列印。
本文首發:http://blog.didispace.com/spring-cloud-starter-finchley-7-6/
相關文章
- java B2B2C原始碼電子商務平臺 -Spring Cloud Stream同一通道根據訊息內容分發不同的消費邏輯Java原始碼SpringCloud
- Spring Cloud Stream如何消費自己生產的訊息?SpringCloud
- Spring Cloud Stream如何處理訊息重複消費?SpringCloud
- 使用spring.cloud.stream來傳送kafka訊息,並根據某欄位將訊息傳送到固定partition上SpringCloudKafka
- Spring Cloud Stream消費失敗後的處理策略(二):自定義錯誤處理邏輯SpringCloud
- Spring Cloud Stream微服務訊息框架SpringCloud微服務框架
- (十七) 整合spring cloud雲架構 -訊息驅動 Spring Cloud StreamSpringCloud架構
- 最完整的 Spring Cloud 元件-訊息中介軟體 Spring Cloud Stream 使用教程SpringCloud元件
- Spring Cloud 快速入門(八)訊息系統整合框架 Spring Cloud StreamSpringCloud框架
- 訊息驅動式微服務:Spring Cloud Stream & RabbitMQ微服務SpringCloudMQ
- JSP頁面根據後臺傳值不同顯示不同內容JS
- 訊息中介軟體—RocketMQ訊息消費(三)(訊息消費重試)MQ
- kafka消費者消費訊息的流程Kafka
- Storm框架:如何根據業務條件選擇不同的bolt進行下發訊息ORM框架
- Pulsar VS. Kafka(1): 統一的訊息消費模型(Queue + Stream)Kafka模型
- Kafka訊息分發、主題分割槽與消費組的概念Kafka
- popWindow 根據內容計算高度
- 根據編號展開內容
- Spring Cloud 終結篇之訊息驅動--stream 大集合SpringCloud
- Spring Cloud構建微服務架構:訊息驅動的微服務(消費組)【Dalston版】SpringCloud微服務架構
- 使用SpringCloud Stream結合rabbitMQ實現訊息消費失敗重發機制SpringGCCloudMQ
- Spring Cloud Stream消費失敗後的處理策略(一):自動重試SpringCloud
- Spring Cloud Stream消費失敗後的處理策略(四):重新入隊(RabbitMQ)SpringCloudMQ
- 訊息佇列-如何保證訊息的不被重複消費(如何保證訊息消費的冪等性)佇列
- 利用redis的hash結構搭建訊息服務(發訊息,訂閱訊息,消費訊息,退訂)Redis
- 訊息佇列——數十萬級訊息的消費方案佇列
- RocketMQ -- 訊息消費過程MQ
- 分散式訊息佇列:如何保證訊息不被重複消費?(訊息佇列消費的冪等性)分散式佇列
- Spring Cloud Stream消費失敗後的處理策略(三):使用DLQ佇列(RabbitMQ)SpringCloud佇列MQ
- WPF TextBlock根據值顯示不同的內容或格式BloC
- 消費端如何保證訊息佇列MQ的有序消費佇列MQ
- RabbitMQ多消費者順序性消費訊息實現MQ
- Stream流根據屬性去重
- iphone根據文字內容調整label高度的方法。iPhone
- Java多執行緒消費訊息Java執行緒
- Nginx 根據不同的域名來代理轉發內部主機-HTTP和HTTPSNginxHTTP
- JavaScript訪問同一個頁面中的不同iframe的內容!JavaScript
- RocketMQ系列(三)訊息的生產與消費MQ