温馨提示:这篇文章已超过446天没有更新,请注意相关的内容是否还可用!
摘要:在高可用环境中,Kafka消息未按顺序消费的问题引起了广泛关注。该问题主要出现在并发消费场景下,由于消费者处理速度不同步,可能导致消息的消费顺序出现混乱。为解决此问题,可采取优化Kafka配置、提高消费者处理速度、采用分布式队列等措施,确保消息按序消费,提高系统的稳定性和可靠性。
目录
(图片来源网络,侵删)
背景
质检任务是异步执行的,正常情况下任务状态转变是 等待中》运行中》成功(失败),在质量平台生成任务实例后,会把具体的任务sql发送到大数据平台执行,大数据平台会根据任务的执行状态发布相应的kafka消息,正常情况下状态是顺序下发。
在生产环境中突然出现很多任务一直处于运行中状态。
问题排查
1、怀疑大数据平台任务没有正常执行完成,所以任务一直是运行中。
* 在yarn平台以及数据库中,都没有发现正在运行中的质量sql任务。
* 排查质量平台服务器日志,发现某个sqlId的正常kafka消息,包括运行中、成功、失败等消息都有,通过排查,确定大数据平台没问题,任务正常执行,并且正常按顺序给质量平台发了kafka消息。
2、排查质量平台处理kafka消息逻辑。
* kafka按顺序返回了状态,但质量平台没有按顺序消费,查看质量平台的代码,发现存在并发处理的问题。
* 代码分析显示,存在多个线程同时处理kafka消息的情况,如果任务sql执行成功,线程1负责处理待运行任务,线程2处理成功状态,在更新任务状态前,线程1会更新另一张表的状态,耗时可能达到2秒,而线程2在更新状态前会执行一些其他操作,如查询es、查询数据表、发邮件等,耗时可能超过5秒,这种情况下,存在线程2先把任务状态更新成功,然后线程1把状态更新为运行中的可能。
* 对于任务sql执行失败的情况,也存在类似的问题,线程1处理待运行任务,线程2处理失败状态,如果大数据平台改进了代码,发送运行中和运行失败的消息间隔缩短至2秒内,就会出现线程2先把任务状态更新成失败,然后线程1把状态更新为运行中的情况。
问题解决
针对上述问题,解决方案如下:
1、调整更新状态的逻辑,对于运行中状态的任务,先更新sqlId对应的任务状态,然后再更新别的数据表状态。
2、对于更新运行中的状态,不直接更新,可以使用如下SQL语句进行更新:update zyrz set yxzt = '2' where id = 'xxx' and yxzt not in('0','1')
,这样可以避免在任务状态正在被另一个线程更新时产生冲突。
解决方案已经基于您提供的信息进行了分析和整理,实际应用时可能需要根据实际情况进行适当调整。
还没有评论,来说两句吧...