宜信支付結算帳戶系統淺析

互聯網金融系統的核心是支付結算,而支付結算的基礎又是帳戶系統。互金帳戶系統的特色是併發量大、響應快、交易金額大,熱點帳戶問題突出。一個合格的帳戶系統既要解決上述問題,又必須絕對保證資金安全。做爲宜信這家互聯網金融公司的支付結算中心,其帳戶系統也具有上述特徵。前端

一、 帳戶體系nginx

1. 帳戶結構redis

宜信支付結算帳戶體系是客戶、用戶、帳戶三層結構,證件號和證件類型惟一肯定一個客戶,客戶號和機構號肯定一個用戶,一個用戶下可開多個不一樣類型的帳戶。如圖:sql

宜信支付結算帳戶系統淺析

 

2. 帳戶屬性數據庫

帳戶系統的基礎是帳戶,全部的操做都圍繞着帳戶進行,帳戶包含如下一些屬性:json

宜信支付結算帳戶系統淺析

 

• 會計科目:每一個帳戶金額的變更要體現一些會計的屬性,以便會計覈算。緩存

• 帳戶類別:分爲我的帳戶、企業帳戶、平臺類帳戶。安全

• 帳戶明細:帳戶的明細是反應帳戶餘額變更的每筆詳情,採用複式記帳法,包含本對方帳號、帳戶等信息、借貸方向、摘要、借貸方的發生額及餘額等信息。網絡

• 帳戶餘額:記錄帳戶的實時餘額。架構

3. 會計科目

帳戶下掛在最底層的會計科目下,會計科目決定了帳戶的含義及餘額變更方向。會計科目的一些屬性以下:

宜信支付結算帳戶系統淺析

 

• 科目類別:資產類、負債類、全部者權益、成本類、損益類等。

• 科目級別:會計科目的級別,一級科目、二級科目、三級科目等。下級科目歸屬上級科目。

• 餘額方向:標示餘額是在借方仍是貸方。

• 科目的期末餘額:每日日切後會彙總底層科目全部下掛帳戶在上一會計日的餘額總和,上級科目彙總下級科目的餘額總和。

4. 科目樹

宜信支付結算帳戶系統採用科目樹的概念,每一個機構都會綁定一個科目樹。科目樹的根節點是一級科目,底層的科目下掛帳戶,結構以下:

宜信支付結算帳戶系統淺析

 

二、 帳戶系統架構

宜信支付結算帳戶系統採用公司自研的分佈式微服務框架,對外暴露http json接口,內部各服務間採用redis實現的消息隊列通信。

1. 帳戶系統功能架構

宜信支付結算帳戶系統分爲接入模塊、記帳子系統、開戶子系統、異步記帳模塊、查詢子系統、定時任務子系統、日終子系統、異步日誌模塊,下圖是帳務系統功能模塊圖:

宜信支付結算帳戶系統淺析

 

• 接入模塊:提供報文解析、驗籤、參數校驗、權限認證等公共服務,是帳戶系統的統一入口。

• 異步日誌模塊:異步記錄業務系統請求報文。

• 記帳子系統:帳戶系統的核心模塊,處理業務系統的記帳請求。

• 開戶子系統:處理業務系統的開戶請求。

• 首次開立帳戶:爲我的或企業開立客戶、用戶及提早配置的默認開通的帳戶。

• 指定開立帳戶:我的或企業在首次開立帳戶後,可按科目號指定開立帳戶。

• 查詢子系統:提供帳戶、記帳的一些查詢功能。

• 異步記帳模塊:提供異步記錄帳戶流水的功能。

• 定時任務子系統:處理失敗重試、熱點帳戶等的定時任務。

• 日終子系統:提供日切以及日終跑批的功能。

1) 記帳處理

記帳處理是帳戶系統的核心功能,該功能對性能的要求比較高,高併發下熱點帳戶問題比較突出,資金的正確性也必須保證,而且根據業務不一樣,記帳的分錄也是五花八門,宜信支付結算帳戶系統如何應對這些問題,這裏重點介紹下:

• 帳戶系統記帳採用記帳服務的概念,每一個記帳服務就是一個記帳分錄的模板,業務系統按照這個模板傳入記帳金額、帳戶號或者用戶號等信息。

• 帳戶系統採用redis分佈式鎖,防止業務系統重複提交請求。設置記帳訂單防重表,按照請求單號和機構號對記帳請求作冪等性校驗。

• 採用複式記帳法,按照會計規則按照借貸記錄流水,有借必有貸。

• 記帳處理時,更新帳戶餘額後同步返回結果給業務系統,異步的處理記帳流水。同時設置補償機制,定時重試記帳流水處理失敗的訂單,重試三次失敗後報警人工介入。

• 記帳規則處理,每一個記帳服務能夠綁定一些記帳規則,帳戶系統根據記帳服務遍歷其綁定的規則,順序處理。

2) 熱點帳戶問題

熱點帳戶問題是帳戶系統的痛點,也困擾了咱們好久,這裏着重說下。

