当前位置:网站首页>Record the abnormal task status caused by an MQ concurrent consumption

Record the abnormal task status caused by an MQ concurrent consumption

2022-06-21 23:07:00 sms technonogy

background :

In the project, there is a task of mass sending SMS ( for example 1 Secondary send 1W Short message ), The system will get the information of each SMS in the task MQ Send SMS concurrently . The default status of the task is Not sent ( Status code :0), You need to send the first text message in this batch of tasks , Change the task status to In sending ( Status code :1), Change the status to at the end of task sending Send complete ( Status code :2).

Code processing logic :

The pseudocode is as follows , adopt redis Record how many messages have been sent by the current task , If it's the first one , Update the task status to being sent , If the number of sent tasks is equal to the total number of tasks , Update the status to send complete

Long sendCount = redisTemplate.opsForValue().increment(taskId);
if(sendCount == 1){
   //  The update status is sending  update task set status = 1 where task_id = #{taskId}
}

if(sendCount >= totalCount){
  //  The update status is send complete  update task set status = 2 where task_id = #{taskId}
}

The code says , Two tasks were simply tested , No problem found

problem :

When actually running online , Discover that some tasks are always In sending state , There are no exceptions in the error log , Later, I checked the log and found that there would be problems when the concurrency was high , Suppose this task has 2 Short message , The following conditions will cause the task to be in the sending status all the time :

step The first text message Article 2 SMS Task status
Long sendCount = redisTemplate.opsForValue().increment(taskId); perform Not sent
Long sendCount = redisTemplate.opsForValue().increment(taskId); perform Not sent
sendCount == 1false Not sent
sendCount >= totalCounttrue Send complete
sendCount == 1true In sending
sendCount >= totalCountfalse Not updated

namely , The second message is to judge first if(sendCount >= totalCount) by true, Change the task status to Send complete , Judge the first message again if(sendCount == 1) by true, Change task status from Send complete become In sending , But the first text message judge if(sendCount >= totalCount) by false, Will not change the task status to Send complete , So the task status will always be In sending .

Optimize :

Modification is actually very simple , You only need to update the SMS status to being sent , Add a judgment , The task status is not 2 Can only be updated when .

Long sendCount = redisTemplate.opsForValue().increment(taskId);
if(sendCount == 1){
   //  The update status is sending  update task set status = 1 where task_id = #{taskId} and status <> 2
}

if(sendCount >= totalCount){
  //  The update status is send complete  update task set status = 2 where task_id = #{taskId}
}

原网站

版权声明
本文为[sms technonogy]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/172/202206212118305762.html