栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

记一次MQ并发消费导致任务状态异常问题

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

记一次MQ并发消费导致任务状态异常问题

背景:

项目中有一个短信群发任务(例如1次要发送1W条短信),系统会获取任务中每一条短信的MQ并发发送短信。任务默认状态是未发送(状态码:0),需要在这一批任务发送第一条短信的时候,将任务状态修改为发送中(状态码:1),在任务发送结束将状态修改为发送完成(状态码:2)。

代码处理逻辑:

伪代码如下,通过redis记录当前任务已发送了多少条,如果是第一条,则将任务状态更新为发送中,如果已发送条数等于任务总条数,将状态更新为发送完成

Long sendCount = redisTemplate.opsForValue().increment(taskId);
if(sendCount == 1){
   // 更新状态为发送中 update task set status = 1 where task_id = #{taskId}
}

if(sendCount >= totalCount){
  // 更新状态为发送完成 update task set status = 2 where task_id = #{taskId}
}

代码这么写,简单测试了两个任务,发现没有问题

问题:

实际线上运行的时候,发现部分任务始终是发送中状态,错误日志也没有异常,后来查日志才发现这种情况在并发比较高的时候会有问题,假设本次任务有2条短信,如下情况会导致任务一直处在发送中状态:

步骤第一条短信第二条短信任务状态
Long sendCount = redisTemplate.opsForValue().increment(taskId);执行未发送
Long sendCount = redisTemplate.opsForValue().increment(taskId);执行未发送
sendCount == 1false未发送
sendCount >= totalCounttrue发送完成
sendCount == 1true发送中
sendCount >= totalCountfalse不更新

即,第二条短信先判断if(sendCount >= totalCount)为true,将任务状态更改为发送完成,第一条短信再判断if(sendCount == 1)为true,将任务状态由发送完成变成发送中,但是第一条短信判断if(sendCount >= totalCount)为false,不会将任务状态变成发送完成,所以任务状态会一直是发送中。

优化:

修改其实很简单,只需要将短信状态更新为发送中的时候,加一个判断,在任务状态不为2的时候才能更新。

Long sendCount = redisTemplate.opsForValue().increment(taskId);
if(sendCount == 1){
   // 更新状态为发送中 update task set status = 1 where task_id = #{taskId} and status <> 2
}

if(sendCount >= totalCount){
  // 更新状态为发送完成 update task set status = 2 where task_id = #{taskId}
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/974237.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号