Java基于XXLJOB的定时任务实现阶梯式通知方式

数据库表设计

CREATE TABLE `tx_order_push_info` (
  `order_no` varchar(64) DEFAULT NULL COMMENT '交易单号',
  `order_id` decimal(11,0) DEFAULT NULL COMMENT '交易单Id',
  `push_status` decimal(2,0) DEFAULT NULL COMMENT '推送状态',
  `push_count` decimal(2,0) DEFAULT NULL COMMENT '推送次数',
  `push_address` varchar(255) DEFAULT NULL COMMENT '推送地址',
  `request_body` varchar(1000) DEFAULT NULL COMMENT '推送报文',
  `next_push_time` datetime DEFAULT NULL COMMENT '下次通知时间',
  `mid` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `create_time` datetime DEFAULT NULL COMMENT '录入时间',
  `update_time` datetime DEFAULT NULL COMMENT '修改时间',
  PRIMARY KEY (`mid`),
  KEY `tx_order_push_info_order_no_IDX` (`order_no`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=406 DEFAULT CHARSET=utf8mb4 COMMENT='支付成功推送记录';

xxl-job配置定时任务策略

注意xxl-job在执行定时任务的时候会丢入参数:10/30/60/300/600/1200/1800/3600 阶梯式通知的时间间隔就和他有关系

准备的表tx_order_push_info里面有两个重要的参数:当前通知次数、下次通知时间

所以想要这种阶梯式通知实现--就很简单了:定时任务还是正常的固定每段时间间隔去执行,但是查询需要执行的数据会有当前时间是否大于下次执行时间的条件过滤,只有满足的数据才会被取出来执行。不满足的就不执行

代码实现

@XxlJob("retryPayNotifyExceptionMsg")
    public ReturnT<String> retryPayNotifyExceptionMsg(String params) {
        String[] timeSplit = params.split("/");
        // 当前服务器索引
        int shardIndex = XxlJobContext.getXxlJobContext().getShardIndex();
        // 总服务器数
        int shardTotal = XxlJobContext.getXxlJobContext().getShardTotal();
        OrderPushInfo orderPushInfo = new OrderPushInfo();
        orderPushInfo.setPushStatus(PushStatusEnum.InitLoading.getCode());
        // 分页参数
        PageParameter pageParameter = new PageParameter();
        // 本次任务需要处理的数据等于默认分页大小*调度任务服务器数量
        pageParameter.setPagesize(20);
        pageParameter.setCurrentPage(1);
        List<OrderPushInfo> orderPushInfos = orderPushInfoService.listByPage(orderPushInfo, pageParameter);
        if (CollectionUtils.isNotEmpty(orderPushInfos)) {
            for (OrderPushInfo pushInfo : orderPushInfos) {
                // 分片处理
                if (shardIndex != (pushInfo.getMid() % shardTotal)) {
                    continue;
                }
                handlerRetrySendMsg(pushInfo, timeSplit);
            }
        }
        return ReturnT.SUCCESS;
    }

    private void handlerRetrySendMsg(OrderPushInfo pushInfo, String[] timeSplit) {
        Integer pushCount = pushInfo.getPushCount();
        if (pushCount >= timeSplit.length) {
            // 大于八次---丢弃
            pushInfo.setPushStatus(PushStatusEnum.MaxRetryGiveUp.getCode());
            orderPushInfoService.update(pushInfo);
            return;
        }
        // 发送时间是否符合预期
        Date nextPushTime = pushInfo.getNextPushTime();
        if (nextPushTime.before(new Date())) {
            // 重新发送消息
            pushCount++;
            try {
                Map<String, String> header = new HashMap<>();
                header.put("token", PBECoder.encrypt(token));
                HttpUtil.doPost(pushInfo.getPushAddress(), pushInfo.getRequestBody(), header);
                pushInfo.setPushStatus(PushStatusEnum.Success.getCode());
            } catch (Exception e) {
                log.error(pushInfo.getOrderNo() + "消息通知失败重试---次数" + pushCount);
            }
            pushInfo.setNextPushTime(DateUtil.addDateSecond(new Date(), Integer.parseInt(timeSplit[pushCount - 1])));
            pushInfo.setPushCount(pushCount);
            orderPushInfoService.update(pushInfo);
        }

    }

posted on   白嫖老郭  阅读(48)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
历史上的今天:
2020-08-05 几种排序算法的:性质

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示