爲什麼推薦使用Apache Camel作EAI?

僅爲筆者一家之言。

1. 概述

筆者所在公司主要業務屬於電子政務,近兩年隨着國家"簡政放權"的不斷深入,政府機構之間信息共享的需求也變得日益頻繁,而在歷史遺留等諸多因素的影響之下部門之間的對接並沒有預想中那麼順暢,這種情形下,一個好的框架能大幅度降低對業務研發人員能力的要求,減少問題的產生,以及出現問題後的排查成本,最終達到降低應用集成成本的目的。

今年年初的時候,在與他家公司作技術交流的時候偶然接觸到了Apache Camel這一組件。又在之後的工作中將其應用到公司的某個核心業務功能上,從結果反饋來看其表現不俗。

本文將結合筆者粗淺的認識,以及實際工作經驗,闡述下筆者個人認爲的在作EAI(Enterprise Application Integration,企業應用集成)時候Apache Camel的優勢。

2. 理由

2.1 爲EIP而生

Apache Camel官方網站首頁上直接點明:“Based on Enterprise Integration Patterns (EIP) to help you solve your integration problem by applying best practices out of the box。” (基於EIP,通過開箱即可用的最佳實踐來幫助你解決應用集成問題)。

2.2 完善的路由日誌

其強大的Pipeline設計,讓我們可以將業務邏輯拆解爲原子狀的積木塊,然後依據自身的業務需求將這些積木搭建成理想的樣子,如果能夠嚴格遵循這個思路執行下去,那麼每個積木塊中將只包含獨立的小塊邏輯,再輔之以少量簡單的約束(例如不允許吞掉異常),那麼其他關鍵性的業務扭轉相關日誌信息的記錄我們可以藉助Camel自身提供的路由日誌功能來複現運行時的業務流程,可以想象這將能大大縮短我們在系統異常情況下的響應延時。

下面是筆者遇到的一個錯誤現場,路由流向非常清晰,錯誤原因也是一目瞭然:
發生錯誤時的路由日誌信息

2.3 完備的事務機制

現在人們對於系統的要求越來越高,由此造成的影響之一就是很少有一個系統能將用戶的需求完全滿足,也就是對於一個用戶請求的響應,很可能是多個系統一起協同工作的結果。那麼對於類似的請求,維護數據間的完整性就成了最基本的需求,也就是在系統處理某個請求失敗時,能夠回滾掉之前已經成功的多個子操作(注意這裏的子操作不僅僅是數據庫層面,還有諸如文件增刪等非事務性的操作)。

在Apache Camel中,除了對常規的數據庫事務的支持外,其還通過引入UOW(UnitOfWork)來完成對補償性事務的需求,達到"最終一致性"的柔性事務效果。

藉助以上概念和Camel提供的支持,我們可以通過引入適當的契約接口,來完成對於柔性事務最終一致性的支持。

public class TransactionCompensatingManager implements Synchronization {

	@Override
	public void onComplete(Exchange exchange) {
		// NONE

	}

	@Override
	public void onFailure(Exchange exchange) {
		// 捕獲原始異常
		//final Exception e = exchange.getProperty(Exchange.EXCEPTION_CAUGHT, Exception.class);

		// Copy From MessageHelper.doDumpMessageHistoryStacktrace()
		@SuppressWarnings("unchecked")
		final List<MessageHistory> list = exchange.getProperty(Exchange.MESSAGE_HISTORY, List.class);
		Collections.reverse(list);  //將list中的數據倒序
		for (MessageHistory messageHistory : list) {
			final NamedNode node = messageHistory.getNode();
			if (!(node instanceof ProcessDefinition)) {
				continue;
			}

			final String ref = ((ProcessDefinition) node).getRef();
			if (StringUtil.isEmpty(ref)) {
				continue;
			}

			final boolean containsBean = SpringBeanFactory.containsBean(ref);
			if (!containsBean) {
				continue;
			}
			final Processor bean = SpringBeanFactory.getBean(ref, Processor.class);
			if (!(bean instanceof XxxRollBack)) {
				continue;
			}

			((XxxRollBack) bean).rollback(exchange);
		}

	}
}

