支付渠道路由系統進化史

支付系統通常須要對接多個支付渠道,一是爲了保證系統的可靠性,不能由於單一渠道的問題影響整個支付系統。二是爲了提升支付能力,不一樣渠道提供支付能力不一樣。三是爲了下降支付成本。html

對接多個支付渠道之後,爲了能夠正確選擇支付渠道支付,所以設計渠道路由系統。apache

155755816925615e8c95361d34e2e8dcec3ede1e4751a.png

從上圖能夠看到路由系統功能其實很簡單,分發支付請求到正確的渠道。但就是這個簡單系統,也通過幾回系統改造升級,最終才成爲如今的樣子。下面就來講說這個系統是如何演進。編程

下面假設對接支付渠道爲支付寶與微信。api

初期

支付系統初期,這個階段業務需求較簡單,僅僅須要知足一個支付場景(例如使用支付寶支付)。爲了快速上線,設計方案就簡單粗暴,對外直接暴露支付服務接口,由業務系統發起直接調用。緩存

系統設計圖以下:微信

1557558195734f56b2af2598348c0b7026a7b7f538c37.png

這個階段因爲只有一個支付渠道,因此也不須要有路由系統,直接由業務系統調用支付服務接口發起支付。架構

這個設計方案存在不少問題:框架

  1. 業務系統與支付系統位於同一個系統,系統任何一次變動都會影響整個系統。
  2. 擴展性問題。接入新支付渠道,如微信,須要新暴露一個微信支付服務接口。業務系統須要改動代碼。從另外一方面講,業務系統承擔路由系統的功能。
  3. 複用性。新支付渠道,其實除了與支付渠道交互相關代碼以外,其餘代碼能夠複用。

針對以上問題,將系統進行了相應改造。性能

首先是將支付系統與業務系統單獨拆分出來,成爲兩套單獨的系統。支付系統對外暴露一組通用接口。業務系統僅對接這組接口。業務系統若想指定支付渠道支付,接口參數傳入渠道標識便可。這樣就將耦合在業務系統中路由功下沉到支付系統。微信支付

其次梳理渠道接口文檔,抽象出共性接口。接入新支付渠道,只要繼承接口,實現相關方法便可,簡化渠道開發難度。

改版後的系統實現圖以下:

15575582396465806ad80c2f5414bb635b0dfd150f44a.png

此時,路由系統知識支付系統的一個模塊,具體實現以下。

首先定義通用渠道接口,其中 channelName 方法,返回渠道渠道惟一標識,如支付寶渠道返回 aliPay

1557558264457c6bac4bb077f4dadb1978bb33345983e.png

而後根據 Spring ApplicationContext getBeansOfType 方法,獲取實現同一個接口的全部 Bean.最後將其放入 Map 緩存中,其中鍵值爲 channelName 方法返回渠道標識。

15575582782446a64cce2d48147bfa55fec4061adfd2c.png

這個階段方案的問題在於支付系統全部模塊位於同一工程。有些模塊須要頻繁發佈,而有些模塊,如渠道模塊,路由模塊改動就不多。這樣就致使系統任一改動發佈,影響整個支付系統可用性。

中期

針對初期後面的問題,進行了相應改造。

首先仍是進行拆分,將支付系統按照模塊拆分。路由系統,渠道系統,成爲獨立系統,獨立部署維護。

1557558294307e5e382cd8cb54a159143ebd8642f0d8a.png

系統之間調用採用 RPC 通信,使用 Dubbo 框架。

相關實現以下:

相關接口邏輯不變,只是將同一進程內調用變成跨系統的調用。

渠道系統提供服務:

155755831008441c9b01adc0e45c7bd8c5baa053bcc27.png

這裏改動,將渠道標識放入 Dubbo 服務 group 字段,藉助 Dubbo 分組功能標識中惟一的渠道系統。

路由系統引用渠道系統的服務:

1557558332575d80f014cc6b5423a817c18189be97d6b.png

這裏一樣須要設置 group 且須要和服務提供者一致。而後在路由系統中將服務註冊到緩存中,使用渠道標識爲 key,渠道服務名爲 value。

1557558342097e514538a992140648ee5723d45a3f29a.png

最後路由系統藉助 Spring ApplicationContext getBean 獲取具體的服務。

15575583555300b6c9d0d5311475b8592d0c014a54922.png

這個設計的問題在於:

路由系統中須要手動引用渠道系統服務,而後再註冊。這樣在增長渠道系統就比較繁瑣。那是否是能夠作到增長渠道系統時,無需修改路由系統,路由系統自動發現服務?

藉助 Dubbo API

後期

查看 Dubbo 文檔,能夠直接使用 ReferenceConfig 直接查找服務提供者。

1557558370850a844af4a344a4704b7d8732ede9a0041.png

官方文檔建議:

ReferenceConfig 實例很重,封裝了與註冊中心的鏈接以及與提供者的鏈接,須要緩存。不然重複生成 ReferenceConfig 可能形成性能問題而且會有內存和鏈接泄漏。在 API 方式編程時,容易忽略此問題。

這裏使用ReferenceConfigCache,用於緩存 ReferenceConfig 實例。

去除以前全部引用服務配置文件以及緩存註冊代碼,引入 ReferenceConfigCache,改造以下。

15575584076432a4bb2e3c49145d3a93eb6c86f8b352e.png

總結

回顧上文路由系統,能夠看到初期沒有路由系統,整個系統能夠運行下去。可是隨着系統複雜度提升,初期系統架構已經不能知足系統的高效運行,因此才一步步改進系統。改進的過程當中,不斷髮現方案不足處,而後一步步迭代演進。這個過程當中,要善於利用現有框架的功能,加速功能的開發。

相關文章
相關標籤/搜索