• 充值時的記帳分錄是,

借方:三方支付待清算帳戶(+)

貸方:我的餘額帳戶(+)

當大量用戶充值時,三方支付的待清算帳戶就是熱點帳戶,頻繁的增長餘額。

• 提現時的記帳分錄是,

借方:我的餘額帳戶(-)

貸方:三方支付資產帳戶(-)

當大量用戶提現時,三方支付的資產帳戶就是熱點帳戶,頻繁的減小余額。

• P2p業務收服務費的記帳分錄是,

借方:我的p2p帳戶(-)

貸方:商戶服務費帳戶(+)

當大量向用戶收取服務費時,商戶服務費帳戶就是熱點帳戶,會頻繁增長餘額。

• p2p業務服務費付款的記帳分錄是,

借方:商戶服務費帳戶(-)

貸方:我的p2p帳戶(+)

當大量用服務費餘額向用戶付款時,商戶服務費帳戶就是熱點帳戶,會頻繁減小余額。

記帳時,全部涉及的帳戶餘額都要作update更新,高併發狀況下,當出現上述類型的熱點帳戶時,因爲數據庫的行級鎖,對同一帳戶的更新餘額操做由並行變成串行,單個請求的響應時間變長,從而拖垮整個記帳服務。

宜信支付結算帳戶系統針對上述問題作了以下處理:

咱們把熱點帳戶按照金額變更方向分爲加頻帳戶(餘額增長頻繁)、減頻帳戶(餘額扣減頻繁)、雙頻帳戶(餘額增長扣減均頻繁)。

• 加頻帳戶處理:準實時更新餘額。先將金額變更插入臨時表中,由定時任務按照必定頻率彙總發生額,並更新帳戶餘額,然後刪除臨時記錄。當加頻帳戶減錢餘額不足時,主動去彙總發生額。這裏須要考慮主動彙總發生額和定時任務處理的併發狀況,咱們在該定時任務執行時設置redis鎖,防止併發,主動彙總時會去判斷這個redis鎖是否存在,如存在證實定時任務正在執行,無需主動彙總,多是真的餘額不足。主動彙總一樣會設置redis鎖,定時任務一樣會判斷。

• 減頻帳戶處理:將減頻帳戶拆分多個子帳戶,減頻子帳戶設置金額報警,若是某個減頻子帳戶餘額不足觸發報警,會對該子帳戶作資金歸集,將其餘子帳戶餘額歸集到該子帳戶(每一個子帳戶設置可歸集金額限制)。如在交易過程當中發現該子帳戶餘額不足,轉向使用其餘子帳戶記帳。因爲拆分子帳戶,餘額查詢時須要彙總各個子帳戶餘額返回;記錄主帳戶流水須要記帳後餘額,這裏須要異步計算彙總。當減頻帳戶加錢時,須要平均分配入帳到不通的子帳戶。

• 雙頻帳戶處理:將雙頻帳戶拆分多個子帳戶。加錢時,準實時更新餘額,先將子帳戶金額變更插入臨時表中,由定時任務按必定頻率彙總發生額,將彙總的發生額更新進對應的子帳戶,並刪除金額變更記錄;減錢按照以前減頻帳戶的邏輯執行。

3) 記帳死鎖問題

高併發狀況下,當多個帳戶以前互相轉帳時,可能會出現死鎖問題。

例如:A餘額帳戶 —> B餘額帳戶(線程1)

B餘額帳戶—>A餘額帳戶(線程2)

兩個轉帳請求併發,帳戶系統對每一個轉帳請求都會更新A、B餘額,這兩個更新須要在一個事務裏,正常流程線程1先更新A,再更新B,線程2先更新B,再更新A,線程1更新完A後會等待B的鎖,不提交事務,線程2更新完B後會等待A的鎖,不提交事務,這樣兩個線程互相等待鎖,形成死鎖。

宜信支付結算帳戶系統針對這種狀況提出瞭解決辦法,對帳戶號進行排序後再更新餘額,這樣每一個線程都是先更新A再更新B,解決了死鎖問題。

2. 帳戶系統存儲層架構

宜信支付結算帳戶系統數據庫採用Mysql,緩存採用redis。

• Mysql數據庫採用主從架構,一主二從,主庫向從庫同步數據。針對一些數據量大的表進行分表,比較有表明性的是帳戶流水錶,既要按帳戶維度查詢,又要按時間維度彙總,因此針對這個特色,冗餘了一張表,一張按照帳戶分表,一張按照日期分表。

• Redis採起集羣架構,集羣中每一個點主備的形式。

3. 帳戶系統的網絡層架構

帳戶系統各個服務部署在同一機房,其中記帳子系統和異步記帳模塊部署在4個不一樣的物理機上,其餘子系統和模塊部署在2個不一樣物理機上。最前端採用nginx實現負載均衡。

-END-

來源:宜信技術學院 做者:李銳 程留允

相關文章
相關標籤/搜索