通過向Camel中註冊以上配置,那麼每個負責進行業務處理的Processor即可以通過實現XxxRollBack來完成自己負責的那塊邏輯的事務回滾操作,簡單,清晰,優美!

另外Camel在2.21.0之後的版本還引入了對於分佈式事務Saga模式的支持,感興趣的讀者可以閱讀下方的引用鏈接。

2.4 強大的運行時支持

Apache Camel支持動態卸載/添加,啓動/停止,掛起/恢復Route等運行時操作,這在某些情況下會變得非常有用,當然更多的神來之筆就取決於研發人員的想象力和創造力,以及實際的業務場景了。(關於這一點,讀者可以通過監控平臺Hawtio來檢驗,實現方式參見筆者的另外一篇博客 Apache Camel監控之使用hawtio
動態操作Route
不過這裏要額外說一句的是,筆者發現在實際工作中,不少研發人員,尤其是剛入行不久的,特別喜歡追求這種奇方祕技,寄希望於其能夠拯救由一堆慘不忍睹的代碼堆砌出來搖搖欲墜的系統,或彰顯某些東西;對此筆者一直覺得莫名其妙——技巧是用來錦上添花的,你這根都爛了,還寄希望於在外面套一層絢爛的外衣能夠力挽狂瀾? 基礎不牢,地動山搖,有這時間把基礎打好,應該是一條更正確的路線。

2.5 極爲豐富的擴展組件

Apache Camel歷經12年的發展,到如今已經擁有多達三百餘種擴展組件,幾乎所有你能想象到的組件都能在Camel的擴展組件包中找到,例如讓筆者驚訝的camel-exec(用於執行系統命令)等。感興趣的讀者可以去camel-components-list找一下是否有自己感興趣的,或者馬上要用到的。

而且每次的版本更新,這些擴展組件的版本號將一併隨之更新,這樣就免去你到處確認版本號的煩惱,非常方便。

2.6 方便靈活的擴展機制

由上面2.4小節就可以看出,Apache Camel的擴展應該是極其方便和靈活的,這一點不僅表現在第三方擴展組件上,也表現在對於內部自定義業務邏輯的拆解上,你可以將自身的業務邏輯拆解爲一個個的Processor處理塊,這隻取決於你自己的想象力,Camel沒有對此作任何限制。

2.7 詳盡的文檔

Apache Camel有着非常詳盡的文檔,並對應得在Github上維護着一份專門的 Camel Example,樣例代碼幾乎涵蓋了Camel的所有擴展組件,對於新手而言相當友好,對於熟手上手其他不熟悉的組件也是非常方便。

2.8 極其活躍的社區

這個可以說是以上大部分其他理由的基石。如此活躍的社區意味着你的絕大部分困擾已經被先驅者們遇到並解決,作爲後來者的你可以盡情享受這樣一份饋贈。箇中的幸福對於由.NET陣營轉投到Java陣營的筆者有着切身體會。

3. 意外之喜

3.1 學習第三方組件的起點

在你熟悉Apache Camel的基本使用之後,你就會發現Camel真的是學習其他第三方組件一個非常好的起點,因爲它已經幫你把一些默認參數都準備好了, 你只需要參考Camel提供的詳盡文檔和用例,測試你想要的功能即可,例如下面這個測試Hibernate validator功能的單元測試:

CamelTestUtil.defaultPrepareTest2(new RouteBuilder() {
	@Override
	public void configure() throws Exception {
		configValidatorFail(this);
		from("stream:in?promptMessage=Enter something:")//
				.setBody(constant(new Car(null, null)))//
				.to("bean-validator://x")//
				.to("stream:err");
	}
});

在以上測試用例中,你只需要關注各個註解的用途是否符合你的預期,然後快速挑選出符合你當前業務場景的註解即可。其他諸如初始化,驗證等工作Camel會自動幫你完成,實在是大大降低了入門曲線。至於之後的高級應用,當然還是得看個人主觀能動性了。

4. Links

  1. Apache Camel Office Site
  2. Apache Camel 介紹
  3. The Saga Pattern in Apache Camel
  4. 基於 Seata Saga 設計更有彈性的金融應用
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章