基於Spring Integration和Apache Camel的SEDA
SEDA,或階段化事件驅動架構,是Matt Welsh在他的博士論文中提出的一種架構風格。論文。它的主要優點是可伸縮性、支援高併發流量和可維護性。
由於可伸縮性是SEDA的核心目標,因此通常最好設計專注於特定操作的小階段,特別是當我們有I/O密集型任務時。而且,擁有小的階段有助於我們更好地調整每個階段的規模。
我們的示例問題將是簡單明瞭的:計算每個單詞在給定字串中不區分大小寫出現的次數。
讓我們把一個單詞定義為一系列沒有空格的字元,我們將忽略標點符號等其他複雜因素。我們的輸出將是一個對映,其中包含作為鍵的單詞和作為值的計數。
為了解決字數統計問題,我們可以透過以下幾個階段來實現解決方案:
- 接受文字
- 分割詞語
- 轉換小寫
- 單詞計數
- 返回
現在我們已經有了階段設計,讓我們在下一節中使用兩種不同的企業整合技術來實現它。在此表中,我們可以預覽SEDA將如何在我們的實現中顯示:
使用Spring整合的解決方案
對於我們的第一個實現,我們將使用Spring Integration。Spring Integration構建在Spring模型之上,以支援流行的企業整合模式。
Spring Integration有三個主要元件:
- 訊息是包含報頭和正文的資料結構。
- 通道將訊息從一個終結點傳送到另一個終結點。 Spring Integration中有兩種通道:
- 點對點:只有一個終結點可以使用此通道中的訊息。
- 釋出-訂閱:多個終結點可以使用此通道中的訊息。
1、準備階段
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-integration</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.integration</groupId> <artifactId>spring-integration-test</artifactId> <scope>test</scope> </dependency> </dependencies> |
訊息傳遞閘道器是一個代理,它隱藏了向整合流傳送訊息的複雜性。讓我們為Spring整合流程設定一個:
@MessagingGateway public interface IncomingGateway { @Gateway(requestChannel = "receiveTextChannel", replyChannel = "returnResponseChannel") public Map<String, Long> countWords(String input); } |
在SEDA下,通道需要透過關聯的執行緒池進行擴充套件,因此讓我們從建立執行緒池開始:
@Bean("receiveTextChannelThreadPool") TaskExecutor receiveTextChannelThreadPool() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(1); executor.setMaxPoolSize(5); executor.setThreadNamePrefix("receive-text-channel-thread-pool"); executor.initialize(); return executor; } |
接下來,我們將使用執行緒池建立通道:
@Bean(name = "receiveTextChannel") MessageChannel getReceiveTextChannel() { return MessageChannels.executor("receive-text", receiveTextChannelThreadPool) .get(); } |
MessageChannels是一個Spring Integration類,它幫助我們建立各種型別的通道。這裡,我們使用executor()方法建立一個 ExecutorChannel,它是一個由執行緒池管理的通道。
2、SEDA接受檔案階段
我們的渠道建立後,我們就可以開始實施我們的階段了。讓我們建立初始階段:
@Bean IntegrationFlow receiveText() { return IntegrationFlows.from(receiveTextChannel) .channel(splitWordsChannel) .get(); } |
IntegrationFlows是一個流暢的Spring整合API,用於建立 IntegrationFlow物件,表示我們的流的各個階段。
3、SEDA拆分單詞階段
我們的下一階段只有一項責任:將我們的輸入字串拆分成一個 字串陣列,其中包含句子中的各個單詞:
@Bean IntegrationFlow splitWords() { return IntegrationFlows.from(splitWordsChannel) .transform(splitWordsFunction) .channel(toLowerCaseChannel) .get(); } |
4、SEDA轉為小寫階段
@Bean IntegrationFlow toLowerCase() { return IntegrationFlows.from(toLowerCaseChannel) .split() .transform(toLowerCase) .aggregate(aggregatorSpec -> aggregatorSpec.releaseStrategy(listSizeReached) .outputProcessor(buildMessageWithListPayload)) .channel(countWordsChannel) .get(); } |
我們在這裡使用的第一個新的 IntegrationFlows 方法是 split()。split()方法使用splitter模式,將我們的輸入訊息的每個元素作為單獨的訊息傳送到toLowerCase。
我們看到的下一個新方法是aggregator(),它實現了聚合器模式。聚合器模式有兩個基本引數。
- 釋出策略,它決定何時將訊息合併成一個單一的訊息
- 處理器,它決定了如何將訊息合併成一個單一的訊息。
我們的釋出策略函式使用listSizeReached,它告訴聚合器在輸入陣列的所有元素都被收集後開始聚合。
5、計詞階段
我們的最後階段將我們的單詞計數打包成一個Map,其中鍵是原始輸入的單詞,而值是每個單詞的出現次數。
@Bean IntegrationFlow countWords() { return IntegrationFlows.from(countWordsChannel) .transform(convertArrayListToCountMap) .channel(returnResponseChannel) .get(); } |
使用Apache Camel的解決方案
Apache Camel是一個流行而強大的開源整合框架。它基於四個主要概念。
- Camel上下文。Camel執行時將不同的部分粘在一起。
- 路由。路由決定了一個訊息應該如何被處理,以及它接下來應該去哪裡。
- 處理程式。這些是各種企業整合模式的即用型實現。
- 元件。元件是透過JMS、HTTP、檔案IO等整合外部系統的擴充套件點。
詳細點選標題
這些示例的原始碼可在 GitHub 上獲得。
相關文章
- Apache Camel與Spring-boot和Kafka的整合開源案例ApacheSpringbootKafka
- apache camelApache
- Apache Camel K 1.0 為基於Kubernetes或Serverless的微服務提供整合功能 - davsclausApacheServer微服務
- Apache Camel的單元測試Apache
- 基於註解的方式使用spring-integration-redis分散式鎖SpringRedis分散式
- Apache Camel日誌四種方法Apache
- 使用Apache Camel進行Java企業整合ApacheJava
- 用 GoLang 編寫類似 Apache Camel 路由引擎GolangApache路由
- 基於SpringBoot的後臺管理系統(Apache Shiro,Spring Session(重點))(五)Spring BootApacheSession
- 基於Apache Doris的湖倉分析Apache
- improve spring integration read message performance from mqSpringORMMQ
- 基於Apache Hudi和Debezium構建CDC入湖管道Apache
- Spring Cloud Stream與Spring Integration整合以及Spring Cloud Function的關係:開啟從基於註釋到函數語言程式設計的漫長轉換 - spring.ioSpringCloudFunction函數程式設計
- 基於Hadoop的Apache Hudi 0.10 釋出HadoopApache
- 使用Spring Integration和Hazelcast進行叢集領導者選舉SpringAST
- 基於Spring Batch的Spring Boot的教程 - BaeldungBATSpring Boot
- 基於Spring Boot和Spring Cloud實現微服務架構Spring BootCloud微服務架構
- 基於Istio/gRPC/Redis/BigQuery/Spring Boot/Spring Cloud和Stackdriver的微服務案例RPCRedisSpring BootCloud微服務
- 使用Spring Integration接收TCP與UDP請求SpringTCPUDP
- 關於Apache Tika的學習和使用Apache
- Spring MVC 基於URL的攔截和對映規則SpringMVC
- 基於Maven的Spring整合CXFMavenSpring
- Spring基於XML方式的使用SpringXML
- 基於Apache元件,分析物件池原理Apache元件物件
- 基於 Apache Hudi 構建增量和無限回放事件流的 OLAP 平臺Apache事件
- 基於Spring Security和 JWT的許可權系統設計SpringJWT
- Spring Cloud OpenFeign:基於Ribbon和Hystrix的宣告式服務呼叫SpringCloud
- Apache Cassandra 的 Spring 資料ApacheSpring
- spring boot基於Java的容器配置Spring BootJava
- Spring基於註解的IoC配置Spring
- 基於Spring Cloud的微服務落地SpringCloud微服務
- Spring基於註解的aop配置Spring
- Spring系列:基於Spring-AOP和Spring-Aspects實現AOP切面程式設計Spring程式設計
- 基於Amazon ECS Fargate構建Apache SupersetApache
- 原始碼簡析Spring-Integration執行過程原始碼Spring
- StreamNative將Kafka整合到基於Apache Pulsar的雲中KafkaApache
- 優步分享基於Apache Kafka的Presto使用經驗ApacheKafkaREST
- Spring7——開發基於註解形式的springSpring