“某寶”支付服務架構演進之路,解決實際問題!

farsun發表於2021-09-09

今天就說說支付服務的那些事吧。以此來對過去幾年的創業經歷做個小結。


系統演進


新的業務系統初建時,業務邏輯相對簡單,業務量也比較小,為了能夠快速實現功能,釋出上線,多數團隊都會把所有的邏輯都耦合在一個系統。這對於初期業務的快速迭代是有一定好處的。毫不例外,前公司的支付交易系統也採用了這樣的方式。


單體架構簡便快速,然而這種架構的缺點也很明顯,姑且不說高併發訪問,邏輯分散,隨著需求的迭代,後期難以維護。初接專案,問題很多,每天就是排查問題,和第三方確認交易等。好在深陷泥濘不久,就開始著手新支付服務設計實現。那麼,支付要解決的問題有哪些呢?


解決的問題


做支付服務也有兩年多了,總結下支付服務要解決的有哪些問題。


  • 最原始和核心的需求,資金流動

  • 高可用。全天候提供服務。需要解決如下問題:


  • 多機。熱釋出。

  • 通訊異常或超時。異常的交易如何保證交易最終一致性。

  • 防雪崩。渠道偶也會有抽風時,他們抽風了,我們可不能跟著抽風。快速熔斷,防止大量資源(連線)被暫用。

  • 通知下游服務失敗或異常時,重試通知。


  • 易用性。滿足各種業務需求,各業務系統呼叫只需提供少量必要資訊即可,介面簡單、呼叫方便。

  • 簡單風控。對交易做校驗,識別並阻止誤交易或惡意交易。

  • 防止重複交易。不用的業務場景,對重複扣款要求不一。對於同一使用者下同一業務的扣款,交易發起方可能會有多個,如:使用者自動發起、工作人員介入發起、系統定時扣款發起,即會下多個支付訂單,然由於業務要求多個支付訂單隻能有一筆支付成功。如何保證不會多扣使用者的錢,即需要防止對同一業務下的支付訂單重複扣款。而有些業務(如充值)又沒有此限制。

  • 支付路由。為保證服務的穩定可靠,一般會接入多個支付渠道互備。多個支付渠道,如何個性化選擇?一般考慮路由的的因素有如下:


  • 不同業務對支付渠道有特殊要求。

  • 同一業務不同時期對支付渠道有特殊要求。

  • 支付渠道有個人問題(卡掛失、卡過期、交易金額超個人設定限額、未知異常等)和渠道問題(渠道下某個銀行未開通或交易金額超渠道設定限額、渠道跪了、渠道對個人餘額不足做次數限制等)導致不可用。

  • 不同渠道費率可能不盡相同,省錢省錢省錢。

  • 一般會將費率高的渠道作為備用,然而作為合作備胎也是有尊嚴的,你也是要時不時撩一下,給下希望,所以每天也得保證一定的交易量。


  • 需求迭代。由於業務的特殊性,需求一直在迭代,經常需要接入新渠道。如何滿足快速的需求迭代?如何讓新人快速高效投產?系統架構要合理,高內聚低耦合。自動化測試釋放重複性的一些測試工作。

  • 監控與預警。要保證系統的高可靠和高可用,監控必不可少。業務上,監控異常的交易。監控銀行和渠道的可用性。手續費預警,避免坐扣發生。系統執行情況監控等。

  • 資源分配。按交易來源的不同,交易可以分為兩類:一類是使用者發起,一類是系統定時批次交易。使用者發起的交易一定得先得到保證,然後又要兼顧系統定時批次交易。


圖片描述


  • 異常交易快速發現及處理。系統難免有異常交易的情況發生。如交易超時、回超時、渠道或銀行系統抽風、掉單等。如何快速發現異常交易並快速修復異常。

  • 動態配置。渠道或銀行系統難免會有維護的時候,尤其銀行節假日經常會有升級維護。維護期間或者他們的服務是不可用的,或者限制交易限額等等。智慧路由也有如權重優先順序等一些配置,等等此類的配置都是需要動態維護的。

  • 全域性異常處理。各業務呼叫方式不一,有RESTFUL介面DUBBO介面等。如何保證異常處理的一致性。

  • 支付結果個性化通知。由於支援了不同的業務,而不同業務的後續處理方式是不同的,需要個性化通知下游系統。

  • Fail fast。分散式系統,要對每個模組系統的可用性持懷疑態度,當出現某個系統不可用時(如發包),要能快速優雅地結束整個流程。這點設計出問題時可能會幫你避免影響的進一步擴大。舉個例子,服務出現過僅有的兩次事故,一次是路由服務機子磁滿了,一次是網路問題,導致異常交易發生,“Fail fast”避免了雪崩效應,同時保證了交易的一致性,避免人工修資料情況的發生,為服務的快速恢復提供了可能(從問題發現到服務恢復,均在十分鐘左右)。

  • 埋點。涉及錢的,應該是一件很嚴肅的事。任何系統都會存在BUG,所以交易需要進行必要的埋點用於追蹤問題交易。

  • 限制資源的使用。對於資源使用的限制設計是高可用系統最重要的一點,也是容易被忽略的一點,資源相對有限,用的過多了,自然會導致應用當機。一般有如下限制:

  • 限制連線數

  • 限制執行緒建立

  • 限制併發

  • 限制記憶體的使用

  • 狀態碼的學習。第三方支付渠道返回的狀態碼偶爾會變更(推測是第三方會切換渠道或者接入新的渠道),而新增的新狀態碼第三方往往通知不及時甚至不通知,新狀態碼在未能判定成功或失敗的情況下,是個未知狀態(寧可未知也不能誤判。這一點很重要,很多第三方在處理和銀行或其他第三方時,出現通訊超時或者未知狀態碼後就返回失敗,這導致了很多掉單情況的發生,踩了很多這樣的坑…),如何快速發現並學習新狀態碼的含義?總之,需求很明確,就是適應網際網路應用的場景,也沒啥特別之處。後面有時間再理一下系統的演進實現吧

作者:高階架構師

來源:https://my.oschina.net/u/3772106/blog/1611400

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4289/viewspace-2808995/,如需轉載,請註明出處,否則將追究法律責任。

相關文章