账户系统的具体实现
在上一篇文章中我們通過場(chǎng)景舉例的方式,討論了一套相對(duì)通用的互聯(lián)網(wǎng)業(yè)務(wù)賬戶系統(tǒng),從業(yè)務(wù)模型上應(yīng)該如何定義。那么除了從業(yè)務(wù)模型上進(jìn)行定義外,在具體系統(tǒng)實(shí)現(xiàn)上又該如何設(shè)計(jì)?又有哪些需要注意的地方呢?在本篇內(nèi)容中小碼農(nóng)就和大家一起討論下賬戶系統(tǒng)的實(shí)現(xiàn)細(xì)節(jié),希望可以和大家一起交流進(jìn)步。
事實(shí)上賬戶系統(tǒng)的業(yè)務(wù)邏輯是比較復(fù)雜的,對(duì)數(shù)據(jù)的一致性要求很高,特別是記賬動(dòng)作涉及強(qiáng)事務(wù)特性;另外,性能問題也是常常制約賬戶系統(tǒng)穩(wěn)定性的一個(gè)比較突出的方面。在這種情況下,我們還需要考慮系統(tǒng)的業(yè)務(wù)通用性設(shè)計(jì)問題,而這必然也會(huì)涉及很多配置項(xiàng)的設(shè)計(jì),增加系統(tǒng)的邏輯復(fù)雜度。但是,也只有處理好了這些問題,賬戶系統(tǒng)才能保證業(yè)務(wù)的持續(xù)擴(kuò)張,否則再好的理念也只是空中樓閣。然而,處理好這些復(fù)雜的問題,事實(shí)上并不只是某一點(diǎn)的設(shè)計(jì)就可以達(dá)成的,既需要邏輯流程設(shè)計(jì)上的優(yōu)化,也需要采用合適的技術(shù)方案,更需要一個(gè)合理的系統(tǒng)結(jié)構(gòu)。
下面我們就從系統(tǒng)結(jié)構(gòu)、整體流程、數(shù)據(jù)模型、記賬規(guī)則,以及日終對(duì)賬這幾個(gè)方面與大家探討從系統(tǒng)層面應(yīng)該如何設(shè)計(jì)。另外對(duì)于賬戶系統(tǒng)中制約性能最常見的熱點(diǎn)賬戶問題,也會(huì)和大家一起探討。
系統(tǒng)結(jié)構(gòu)
在之前的內(nèi)容中,我們提到要設(shè)計(jì)一套可以滿足互聯(lián)網(wǎng)業(yè)務(wù)擴(kuò)展的賬戶系統(tǒng),所以賬戶是這套系統(tǒng)的基礎(chǔ),為了更好地支持不同業(yè)務(wù)、或同一業(yè)務(wù)不同賬戶的開戶,我們需要將開戶邏輯設(shè)計(jì)成獨(dú)立的子系統(tǒng),獨(dú)立地提供包括開戶、賬戶信息查詢、余額查詢?cè)趦?nèi)的服務(wù),以便邏輯復(fù)雜到一定階段后可以更容易的擴(kuò)展。在完成開賬戶動(dòng)作后,就需要根據(jù)業(yè)務(wù)規(guī)則,設(shè)計(jì)好邏輯體系下不同交易類型的記賬規(guī)則了,而這種規(guī)則配置是否智能,則是賬戶系統(tǒng)是否通用的關(guān)鍵;配置完規(guī)則后賬戶系統(tǒng)就可以接收業(yè)務(wù)發(fā)起的交易請(qǐng)求,并根據(jù)規(guī)則的配置完成業(yè)務(wù)資金流的處理了,所以,從系統(tǒng)結(jié)構(gòu)層面也需要將記賬核心服務(wù)設(shè)計(jì)成獨(dú)立的子系統(tǒng);此外,為了適配業(yè)務(wù)層不同的交易類型,主要是隔離記賬邏輯與交易邏輯,還需要前置賬戶交易系統(tǒng)。
最后,為了確保賬戶余額與流水之間的平衡,我們還需要在日終時(shí)對(duì)主要資金賬戶進(jìn)行對(duì)賬核算,確保賬戶流水發(fā)生額與賬戶余額的一致性。所以從系統(tǒng)結(jié)構(gòu)層面,整個(gè)系統(tǒng)主要可以分為四個(gè)部分:
之所以在賬戶系統(tǒng)、核心記賬系統(tǒng)之上設(shè)置一層賬戶層交易系統(tǒng),是為了將多變的業(yè)務(wù)交易邏輯與相對(duì)通用的記賬邏輯進(jìn)行隔離,避免在核心記賬系統(tǒng)中冗余過多的業(yè)務(wù)邏輯導(dǎo)致后續(xù)出現(xiàn)臃腫的情況。例如業(yè)務(wù)層的交易類型可能是復(fù)雜多變的,如車費(fèi)充值、押金支付之類,而這樣的邏輯是沒有必要讓記賬系統(tǒng)感知的,記賬系統(tǒng)只需要根據(jù)交易系統(tǒng)傳遞的記賬規(guī)則,根據(jù)會(huì)計(jì)分錄完成資金流處理即可。
?
整體流程
為了確保系統(tǒng)能夠正常Run起來,需要對(duì)系統(tǒng)整體的流程進(jìn)行規(guī)劃,這部分流程即包括線下流程,也包括線上流程,它是確保整個(gè)系統(tǒng)閉環(huán)的基礎(chǔ)。例如,以賬戶系統(tǒng)需要支撐A公司打車業(yè)務(wù)為例,假設(shè)賬戶系統(tǒng)已經(jīng)存在的情況下,那么它需要支撐這個(gè)業(yè)務(wù)應(yīng)該經(jīng)歷以下兩個(gè)階段的流程:
(一)、線下規(guī)劃配置流程
?
按照正常的流程設(shè)計(jì),在業(yè)務(wù)開展之前,需要根據(jù)實(shí)際的業(yè)務(wù)資金流設(shè)計(jì)好具體的賬戶及交易資金邏輯,這部分邏輯一般是由PM與資金部門線下確認(rèn)后形成正式的產(chǎn)品規(guī)格文檔。之后,由具有權(quán)限的運(yùn)營(yíng)人員通過后臺(tái),或者前期在沒有完善配置系統(tǒng)的情況下,由技術(shù)人員初始化到系統(tǒng)中,由于這部分配置關(guān)系到交易核心流程,所以在流程及操作規(guī)范的制定上要嚴(yán)格把控,避免配置錯(cuò)誤導(dǎo)致的嚴(yán)重系統(tǒng)邏輯錯(cuò)亂問題。
在這部分流程中我們首先需要配置業(yè)務(wù)主體,這里需要為A公司配置客戶開戶信息,之后需要按照之前業(yè)務(wù)模型定義的結(jié)構(gòu),在客戶下為其開通表示打車業(yè)務(wù)線網(wǎng)約車用戶,至此在系統(tǒng)中就完成了“誰(shuí)?要干什么?”的定義。而具體“怎么干?”,則是在后面我們要重點(diǎn)配置的內(nèi)容。
那么具體需要配置什么內(nèi)容呢?
因?yàn)?#xff0c;賬戶系統(tǒng)本身是為交易邏輯服務(wù)的,所以我們需要明確業(yè)務(wù)中涉及賬戶邏輯的交易有哪些類型,例如在約車業(yè)務(wù)中主要涉及到司機(jī)端開戶、乘客開戶、現(xiàn)金支付車費(fèi)、余額充值、余額支付車費(fèi)、司機(jī)提現(xiàn)等這些交易類型,所以我們需要為這些交易類型定義交易編碼(tradeCode),并將其與之前開通的網(wǎng)約車業(yè)務(wù)用戶進(jìn)行關(guān)聯(lián),這樣在后續(xù)的系統(tǒng)交易流程中,就可以進(jìn)行交易權(quán)限控制,各業(yè)務(wù)線邏輯各自關(guān)聯(lián)自身的交易類型,以免互相干擾了。
而定義了這些交易類型以后,賬戶層交易系統(tǒng)具體接收到這樣的交易請(qǐng)求后應(yīng)該怎樣執(zhí)行邏輯呢?在互聯(lián)網(wǎng)公司早期業(yè)務(wù)發(fā)展的過程中,很多都是將賬戶邏輯與交易邏輯耦合在一起的,這樣會(huì)導(dǎo)致各個(gè)業(yè)務(wù)賬戶邏輯陷入要么繼續(xù)耦合,要么各自定制、重復(fù)開發(fā)的怪圈。
而要讓這種邏輯變得通用,就需要將其規(guī)則化,即賬戶層交易系統(tǒng)接收到指定的交易請(qǐng)求類型后,會(huì)根據(jù)系統(tǒng)用戶交易規(guī)則配置,獲取開戶、記賬交易規(guī)則信息,然后記賬系統(tǒng)和開戶系統(tǒng)就會(huì)按照規(guī)則指定的邏輯執(zhí)行了,這種執(zhí)行邏輯識(shí)別規(guī)則,不感知具體業(yè)務(wù)邏輯。在上述流程中,我們將“平臺(tái)層開戶”也設(shè)計(jì)成了規(guī)則,只是這種開戶動(dòng)作接口并不對(duì)實(shí)時(shí)交易接口開放,一般是通過后臺(tái)設(shè)置,即通過后臺(tái)調(diào)用開戶系統(tǒng)機(jī)構(gòu)(平臺(tái))開戶接口,開戶邏輯根據(jù)網(wǎng)約車平臺(tái)層開戶規(guī)則,自動(dòng)開立“服務(wù)費(fèi)賬戶”、“代收付平臺(tái)賬戶”、“結(jié)算賬戶”、“市場(chǎng)營(yíng)銷賬戶”這類開展網(wǎng)約車業(yè)務(wù)所需的平臺(tái)層賬戶體系。
其他開戶交易類型,如司機(jī)端開戶、乘客開戶由于需要在具體用戶注冊(cè)、司機(jī)入駐時(shí)通過實(shí)時(shí)交易接口自動(dòng)調(diào)用Api開通,所以這里需要配置好開戶規(guī)則即可;至于,各個(gè)涉及資金變動(dòng)的交易類型,如車費(fèi)支付、余額充值之類,涉及到具體的記賬規(guī)則的邏輯,也需要通過配置相應(yīng)的交易記賬規(guī)則,關(guān)于記賬規(guī)則的配置設(shè)計(jì)涉及一點(diǎn)會(huì)計(jì)知識(shí)的細(xì)節(jié),會(huì)在后面的內(nèi)容中介紹到。
(二)、線上系統(tǒng)交易流程
完成系統(tǒng)級(jí)的數(shù)據(jù)定義及規(guī)則配置后,整個(gè)賬戶系統(tǒng)就會(huì)通過開放Api,為各個(gè)業(yè)務(wù)交易系統(tǒng)提供線上賬戶交易接口服務(wù)了。
?
業(yè)務(wù)層交易系統(tǒng)向賬戶層交易系統(tǒng)發(fā)起交易請(qǐng)求后,系統(tǒng)會(huì)首先根據(jù)傳遞的客戶、用戶ID對(duì)請(qǐng)求權(quán)限進(jìn)行識(shí)別,只有在(一)流程中設(shè)置了客戶、用戶主體信息的交易請(qǐng)求才被允許,之后賬戶層交易系統(tǒng)會(huì)根據(jù)傳遞的交易編碼(tradeCode)識(shí)別交易數(shù)據(jù)開戶交易類型,還是交易記賬類型。開戶交易類型則被轉(zhuǎn)發(fā)至開戶子系統(tǒng)進(jìn)行開戶處理,開戶子系統(tǒng)根據(jù)tradeCode設(shè)置的開戶規(guī)則,完成注冊(cè)用戶賬戶體系的開通,如:乘客張三,會(huì)依次為其開通客戶身份、打車用戶身份、以及打車用戶涉及的余額賬戶,余額返現(xiàn)賬戶,押金賬戶的開通。
而如果為交易記賬類型,假設(shè)這里為乘客使用現(xiàn)金支付車費(fèi),則請(qǐng)求被轉(zhuǎn)發(fā)至記賬子系統(tǒng),記賬子系統(tǒng)根據(jù)業(yè)務(wù)線客戶、用戶ID、乘客業(yè)務(wù)用戶ID以及tradeCode獲取記賬規(guī)則,完成資金邏輯記賬處理。
規(guī)則涉及的賬戶邏輯如下:
?
記賬規(guī)則
在賬戶系統(tǒng)中,記賬規(guī)則邏輯的設(shè)計(jì)是最為復(fù)雜的一項(xiàng)設(shè)計(jì),需要在兼顧會(huì)計(jì)邏輯的情況下,還需要將其設(shè)計(jì)成較為通用的規(guī)則,以上面用戶支付車費(fèi)的賬戶資金邏輯為例,如何將其設(shè)計(jì)成規(guī)則配置呢?
?
在以上記賬規(guī)則表中,定義了業(yè)務(wù)線用戶ID(merchUserId),表示該業(yè)務(wù)模式在系統(tǒng)中的唯一編碼;記賬交易類型(tradeCode)由具體的業(yè)務(wù)線交易模式定義,例如打車業(yè)務(wù)用戶現(xiàn)金支付車費(fèi)。這兩個(gè)字段由定義客戶用戶信息、用戶交易類型,可根據(jù)實(shí)際業(yè)務(wù)定義。
后面的字段主要定義了賬戶交易邏輯的情況,例如changeType中定義的記賬,表示按照規(guī)則正常的借貸方向進(jìn)行余額更新,而凍結(jié)、解凍則是對(duì)賬戶余額進(jìn)行凍結(jié)、解凍操作,增加、減少是根據(jù)規(guī)則直接對(duì)賬戶進(jìn)行增加及減少操作,之所以定義上述不同類型,主要是為了適應(yīng)不同賬戶操作邏輯,具體定義及含義,大家也可以根據(jù)自身公司的實(shí)際業(yè)務(wù)情況進(jìn)行定義。
可能這么解釋大家會(huì)有比較大的疑問,我們以線上交易流程中涉及的網(wǎng)約車用戶現(xiàn)金支付車費(fèi)的資金邏輯為例:
根據(jù)規(guī)則表的設(shè)計(jì),以上規(guī)則描述了各賬戶資金流的變動(dòng)邏輯,其中涉及賬戶類型、借貸方向、資金類型、記賬科目以及記賬步驟。當(dāng)業(yè)務(wù)層交易發(fā)起至賬戶層交易系統(tǒng)后,賬戶層交易系統(tǒng)會(huì)獲取以上記賬規(guī)則,并根據(jù)規(guī)則描述的賬戶類型,找到普通消費(fèi)用戶、平臺(tái)層用戶、普通服務(wù)用戶對(duì)應(yīng)的賬戶信息,并按照規(guī)則逐條進(jìn)行記賬邏輯執(zhí)行。
通用數(shù)據(jù)模型
在上面的流程及規(guī)則涉及中,以網(wǎng)約車業(yè)務(wù)為例,通過兩個(gè)流程說明了賬戶系統(tǒng)應(yīng)該如何支撐著項(xiàng)業(yè)務(wù),雖然,看著并不是特別復(fù)雜,但是從系統(tǒng)設(shè)計(jì)上看卻是涉及了很多實(shí)體信息,接下來我們從數(shù)據(jù)建模的角度,看看如何設(shè)計(jì)系統(tǒng)的數(shù)據(jù)模型。
在模型中我們根據(jù)邏輯,抽象了客戶、用戶、賬戶相關(guān)實(shí)體,同時(shí)也抽象了賬戶流水、科目信息、記賬規(guī)則、開戶規(guī)則,交易類型等信息。系統(tǒng)通過這些實(shí)體設(shè)計(jì)相關(guān)表結(jié)構(gòu),系統(tǒng)就初步具備了運(yùn)轉(zhuǎn)能力了,大家可以根據(jù)實(shí)際情況增加其他實(shí)體信息。
會(huì)計(jì)科目
會(huì)計(jì)科目是賬戶系統(tǒng)中比較基礎(chǔ)的概念,它的定義決定了賬戶的一些屬性特征,例如是否可透支,屬于資產(chǎn)類or負(fù)債類,可以根據(jù)不同公司財(cái)務(wù)的需求進(jìn)行設(shè)計(jì)。
記賬策略
大家知道記賬動(dòng)作是強(qiáng)事務(wù)的,按照正常記賬邏輯以上規(guī)則執(zhí)行過程中涉及的4個(gè)賬戶更新需要具有原子性,要么都執(zhí)行成功,要么全部回滾,而對(duì)于普通消費(fèi)賬戶、普通服務(wù)賬戶,這些賬戶都屬于個(gè)人賬戶,在線上實(shí)時(shí)交易中的并發(fā)度是有限的。而對(duì)于平臺(tái)層賬戶,包括代收付賬戶、服務(wù)費(fèi)賬戶等,平臺(tái)所有的交易都涉及這些賬戶的資金變動(dòng),所以如果在某一個(gè)交易過程中對(duì)其加鎖,會(huì)導(dǎo)致該賬戶記錄的加鎖-更新動(dòng)作非常頻繁,成為熱點(diǎn)賬戶,影響系統(tǒng)性能。
所以在規(guī)則中我們加入了是否緩沖記賬的配置,一旦配置為緩沖記賬,則在執(zhí)行該規(guī)則時(shí),只是把該記賬邏輯放入緩沖隊(duì)列的邏輯與其他規(guī)則在一個(gè)事務(wù)中,而具體賬戶更新邏輯則是由緩沖記賬系統(tǒng)完成,該邏輯可設(shè)置為日間完成,或日終完成。
從而緩解熱點(diǎn)賬戶問題導(dǎo)致系統(tǒng)性能瓶頸,但是需要注意,這種方案也對(duì)緩沖記賬邏輯提出了比較高的要求,需要緩沖記賬系統(tǒng)盡量保證記賬動(dòng)作執(zhí)行成功,一旦執(zhí)行失敗前面同步執(zhí)行成功的記賬邏輯回滾起來會(huì)比較麻煩;另外,如果之前的同步記賬邏輯在發(fā)送緩沖隊(duì)列成功后,自身邏輯又失敗了,則需要及時(shí)發(fā)送沖正機(jī)制,取消該緩沖記賬動(dòng)作。
日終對(duì)賬
為了確保賬戶余額始終處于相對(duì)正確地狀態(tài),需要對(duì)日終賬戶流水進(jìn)行各種試算核對(duì),確保所有流水發(fā)生額累加后的余額+期初余額能夠與當(dāng)前余額匹配,這里會(huì)涉及到比較復(fù)雜的對(duì)賬邏輯,需要大家在實(shí)際系統(tǒng)研發(fā)實(shí)踐中加以考慮。
技術(shù)點(diǎn)拓展
在賬戶系統(tǒng)的研發(fā)設(shè)計(jì)過程中,還會(huì)涉及很多其他問題,例如賬戶流水?dāng)?shù)據(jù)量非常大,同時(shí)數(shù)據(jù)的留存時(shí)間又要求比較長(zhǎng),所以需要考慮數(shù)據(jù)的分布式存儲(chǔ),目前小碼農(nóng)所在公司,采用了TIDB這種分布式數(shù)據(jù)庫(kù),大家可在實(shí)踐中根據(jù)自身情況進(jìn)行選擇。
另外,賬戶的頻繁更新,在系統(tǒng)并發(fā)量非常高的情況下,還會(huì)遇到性能瓶頸,如何在保證用戶體驗(yàn)及數(shù)據(jù)正確性的情況下,采取更多的技術(shù)手段,如采用Redis/Codis進(jìn)行緩存記賬,也需要在實(shí)踐應(yīng)用場(chǎng)景中進(jìn)行探索。
后記
由于賬戶系統(tǒng)邏輯相對(duì)比較復(fù)雜,涉及很多會(huì)計(jì)知識(shí)及細(xì)節(jié)邏輯,本文只是描述了一種理念與思路,真正做好這套賬戶系統(tǒng)還需要大家根據(jù)自身場(chǎng)景進(jìn)行取舍與裁剪。由于作者水平有限,不足之處,還請(qǐng)多多包涵!
轉(zhuǎn)摘于:http://www.sohu.com/a/253132589_684445
總結(jié)
- 上一篇: python音标1003python音标
- 下一篇: ORA-02292: 违反完整约束条件