Spring Cloud Stream事件路由 - spring.io
Spring Cloud Stream(SCSt)的事件路由有以下功能:a)將事件路由到特定事件訂閱者,或b)將事件訂閱者產生的事件路由到特定目的地。
讓我們快速看一下基於註釋的程式設計模型中的工作方式。在本文中,我們將其稱為路由“ TO”和路由“ FROM”。
為了路由到事件訂閱者,我們使用condition了StreamListener註釋的屬性,如下所示:
@StreamListener(target = Sink.INPUT, condition = "headers['type']=='order'") public void receiveOrders(Order order) {...} |
這是有關此方法的更多詳細資訊。
而且,為了從事件訂閱者進行路由,我們使用了動態繫結目標 -這種方法允許框架根據單個事件中提供的某些指令將框架繫結到目標。
具有函式的事件路由
使用函式性方法,我們可以透過一些附加函式以更簡潔明瞭的方式完成上述所有操作。
路由“ TO”
可以透過依賴Spring Cloud Function(SCF)中可用的路由功能來實現路由“ TO”功能。您可以透過設定spring.cloud.stream.function.routing.enabled屬性來顯式啟用路由,也可以透過設定spring.cloud.function.routing-expression屬性並使用Spring Expression Language(SpEL)提供路由指令來隱式啟用路由。路由指令應導致路由到“ TO”的功能的定義。
對於路由目的,路由目的地的名稱是functionRouter-in-0(見RoutingFunction.FUNCTION_NAME和描述的繫結命名約定在這裡)。
當一個訊息被髮送到該目的地,路由功能嘗試確定哪些實際功能需要來處理這樣的事件。它首先試圖訪問spring.cloud.function.routing-expression訊息報頭,並且如果提供,確定實際的函式呼叫的名稱。這是最動態的方法。第二種最動態的方法是提供spring.cloud.function.definition標頭,其中應包含將“ TO”路由到的函式的定義。兩種方法都需要透過設定spring.cloud.stream.function.routing.enabled屬性來明確啟用路由功能。
至於以前版本中沒有的其他功能,spring.cloud.function.routing-expression也可以用作應用程式屬性。例如,請考慮無論傳入事件如何,表示式都相同的情況,如本文前面顯示的基於註釋的示例(例如,spring.cloud.function.routing-expression=headers['type']=='order')。對於這種方法,您無需顯式啟用路由功能,因為spring.cloud.function.routing-expression作為應用程式屬性具有相同的效果。
儘管很簡單,但以下是上述方法之一的完整示例:
@SpringBootApplication public class RoutingStreamApplication { public static void main(String[] args) { SpringApplication.run(RoutingStreamApplication.class, "--spring.cloud.function.routing-expression=" + "T(java.lang.System).nanoTime() % 2 == 0 ? 'even' : 'odd'"); } @Bean public Consumer<Integer> even() { return value -> System.out.println("EVEN: " + value); } @Bean public Consumer<Integer> odd() { return value -> System.out.println("ODD: " + value); } } |
透過傳送訊息到functionRouter-in-0,這是由rabbit或kafka繫結暴露的,基於訊息系統時間的nanoTime()方法返回值,訊息將被路由到Consumer相應的'even'或'odd'
路由“ FROM”
和以前一樣,路由“ FROM”依賴於SCSt的“動態繫結目標”功能。但是,與路由“ TO”一樣,還有許多其他功能。
以下示例顯示了基礎知識:
@Autowired private BinderAwareChannelResolver resolver; public Consumer<String> send(Message message) { MessageChannel destination = resolver .resolveDestination(message.getHeaders().get("type")) Message outgoingMessage = . . . // your code destination.send(outgoingMessage); } |
您所需要的只是BinderAwareChannelResolver的引用(在後面的示例中自動注入)。然後,您可以使用一些邏輯來確定目標名稱(在本例中,我們使用“型別”標頭的值)。確定目的地名稱後,您可以透過使用該BinderAwareChannelResolver.resolveDestination(..)操作並向其傳送訊息來獲取對其的引用。這就是全部。
上述方法的缺點是某些特定於框架的抽象會洩漏到您的程式碼中。看一下您需要了解BinderAwareChannelResolver和的MessageChannel事實。實際上,前面示例中的大多數程式碼都是樣板程式碼。
一種更動態,更少洩漏的方法是依靠spring.cloud.stream.sendto.destination屬性,這有效地完成了上述所有操作-但在幕後。下面的示例演示如何使用此方法:
@SpringBootApplication public class RoutingStreamApplication { @Bean public Function<Message<String>, Message<String>> process() { return message -> { // some logic to process incoming message Message<String> outgoingMessage = MessageBuilder .withPayload("Hello") .setHeader("spring.cloud.stream.sendto.destination", "even") .build(); return outgoingMessage; }; } } |
我們不再需要注入BinderAwareChannelResolver執行解析MessageChannel。我們只需建立一個新Message,指定一個頭部header:框架使用這個標頭即可動態解析目標。
路由源
最後但並非最不重要的一點,讓我們看一下路由“ FROM”的另一個流行用例,其中資料來源起源於SCSt的上下文之外,但需要路由到適當的目的地:
@Controller public class SourceWithDynamicDestination { @Autowired private ObjectMapper jsonMapper; private final EmitterProcessor<?> processor = EmitterProcessor.create(); @RequestMapping(path = "/", method = POST, consumes = "*/*") @ResponseStatus(HttpStatus.ACCEPTED) public void handleRequest(@RequestBody String body, @RequestHeader(HttpHeaders.CONTENT_TYPE) Object contentType) throws Exception { Map<String, String> payload = jsonMapper.readValue(body, Map.class); String destination = payload.get("id"); Message<?> message = MessageBuilder.withPayload(payload) .setHeader("spring.cloud.stream.sendto.destination", destination) .build(); processor.onNext(message); } @Bean public Supplier<Flux<?>> source() { return () -> processor; } } |
然後,我們可以透過執行以下curl命令來檢視結果:
curl -H "Content-Type: application/json" -X POST -d '{"id":"customerId-1","bill-pay":"100"}' http://localhost:8080 |
在這裡,我們藉助Supplier<Flux<?>>bean 既使用函式性方法又使用反應式範例的混合。我們有一個簡單的MVC控制器,我們希望根據內容的'id'屬性值將請求路由到下游。儘管EmitterProcessor此處的詳細資訊及其用法是另一篇文章的主題,但重要的是它演示了一個功能齊全的應用程式,其中HTTP請求被動態路由到目標繫結程式管理的目的地。
在GitHub上檢視Spring Cloud Stream。
相關文章
- Spring Cloud Gateway入門 - spring.ioSpringCloudGateway
- Spring Cloud Stream的函式式和響應式Reactive程式設計特點 - spring.ioSpringCloud函式React程式設計
- springCloud學習5(Spring-Cloud-Stream事件驅動)SpringGCCloud事件
- RocketMQ 整合 Spring Cloud StreamMQSpringCloud
- 使用Spring Cloud Stream和RabbitMQ實現事件驅動的微服務SpringCloudMQ事件微服務
- 使用Spring Cloud Stream和Spring State Machine建立事件驅動的微服務案例SpringCloudMac事件微服務
- Spring Cloud Stream與Spring Integration整合以及Spring Cloud Function的關係:開啟從基於註釋到函數語言程式設計的漫長轉換 - spring.ioSpringCloudFunction函數程式設計
- Spring Cloud Stream微服務訊息框架SpringCloud微服務框架
- Spring Cloud Stream如何深度支援Apache Kafka?SpringCloudApacheKafka
- (十七) 整合spring cloud雲架構 -訊息驅動 Spring Cloud StreamSpringCloud架構
- Spring Cloud 快速入門(八)訊息系統整合框架 Spring Cloud StreamSpringCloud框架
- Spring Cloud Stream 體系及原理介紹SpringCloud
- spring-cloud-gateway靜態路由SpringCloudGateway路由
- 最完整的 Spring Cloud 元件-訊息中介軟體 Spring Cloud Stream 使用教程SpringCloud元件
- 介紹一下Spring Cloud Stream主要概念SpringCloud
- Spring cloud(5)-路由閘道器(Zuul)SpringCloud路由Zuul
- Spring Cloud Gateway 整合Eureka路由轉發SpringCloudGateway路由
- 訊息驅動式微服務:Spring Cloud Stream & RabbitMQ微服務SpringCloudMQ
- Spring Cloud Stream如何消費自己生產的訊息?SpringCloud
- Spring Cloud Stream如何處理訊息重複消費?SpringCloud
- Spring Cloud 之 Config與動態路由.SpringCloud路由
- spring cloud gateway 原始碼解析(2)動態路由SpringCloudGateway原始碼路由
- Spring Cloud Gateway實戰之三:動態路由SpringCloudGateway路由
- 重要版本Spring Boot 2.3.0釋出 - spring.ioSpring Boot
- Spring Data Moore有哪些新功能? - spring.ioSpring
- RSocket入門:Spring Boot伺服器 -Spring.ioSpring Boot伺服器
- Spring Cloud Gateway 路由轉發之After(Before)路由斷言工廠使用SpringCloudGateway路由
- Spring Cloud 終結篇之訊息驅動--stream 大集合SpringCloud
- Spring Cloud Stream應用與自定義RocketMQ Binder:程式設計模型SpringCloudMQ程式設計模型
- Spring Cloud Gateway實戰之二:更多路由配置方式SpringCloudGateway路由
- 【Azure 事件中心】azure-spring-cloud-stream-binder-eventhubs客戶端元件問題, 實踐訊息非順序可達事件SpringCloud客戶端元件
- 在Spring Data MongoDB中實現關係建模 - spring.ioSpringMongoDB
- WPF路由事件路由事件
- Spring Cloud Zuul API服務閘道器之請求路由SpringCloudZuulAPI路由
- Spring Cloud 學習筆記 ——Sleath、Zipkin、RabbitMQ、ElasticSearch、Stream 搭建鏈路專案SpringCloud筆記MQElasticsearch
- Spring Cloud Stream應用與自定義RocketMQ Binder:實現RocketMQ繫結器SpringCloudMQ
- Spring Cloud(二):Spring Cloud ConfigSpringCloud
- Spring Cloud Stream消費失敗後的處理策略(一):自動重試SpringCloud