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);
}
}
作者:隔壁老郭
个性签名:独学而无友,则孤陋而寡闻。做一个灵魂有趣的人!
如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!
Java入门到入坟
万水千山总是情,打赏一分行不行,所以如果你心情还比较高兴,也是可以扫码打赏博主,哈哈哈(っ•̀ω•́)っ✎⁾⁾!