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 2024-08-05 14:57  白嫖老郭  阅读(24)  评论(0编辑  收藏  举报

导航