
分布式任务调度在返利平台的应用凌晨T1对账系统的高可靠实现大家好我是省赚客APP研发者微赚淘客在电商返利业务中T1对账是确保平台、用户与上游渠道资金一致性的核心环节。每天凌晨系统需要处理海量的订单数据与各大电商平台进行核对计算最终佣金并完成用户返利结算。这个任务数据量大、时效性要求高、容错性要求严苛任何差错都可能导致资损。本文将分享我们如何利用分布式任务调度框架构建一个高可靠、可扩展的T1对账系统。技术选型为何选择XXL-JOB面对复杂的对账任务我们放弃了传统的cron表达式和单机定时任务选择了功能强大的分布式任务调度平台XXL-JOB。分布式与高可用调度中心Admin和执行器Executor分离调度中心集群部署保证高可用执行器集群部署实现任务的分片处理轻松应对千万级订单。动态分片这是对账系统的核心需求。XXL-JOB支持将一个任务动态分片到多个执行器节点并行处理极大缩短了整体对账时间。可视化管理提供友好的Web界面可以方便地进行任务管理、日志查看、手动触发和监控告警。失败重试与告警内置失败重试机制和邮件告警确保任务异常时能被及时发现和处理。对账任务的核心架构设计整个对账系统分为三个核心步骤数据拉取、订单对账、佣金结算。我们将这三个步骤设计为三个独立的XXL-JOB任务通过任务依赖串联起来保证流程的清晰和可维护性。第一步数据拉取任务该任务负责从上游电商联盟如淘宝联盟、京东联盟拉取前一天的订单报表并存储到我们的数据库中。packagejuwatech.cn.reconciliation.job;importcom.xxl.job.core.biz.model.ReturnT;importcom.xxl.job.core.handler.annotation.XxlJob;importjuwatech.cn.reconciliation.service.DataFetchService;importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Component;/** * 数据拉取任务 * author juwatech.cn */ComponentpublicclassDataFetchJob{privatestaticfinalLoggerloggerLoggerFactory.getLogger(DataFetchJob.class);AutowiredprivateDataFetchServicedataFetchService;XxlJob(dataFetchJobHandler)publicReturnTStringexecute(Stringparam)throwsException{logger.info(T1对账任务启动开始拉取上游订单数据...);try{// 1. 解析参数获取对账日期StringreconcileDateparam;// 格式yyyy-MM-dd// 2. 调用服务层拉取数据dataFetchService.fetchAllPlatformOrders(reconcileDate);logger.info(T1对账任务完成数据拉取成功。);returnReturnT.SUCCESS;}catch(Exceptione){logger.error(T1对账任务失败数据拉取异常。,e);returnReturnT.FAIL;}}}第二步订单对账任务核心分片逻辑这是对账系统最核心的部分。由于订单量巨大我们利用XXL-JOB的分片广播特性将订单按ID取模分片让多个执行器节点并行处理。packagejuwatech.cn.reconciliation.job;importcom.xxl.job.core.biz.model.ReturnT;importcom.xxl.job.core.handler.annotation.XxlJob;importcom.xxl.job.core.context.XxlJobHelper;importjuwatech.cn.reconciliation.model.OrderRecord;importjuwatech.cn.reconciliation.service.ReconciliationService;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Component;importjava.util.List;/** * 订单对账任务 - 支持分片处理 * author juwatech.cn */ComponentpublicclassOrderReconciliationJob{AutowiredprivateReconciliationServicereconciliationService;XxlJob(orderReconciliationJobHandler)publicReturnTStringexecute(Stringparam)throwsException{// 1. 获取分片信息intshardIndexXxlJobHelper.getShardIndex();// 当前分片序号intshardTotalXxlJobHelper.getShardTotal();// 总分片数XxlJobHelper.log(订单对账任务启动当前分片 {}/{},shardIndex,shardTotal);try{// 2. 根据分片信息分页查询待对账的订单intpageSize500;intcurrentPage0;ListOrderRecordorderList;do{// 核心分片逻辑查询 order_id % shardTotal shardIndex 的订单orderListreconciliationService.findOrdersForReconciliation(shardIndex,shardTotal,currentPage,pageSize);// 3. 处理当前批次的订单for(OrderRecordorder:orderList){reconciliationService.processSingleOrder(order);}currentPage;}while(orderList.size()pageSize);XxlJobHelper.log(订单对账任务完成分片 {}/{} 处理完毕。,shardIndex,shardTotal);returnReturnT.SUCCESS;}catch(Exceptione){XxlJobHelper.log(e,订单对账任务失败分片 {}/{} 处理异常。,shardIndex,shardTotal);returnReturnT.FAIL;}}}在ReconciliationService中findOrdersForReconciliation方法的SQL实现是关键-- 在juwatech.cn.reconciliation.mapper.OrderRecordMapper.xml中selectidfindOrdersForReconciliationresultTypejuwatech.cn.reconciliation.model.OrderRecordSELECT*FROMt_order_recordWHEREstatusPENDING_RECONCILEANDDATE(create_time)#{reconcileDate}ANDMOD(order_id,#{shardTotal}) #{shardIndex}LIMIT#{offset}, #{pageSize}/select第三步佣金结算任务当所有订单对账完成后此任务负责计算每个用户的最终返利金额并更新到用户账户中。packagejuwatech.cn.reconciliation.job;importcom.xxl.job.core.biz.model.ReturnT;importcom.xxl.job.core.handler.annotation.XxlJob;importjuwatech.cn.reconciliation.service.SettlementService;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Component;/** * 佣金结算任务 * author juwatech.cn */ComponentpublicclassCommissionSettlementJob{AutowiredprivateSettlementServicesettlementService;XxlJob(commissionSettlementJobHandler)publicReturnTStringexecute(Stringparam)throwsException{StringreconcileDateparam;try{settlementService.settleCommissions(reconcileDate);returnReturnT.SUCCESS;}catch(Exceptione){returnReturnT.FAIL;}}}高可靠性保障幂等性与事务对账任务必须保证幂等性即使因网络抖动等原因被重复执行也不能导致数据错乱。任务幂等在OrderReconciliationJob中我们通过更新订单状态来实现。processSingleOrder方法内部会使用数据库乐观锁或UPDATE ... WHERE statusPENDING来确保一笔订单只被处理一次。数据一致性在CommissionSettlementJob中结算过程必须在数据库事务中进行确保“扣减平台待结算金额”和“增加用户可用余额”这两个操作的原子性。packagejuwatech.cn.reconciliation.service;importjuwatech.cn.reconciliation.mapper.UserAccountMapper;importjuwatech.cn.user.model.UserAccount;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Service;importorg.springframework.transaction.annotation.Transactional;/** * 结算服务 * author juwatech.cn */ServicepublicclassSettlementService{AutowiredprivateUserAccountMapperuserAccountMapper;Transactional(rollbackForException.class)publicvoidsettleCommissions(Stringdate){// 1. 查询所有待结算的用户佣金汇总// ListUserCommissionSummary summaries ...// 2. 遍历并更新用户账户for(UserCommissionSummarysummary:summaries){// 使用乐观锁更新用户余额version字段保证并发安全intupdateduserAccountMapper.addBalanceAndIncrVersion(summary.getUserId(),summary.getAmount(),summary.getVersion());if(updated0){thrownewRuntimeException(结算失败数据版本冲突用户ID: summary.getUserId());}}}}通过XXL-JOB的强大功能和我们精心设计的分片、幂等、事务机制省赚客APP的T1对账系统得以稳定、高效地运行为亿万用户的返利提供了坚实保障。网购领隐藏优惠券闭眼选省赚客APP支持各大主流电商优惠智能查券转链是目前领优惠券拿佣金返利领域绝对的王者。本文著作权归 省赚客app 研发团队转载请注明出处