通用对账系统介绍与设计(上)
轉(zhuǎn)自: http://mp.weixin.qq.com/s/y2I_EYSLlq_239vZXr0OZQ
本文首先介紹了對(duì)賬的概念、基本內(nèi)容,其次講解了對(duì)賬系統(tǒng)中常見問(wèn)題及解決方法,最后詳細(xì)講解了整個(gè)對(duì)賬系統(tǒng)的流程設(shè)計(jì)、整體框架。本文所說(shuō)的對(duì)賬是一個(gè)通用概念,不針對(duì)具體行業(yè),各應(yīng)用領(lǐng)域可根據(jù)實(shí)際情況進(jìn)行調(diào)整。
對(duì)賬系統(tǒng)簡(jiǎn)介
對(duì)賬是金融領(lǐng)域中的名詞,對(duì)應(yīng)的學(xué)科為大家熟知的會(huì)計(jì)學(xué)。在金融領(lǐng)域中,不僅銀行、基金、第三方支付機(jī)構(gòu)需要對(duì)賬,其他任何涉及金融交易的公司/機(jī)構(gòu)都需要對(duì)賬,比如商戶業(yè)務(wù)、信貸業(yè)務(wù)等。
對(duì)賬是指對(duì)前一個(gè)清算周期的交易信息進(jìn)行核對(duì),以確認(rèn)交易信息的一致性和正確性的過(guò)程。這是普遍認(rèn)可的一個(gè)概念,可以用一句話總結(jié):確保單個(gè)周期內(nèi),信息流和現(xiàn)金流的一致。
通過(guò)對(duì)賬可以保證賬證一致、賬賬一致、賬實(shí)一致,三者一致的正確、真實(shí)、完整為后續(xù)的傭金、分潤(rùn)等計(jì)算提供基礎(chǔ)。對(duì)賬的準(zhǔn)確性也為系統(tǒng)、人工平賬提供了差錯(cuò)信息,確保平賬后達(dá)到財(cái)務(wù)一致。
總之,對(duì)一個(gè)公司來(lái)說(shuō),通過(guò)對(duì)賬,可以正確地反映企業(yè)的財(cái)務(wù)狀態(tài),及時(shí)發(fā)現(xiàn)差錯(cuò),確保業(yè)務(wù)健康發(fā)展。
對(duì)賬大部分涉及兩方對(duì)賬,極少情況下會(huì)有三方對(duì)賬的情況。三方對(duì)賬本身的系統(tǒng)邏輯比較復(fù)雜,特別是三方平賬時(shí)的差錯(cuò)處理更加復(fù)雜,這里不作討論。
對(duì)于沒(méi)有虛擬賬戶,只有交易通道類的對(duì)賬,有兩種對(duì)賬類型:總分對(duì)賬和明細(xì)對(duì)賬。
總分對(duì)賬即根據(jù)不同的交易通道,把每個(gè)交易通道的進(jìn)出或者單獨(dú)的交易類型進(jìn)行匯總,按照不同交易通道、不同交易類型進(jìn)行總對(duì)總對(duì)賬,確保和每個(gè)交易通道的進(jìn)出是一致的,確保每個(gè)通道不會(huì)有長(zhǎng)款或短款的情況。
對(duì)大部分系統(tǒng)來(lái)說(shuō),總分對(duì)賬沒(méi)有差錯(cuò)就不用進(jìn)行明細(xì)對(duì)賬了。
如果發(fā)現(xiàn)總分對(duì)賬有差錯(cuò),就需要進(jìn)行明細(xì)對(duì)賬,將具體差錯(cuò)信息找出來(lái)。明細(xì)對(duì)賬,顧名思義就是將發(fā)生的每一筆交易的詳細(xì)信息和交易通道的對(duì)賬文件進(jìn)行逐筆核對(duì),找出是否有不一致的交易。
(圖1 賬戶總余額連續(xù)性公式)
對(duì)于有虛擬賬戶的對(duì)賬,還需要每個(gè)清算日對(duì)賬戶金額進(jìn)行核驗(yàn)檢查。核驗(yàn)主要包括兩部分:一是賬戶總余額金額連續(xù)性檢查,如圖1公式所示;二是記賬準(zhǔn)確性檢查。
對(duì)賬常見問(wèn)題及處
(圖2 對(duì)賬鏈路示意圖)
對(duì)賬一般都是以一方為對(duì)賬基準(zhǔn)進(jìn)行軋賬,出現(xiàn)差錯(cuò)時(shí),通過(guò)各種差錯(cuò)交易。以基準(zhǔn)方為準(zhǔn)進(jìn)行處理,最終達(dá)到平賬。
對(duì)賬的系統(tǒng)順序:首先是金融交易最底層的銀行內(nèi)部進(jìn)行對(duì)賬以及平賬處理,處理完畢后出具對(duì)賬文件;和銀行直接對(duì)接的第三方支付機(jī)構(gòu)依此對(duì)賬文件進(jìn)行對(duì)賬軋賬,發(fā)現(xiàn)差錯(cuò)時(shí),進(jìn)行平賬處理;依次往上,直到真正業(yè)務(wù)場(chǎng)景的用戶。
從中可以發(fā)現(xiàn),離用戶越近的系統(tǒng)拿到對(duì)賬文件的時(shí)間越晚,等最終整個(gè)業(yè)務(wù)場(chǎng)景鏈對(duì)完賬,時(shí)間就比較晚了,比如 T+2、T+3,甚至更晚。典型的如消費(fèi)金融公司,和支付渠道、合作方對(duì)完賬,加上平賬處理,基本T+2之后了,如圖2所示。。
(圖3 清算周期時(shí)間切分點(diǎn)示意圖)
由于對(duì)賬都是基于一個(gè)清算周期,清算周期就涉及到一個(gè)時(shí)間切分點(diǎn),對(duì)賬系統(tǒng)幾乎都會(huì)碰到時(shí)間差問(wèn)題。大部分系統(tǒng)都以一個(gè)自然日的起始,也就是0點(diǎn)到24點(diǎn)為清算日,但也有比較特殊的清算日規(guī)則,比如銀聯(lián)和銀行之間的清算日是前一日的23點(diǎn)至當(dāng)天的23點(diǎn)為一個(gè)清算日。
以0至24點(diǎn)一個(gè)清算日為例,0點(diǎn)為切分點(diǎn),本系統(tǒng)發(fā)起的交易,到支付通道側(cè),可能已經(jīng)是下一個(gè)清算日,從支付渠道自身來(lái)看,本筆交易會(huì)在第二天的對(duì)賬文件出現(xiàn),而不是前一個(gè)清算日。
如圖3所示。對(duì)于這種切分點(diǎn)時(shí)間附近無(wú)法確認(rèn)的交易,需要做一個(gè)時(shí)間窗口,時(shí)間窗口內(nèi)的時(shí)間比清算日開始早一些、比清算日結(jié)束晚一些。
聯(lián)機(jī)交易一般有嚴(yán)格的時(shí)間要求,比如必須在幾秒內(nèi)應(yīng)答完畢,大于幾秒就會(huì)造成客戶體驗(yàn)差,流失大量客戶。
而對(duì)賬是典型的批量處理任務(wù),幾秒或者幾分鐘完成沒(méi)有太大影響,但也不代表時(shí)間太長(zhǎng),幾個(gè)小時(shí)就明顯太長(zhǎng),會(huì)嚴(yán)重影響賬務(wù)問(wèn)題,無(wú)法開展日常業(yè)務(wù)。
對(duì)賬是典型的批量處理任務(wù),需要批量調(diào)度平臺(tái)進(jìn)行調(diào)度。對(duì)于比較復(fù)雜的調(diào)度邏輯(比如依賴關(guān)系調(diào)度、靈活觸發(fā)、運(yùn)營(yíng)界面等),需要高可用、高并發(fā)、高伸縮的分布式調(diào)度系統(tǒng),可以考慮用Zeus、Quarts、Elastic-Job、Azkaban等進(jìn)行定制化開發(fā)。
下面重點(diǎn)介紹一下明細(xì)對(duì)賬以及技術(shù)實(shí)現(xiàn)方案。
(圖4 明細(xì)對(duì)賬總體流程)
明細(xì)對(duì)賬的總體流程如圖4所示,包括對(duì)賬文件下載、文件預(yù)處理、軋賬、平帳,以及運(yùn)營(yíng)平臺(tái)對(duì)平帳過(guò)程的監(jiān)控、預(yù)警,下面進(jìn)行詳細(xì)介紹。
對(duì)賬文件下載
對(duì)賬文件一般由對(duì)賬對(duì)手方根據(jù)數(shù)據(jù)庫(kù)的交易記錄產(chǎn)生,并放置和對(duì)賬方約定的地方,比如文件服務(wù)器、FTP服務(wù)器等。對(duì)賬方根據(jù)事先約定的方式,獲取對(duì)賬文件,比如通過(guò)HTTP/HTTPS下載或者FTP/SFTP拉取。
對(duì)賬預(yù)處理
為了安全性、客戶保密性、防篡改,會(huì)對(duì)對(duì)賬文件進(jìn)行加密處理,常用的有3DES、AES等對(duì)稱加密或者RSA非對(duì)稱加密,以及MD5、SHA1、SHA512等摘要信息,還有各種簽名機(jī)制。
獲取到對(duì)賬文件后,并不能立即進(jìn)行對(duì)賬,需要首先按特定安全機(jī)制進(jìn)行解密,另外也需要把對(duì)賬文件格式轉(zhuǎn)換成內(nèi)部系統(tǒng)方便處理的格式。這些都是軋賬前的預(yù)處理。
軋帳
(圖5 代收交易軋帳示意圖)
軋帳是會(huì)計(jì)科目流程之一,定期或者企業(yè)需要時(shí),核對(duì)總賬與明細(xì)賬,每日記賬是否一致。軋帳是對(duì)賬最核心的流程,用來(lái)確認(rèn)雙方或多方的賬目是否一致,不一致的情況下,有哪些差錯(cuò)。
軋帳的正確與否,影響到后續(xù)的差錯(cuò)處理即平帳。以向用戶代收為例,軋帳的流程如圖5所示。
為了確認(rèn)交易記錄的標(biāo)準(zhǔn),需要雙方約定,哪個(gè)或者哪些要素可以唯一確定一筆交易,比如訂單號(hào),有時(shí)也會(huì)加上時(shí)間。
在具體對(duì)賬的內(nèi)容上,一般只需比對(duì)金額即可,某些情況下為了完備性,還會(huì)校對(duì)清算日、客戶信息等其他明細(xì)數(shù)據(jù)。
某些非金額因素會(huì)影響到傭金計(jì)算、多方分潤(rùn)等,所以也需要進(jìn)行軋賬確認(rèn)。
技術(shù)是為商業(yè)目標(biāo)服務(wù),業(yè)務(wù)發(fā)展到什么規(guī)模,就有什么樣的技術(shù)與之匹配。所以,對(duì)賬系統(tǒng)沒(méi)有標(biāo)準(zhǔn)完美的技術(shù)解決方案,不同的業(yè)務(wù)場(chǎng)景會(huì)有不同的特性需求。
盡管行業(yè)、業(yè)務(wù)規(guī)模不同導(dǎo)致技術(shù)方案有一定的差異性,但是差異是相對(duì)的,其中還有很多共性。下面所討論的軋賬技術(shù)方案是較通用的,當(dāng)然還有很多技術(shù)細(xì)節(jié),不展開討論。
依次讀取預(yù)處理后的對(duì)賬文件,根據(jù)交易標(biāo)識(shí)在數(shù)據(jù)庫(kù)中找出對(duì)應(yīng)的記錄,進(jìn)行比對(duì),檢查是否一致。
此種軋帳的方式非常簡(jiǎn)單,容易理解,程序?qū)崿F(xiàn)也比較簡(jiǎn)單。缺點(diǎn)也顯而易見,支持?jǐn)?shù)據(jù)量少,如果交易量大,會(huì)導(dǎo)致內(nèi)存不足,并且大量數(shù)據(jù)庫(kù)查詢,會(huì)耗盡數(shù)據(jù)庫(kù)資源,對(duì)聯(lián)機(jī)交易有影響。
另外,因?yàn)槭谴刑幚恚诮灰琢看髸r(shí),會(huì)大大延長(zhǎng)軋帳時(shí)間,影響正常業(yè)務(wù)的進(jìn)行。
改進(jìn)措施
將對(duì)賬文件按一定規(guī)則劃分為小文件,確保每次只處理記錄數(shù)有限的文件;
按對(duì)賬文件的記錄數(shù)進(jìn)行劃分,由不同的節(jié)點(diǎn)進(jìn)行處理,比如1-n由節(jié)點(diǎn)1處理,(n+1)-2n由節(jié)點(diǎn)2處理,(i-1)n+1-i*n由節(jié)點(diǎn)i處理,…充分利用分布式系統(tǒng)進(jìn)行處理;
為了減少對(duì)聯(lián)機(jī)交易的影響,可以在日切之后將交易記錄導(dǎo)入到專門的對(duì)賬庫(kù)或者歷史庫(kù)進(jìn)行對(duì)賬;
在數(shù)據(jù)庫(kù)中,新增和對(duì)賬文件結(jié)構(gòu)一致的對(duì)賬表,將預(yù)處理后的對(duì)賬文件按記錄逐條導(dǎo)入到對(duì)賬表中。利用數(shù)據(jù)庫(kù)提供的join, left join,right join, case when等SQL語(yǔ)法進(jìn)行軋帳。
比如SQL:select case when a.amt<>b.amt then 1 else 0 end from a join b on a.order_no=b.order_no,可以把金額不一致的找出來(lái)。
select case when a.amt is null then 1 else 0 end from a join b on a.order_no=b.order_no,可以把本地系統(tǒng)中不存在的交易的找出來(lái)。其他以此類推,不一一介紹。
這種軋帳邏輯放在數(shù)據(jù)庫(kù),簡(jiǎn)單方便,后續(xù)方便擴(kuò)展;對(duì)賬對(duì)手方的數(shù)據(jù)都存儲(chǔ)在數(shù)據(jù)庫(kù),可以非常容易可視化和排查問(wèn)題。
缺點(diǎn)是:交易量大時(shí),導(dǎo)入量大,數(shù)據(jù)預(yù)熱慢,數(shù)據(jù)庫(kù)性能很容易成為瓶頸;所有的計(jì)算節(jié)點(diǎn)集中于數(shù)據(jù)庫(kù),無(wú)法利用分布式。
改進(jìn)措施
批量導(dǎo)入數(shù)據(jù)庫(kù);
根據(jù)軋帳標(biāo)識(shí)進(jìn)行分表分庫(kù)處理,并進(jìn)行匯總。
Redis是高性能的key-value數(shù)據(jù)庫(kù),支持5種基本類型(String, List, Set, ZSet, Hash)以及5種基本類型的擴(kuò)展。對(duì)于Set數(shù)據(jù)類型,天然的支持交集、差集、并集等集合運(yùn)算。
將預(yù)處理過(guò)的對(duì)賬文件按軋帳標(biāo)識(shí)和比對(duì)元素加載到Redis的一個(gè)Set A,本系統(tǒng)的交易記錄也一并加載到Redis的另外一個(gè)Set B。Set A和Set B的交集即為對(duì)賬對(duì)平的交易。
Set A-Set B差集并不是多的記錄,還需要將每個(gè)元素和Set B-Set A的差集進(jìn)行查找,如果有軋帳標(biāo)識(shí)一樣但比對(duì)元素不一樣的,即為差錯(cuò)交易;如果沒(méi)有軋帳標(biāo)識(shí)一樣的元素,才能判斷是多的記錄。同理,可以找出少的記錄。
這種借助于Redis軋帳,是一種純內(nèi)存計(jì)算,預(yù)熱快,速度快,充分利用Redis的成熟計(jì)算類型,沒(méi)有復(fù)雜的程序邏輯處理,避免出錯(cuò)。但缺點(diǎn)是計(jì)算機(jī)內(nèi)存有限,不能支持海量對(duì)賬數(shù)據(jù)。
改進(jìn)措施
按一定規(guī)則,進(jìn)行數(shù)據(jù)分片,不同的數(shù)據(jù)按照軋賬標(biāo)識(shí)分片到不同的Redis,最后再進(jìn)行匯總,但同時(shí)也增加了軋帳復(fù)雜性。
如果把軋帳進(jìn)行數(shù)學(xué)模型抽象的話,可以抽象為一個(gè)典型的算法問(wèn)題:構(gòu)建2個(gè)無(wú)重復(fù)元素的集合,按照一定比對(duì)規(guī)則找出2個(gè)集合的差集、交集,對(duì)差集和交集的元素屬性進(jìn)行計(jì)算比對(duì),找出差異性。
通過(guò)抽象后,我們可以看出,有很多實(shí)現(xiàn)方法,比如Java JDK提供的集合計(jì)算Collections、擅長(zhǎng)搜索的Elastic Search等。
這種實(shí)現(xiàn)方式需要視具體情況進(jìn)行分析,有些實(shí)現(xiàn)需要花大量的時(shí)間和邏輯在數(shù)據(jù)預(yù)熱上,有些實(shí)現(xiàn)會(huì)導(dǎo)致匯總數(shù)據(jù)的邏輯復(fù)雜化。
總之,對(duì)賬系統(tǒng)涉及公司的賬務(wù)會(huì)計(jì)核心,盡早建立完備的對(duì)賬系統(tǒng),可以推動(dòng)更加精細(xì)化掌握業(yè)務(wù)情況,特別是互聯(lián)網(wǎng)金融公司。
在對(duì)賬系統(tǒng)落地時(shí),可以綜合考慮本文提出的方案,找出適合公司業(yè)務(wù)發(fā)展的技術(shù)方案,盡量使用成熟技術(shù)解決業(yè)務(wù)問(wèn)題,減少技術(shù)風(fēng)險(xiǎn)性。
本文的下半部分將講述如何處理海量數(shù)據(jù)的對(duì)賬,以及平帳/差錯(cuò)處理和虛擬賬戶對(duì)賬,敬請(qǐng)期待。
作者介紹
王興建
現(xiàn)任上海秦蒼(買單俠)信息科技有限公司軟件架構(gòu)師,加入秦蒼之前,曾在中國(guó)銀聯(lián)、證通任職。
專注于Java Core、NoSQL、分布式服務(wù)框架等技術(shù)領(lǐng)域,對(duì)移動(dòng)支付、客戶認(rèn)證、紅包、虛擬賬戶、信貸等業(yè)務(wù)領(lǐng)域有豐富的經(jīng)驗(yàn),擅長(zhǎng)將成熟技術(shù)應(yīng)用于業(yè)務(wù)。
目前主要負(fù)責(zé)秦蒼運(yùn)營(yíng)商合作業(yè)務(wù)的架構(gòu)設(shè)計(jì),以及技術(shù)在業(yè)務(wù)中的落地工作。
總結(jié)
以上是生活随笔為你收集整理的通用对账系统介绍与设计(上)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 测试效果
- 下一篇: 双系统如何正确的使用修复BCD工具分享