響應式架構與 RxJava 在有贊零售的實踐
隨著有贊零售業務的快速發展,系統和業務復雜度也在不斷提升。如何解決系統服務化后,多個系統之間的耦合,提升業務的響應時間與吞吐量,有效保證系統的健壯性和穩定性,是我們面臨的主要問題。結合目前技術體系和業務特點的思考,我們在業務中實踐了響應式架構以及 RxJava 框架,來解決系統與業務復雜所帶來的問題。
一、實踐響應式架構
響應式架構是指業務組件和功能由 事件驅動 ,每個組件異步驅動,可以并行和分布式部署及運行。
響應式架構可以帶來以下優勢:
-
大幅度降低應用程序內部的耦合性
-
事件傳遞形式簡化了并行程序的開發工作,使開發人員無須與并發編程基礎元素打交道,同時可以解決許多并發編程難題,如死鎖等。
-
響應式架構能夠大幅度提高調用方法的安全性和速度。
-
對復雜業務系統的領域建模,響應式架構可以天然支持。每個系統組件就可以對應到一個業務實體,業務實體之間通過接收事件來完成一次業務操作。
我們使用響應式架構主要是為解決多個系統間的多次遠程調用帶來的分布式問題,尤其在長任務場景中,響應式架構顯得尤其必要。
有贊連鎖出現后,隨著連鎖商家經營規模的擴張,會在系統中創建新的門店。創建新門店會引發一系列業務初始化工作,例如店鋪、員工、倉庫、商品、庫存等業務域,并且各業務域之間存在一定的依賴關系(如圖1所示),例如商品依賴倉庫初始化完成。
圖1 連鎖新建分店系統依賴關系
商家新增門店時,在店鋪初始化完成后,連鎖系統發送店鋪初始化成功消息,相應系統對事件進行響應,處理完成(成功/失敗)后將回執給連鎖系統,連鎖系統根據相關業務的反饋,決定是繼續通知下游業務,還是結束整個過程。新建門店部分流程如圖2所示。
在創建門店業務中,每個系統響應連鎖系統發出的消息,處理完成后進行回執。通過這種模式,業務系統本身不關心其他系統是否成功或失敗,只需對通知的事件進行處理,整體初始化進度與異常處理由連鎖系統來控制。這種設計使得各業務系統之間沒有直接耦合并保持相互獨立。
圖2 連鎖體系新增分店消息驅動圖
上面的案例介紹了在復雜業務場景下系統間對響應式架構的實踐,系統內部同樣會遇到復雜業務場景。下面介紹下在系統內部應對復雜業務的實踐。
二、RxJava在有贊零售實踐
Rxjava 是用來編寫異步和基于消息的程序的類庫。RxJava 在 Android 有著廣泛的使用,主要應用在用戶界面繪制與服務端通訊等場景。RxJava 的核心思想是響應式編程以及事件、異步這兩個特點。響應式編程是一種通過異步和事件流來構建程序的編程模型。在復雜的業務開發中,最棘手的問題就是如何清晰直觀的展現復雜的業務邏輯,并且方便后續的業務維護與擴展。
2.1 響應式編程使得復雜業務邏輯更清晰
有贊零售的業務場景中有著復雜的業務邏輯,有贊目前提供多種產品供商家選擇,商家在不同產品進行切換時,為了商家更好的體驗,不同業務的切換會進行數據初始化與處理。例如有贊微商城轉換到有贊零售。
這里拿著微商城升級零售的業務場景給大家舉例。微商城升級為零售時需要對商品進行轉換。首先初始化店鋪基礎信息。然后讀取商品流,將微商城的商品類型轉換成零售支持的商品類型。最后讀取規格,為規格創建供應鏈商品庫,創建門店商品與添加網店商品的供應鏈商品關聯關系。整體轉換流程如圖3所示。圖中也畫出了可以并發處理的場景。
圖3 微商城升級有贊零售流程
如果單純使用設計模式來解決上面這種場景單一、但業務邏輯特別復雜的場景,是很難做到的。也可以看到除了初始化信息那一步,后面的商品模型轉化自始至終在業務中流轉的事件都是商品,這里就可以使用 RxJava 來優化業務代碼使得處理流程可以并發,加快升級速度。
最終我們按照圖3的流程處理升級邏輯,其中的并發場景,比如保存完零售商品后,并發處理庫存、和銷售渠道,使用 rxjava 封裝的方法幫助我們進行并發操作。如下所示代碼結構清晰,對外屏蔽了復雜的并發處理邏輯。
最終我們的整體的代碼:
整個商品處理流程就是上面這段代碼,一目了然,后面擴展可以自己在中間加入處理流程,也可以在對應業務方法中修改邏輯。
2.2 多服務、數據源組合
隨著微服務架構興起,我們將不同的業務域拆分成不同的系統。這樣方便了系統的維護,提升了系統的擴展性,但是給上層業務系統也帶來了很多麻煩。往往我們為了展示一個頁面會涉及到 2-3 個或更多的應用,而多次的分布式調用不但使得系統的rt增加,也使得核心頁面的出錯風險更高。
降低rt:在假設第三方接口已經達到性能頂點的情況下,并發是解決多次分布式調用降低rt的常用方法。
自動降級:傳統編程方法中,自動降級處理,意味著我們代碼中會出現一大堆try/catch,而使用 rxjava,我們可以直接定義當流處理異常時,程序需要怎么做,這樣的代碼看起來非常簡潔。
商品搜索作為商品管理的核心入口,根據不同場景聚合商品、優惠、庫存等信息。由于商品列表頁展示的信息涉及到多服務數據的整合,一方面需要保證整個接口的 rt,另一方面不希望由于一個商品數據或外部服務的異常影響到整個商品列表的加載。因此該場景非常適用于 RxJava。
最終我們的代碼
1.根據入參獲取商品加載器
2.根據 es 結果獲取商品各個屬性詳情并加載到 SkuAttrContext 中(某類屬性加載失敗則忽略)
3.組裝搜索結果(如果某個 sku 組裝失敗則直接忽略)
三、后記
本文主要介紹了響應式架構與 RxJava 在有贊零售的使用場景。目前我們對響應式架構的實踐方式是:在系統間使用消息中間件來進行實現,在系統內則使用 RxJava 實現異步化和響應式編程。對于響應式架構的思想,我們也在探索階段,并在部分業務場景進行實踐。未來面對越來越復雜的零售業務場景,會用響應式架構全面實現系統業務的異步化。總的來說響應式架構思想為提升復雜業務系統健壯性、靈活性提供了強有力的支撐。后面大家如果想更多的討論響應式架構與編程的實踐,歡迎聯系我們。
擴展閱讀:
4. WEB-UI 自動化實踐
-The End-