對賬流程
對賬流程節(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