對賬系統(tǒng)

對賬流程

對賬流程節(jié)點:數(shù)據(jù)抓取、數(shù)據(jù)清洗、對賬、結(jié)果匯總4個操作節(jié)點;

對賬結(jié)果:上游單邊(訂單上游存在,下游不存在)、下游單邊、金額不一致(上下游訂單都存在,但是金額不同);

對賬操作節(jié)點功能簡介

  • 數(shù)據(jù)抓?。豪〈龑~業(yè)務(wù)數(shù)據(jù),生成原始憑證數(shù)據(jù);
  • 數(shù)據(jù)清洗:原始憑證數(shù)據(jù)清洗,生成對賬憑證數(shù)據(jù);
  • 對賬:對賬憑證對賬,記錄對賬結(jié)果;
  • 匯總:對賬結(jié)果匯總;

系統(tǒng)設(shè)計需要處理的問題

  • 數(shù)據(jù)量較大時,要分組處理;
  • 數(shù)據(jù)分組時,避免相同單號的分到不同的組,導(dǎo)致數(shù)據(jù)單邊;
  • 應(yīng)用多實例部署,避免多實例并發(fā)沖突,避免數(shù)據(jù)重復(fù)處理或數(shù)據(jù)遺漏;
  • 對賬流程,可以個性化配置,不同業(yè)務(wù)需要的對賬流程可以不同;
  • 對賬鏈路中,任意節(jié)點的數(shù)據(jù),都可以沿著對賬鏈路往下執(zhí)行;

系統(tǒng)實現(xiàn)方案

  • 數(shù)據(jù)分表存儲,避免后期數(shù)據(jù)量大了之后再分表時的數(shù)據(jù)遷移問題,并對數(shù)據(jù)進行了分組;
  • 使用task處理方式,結(jié)合分布式定時任務(wù)組件xxljob,避免多實例沖突及數(shù)據(jù)重復(fù)處理問題(按表維度創(chuàng)建task任務(wù));
  • task處理流程進行模板化,模板方法抽象task處理的公共流程;

使用到的設(shè)計模式

  • 責任鏈模式;
  • 模板模式;

責任鏈模式

  • 對于對賬流程,目前的對賬分為抓取、清洗、對賬、匯總4個功能節(jié)點;
  • 責任鏈模式靈活組裝、增減功能節(jié)點的流轉(zhuǎn)順序和個數(shù);
  • 任意節(jié)點開始,進入鏈路,都可以繼續(xù)鏈路的流轉(zhuǎn)(常規(guī)代碼實現(xiàn)的責任鏈不支持該需求);

模板模式

  • 依賴task觸發(fā)數(shù)據(jù)處理;
  • task控制任務(wù)的并發(fā)處理;

代碼結(jié)構(gòu)

模板模式代碼繼承關(guān)系

  • BaseTask<T>:基礎(chǔ)模板抽象類,描述了Task任務(wù)處理的流程(execute方法),及流程處理過程中的抽象方法;
    • task解鎖方法:unlockTask();
    • task獲取方法:getTasks();
    • task分片方法:currentPartition();
    • task執(zhí)行方法:process();
    • task執(zhí)行前處理方法:beforeProcess();
    • task執(zhí)行后處理方法:afterProcess();
  • BaseExeTask:繼承了基礎(chǔ)抽象類BaseTask,并具體實現(xiàn)了task流程處理過程中的抽象方法(除process()之外的方法);
  • BaseReconcileTask:對賬操作基礎(chǔ)抽象類,其中放置對賬的基礎(chǔ)操作(目前的對賬只一種,所以該類為空);
  • ReconcileDefaultTask:具體對賬實現(xiàn)類,實現(xiàn)process(),對賬邏輯在這里實現(xiàn);

圖中是對賬模塊的繼承關(guān)系

image

責任鏈各節(jié)點核心處理流程介紹

  • 數(shù)據(jù)抓取
    • 提供目標業(yè)務(wù)數(shù)據(jù)分組功能,確定數(shù)據(jù)抓取的范圍,并創(chuàng)建對應(yīng)數(shù)量的task來分組抓取業(yè)務(wù)數(shù)據(jù);
    • 提供目標業(yè)務(wù)數(shù)據(jù)按組抓取功能,每個task可以按照上面的分組信息抓取指定范圍的業(yè)務(wù)數(shù)據(jù);
    • 針對多個對賬目標字段的情況,組裝目標字段為json,便于數(shù)據(jù)清洗時拆分;
  • 數(shù)據(jù)清洗
    • 按照物理表維度創(chuàng)建清洗task,每個task只處理一個物理分表中的數(shù)據(jù);
    • 完成字段調(diào)整映射,統(tǒng)一同一對賬字段名稱,統(tǒng)一方式、渠道、狀態(tài)等屬性值;
    • 對于多個對賬目標字段的情況,拆分一條原始憑證數(shù)據(jù)為多條對賬憑證;
  • 對賬
    • 按照物理表維度創(chuàng)建對賬task,每個task只處理一個物理分表中的數(shù)據(jù);
    • 借助Redis中Set結(jié)構(gòu)的命令:Sdiffstore、Sinterstore函數(shù)實現(xiàn)對賬操作;
  • 對賬匯總
    • 按照物理表維度創(chuàng)建匯總task,每個task只處理一個物理分表中的數(shù)據(jù);
    • 每個task統(tǒng)計完該物理表中的匯總數(shù)據(jù)后,獲取redis鎖,獲取成功后將單個表的匯總結(jié)果插入或更新到對賬匯總表中;

責任鏈task節(jié)點創(chuàng)建及鏈路流轉(zhuǎn)過程介紹

  • 鏈路節(jié)點及節(jié)點的順序信息存儲在數(shù)據(jù)庫中,可以針對每個對賬類型創(chuàng)建一個鏈路,實現(xiàn)對賬流程的高度配置話和自由度;
  • 每次對賬執(zhí)行,創(chuàng)建批次信息,批次信息中記錄當前對賬流轉(zhuǎn)到的節(jié)點及該節(jié)點下創(chuàng)建了多少個task;
  • 任務(wù)開始執(zhí)行,創(chuàng)建批次信息,task讀取到批次信息后,讀取對應(yīng)的鏈路配置信息,開始創(chuàng)建第一個節(jié)點的task數(shù)據(jù),并在批次中記錄節(jié)點類型及對應(yīng)task數(shù)量;
  • 各個節(jié)點對應(yīng)的task定時掃描表中對應(yīng)的task,執(zhí)行各自的任務(wù)(按照目標方法中規(guī)定的流程執(zhí)行);
  • 批次對應(yīng)的task任務(wù)出發(fā)批次執(zhí)行,校驗該批次當前節(jié)點下所有的任務(wù)是否都已經(jīng)執(zhí)行完成,完成后創(chuàng)建下個節(jié)點的任務(wù),未完成則根據(jù)規(guī)則重試;

對賬流程圖

image
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容