多线程情况下IBMMQ报文丢失原因分析

背景

最近工作中,使用IBMMQ,重启服务时有偶发性的报文丢失情况,应用从队列中获取到了消息,但是线程停止没有处理。

分析

消息处理线程流程:

  1. 判断线程状态是否可用,如果不可用直接返回。
  2. 使用MQQueue.get方法获取消息。
  3. 如果消息为null继续循环;否则判断线程是否可用,可用则进行处理,不可用则产生消息丢失。

服务关闭流程:
1.设置线程状态为不可用
2.睡眠2秒等待线程处理当前内容。
3.线程关闭;tp.shutdown
4. 线程等待结束。tp.awaitTermination(50,SENCONDS)

分析以上过程,发生消息丢弃必为
1.当前线程状态可用
2.获取消息
3.关闭服务:线程不可用
4.关闭服务:睡眠2秒
5.关闭线程
6.处理消息

获取消息与处理消息之间必须大于2s,但是消息获取成功后立即处理,一般情况不会超过2秒。所以将原因定位到获取消息方法中。
分析MQQueue.get方法,如果队列中没有消息,会发生等待,等待时间由参数Wait Interval (-WI)决定。
该参数解析详见IBM官网说明.
在这里插入图片描述

WI参数用来设置适配器等待消息接收的时间。

在这里插入图片描述

参数0:不进行等待
参数S: 一直等待
wait_interval_in_milliseconds:等待时间
默认为每次等待1s
在等待时间内,线程无法停止。

分析代码,发现该参数我们代码默认设置了10s,所以在执行服务关闭流程4时,需要等待获取消息结束。
如果在1s时获取消息,在2s时关闭服务,则在4s时线程关闭,如果在6s时获取到消息,此时线程关闭,则发生消息丢失。

改进

修改IW参数值,设置为1,保证在服务关闭睡眠2s时间段内可以获取消息完成,不影响服务关闭流程。

备注

awaitTermination(s,unit)方法说明:
在单位s时间段内,如果线程全部处理完成,则结束返回true;在单位s时间段内,如果线程未全部处理完成,则继续等待;超过单位s时间后,则返回false。

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值