Java QueueClient中的长时间不活动和频繁MessageLockLostException 背景
我们有一个以Azure Service Bus作为消息代理的数据传输解决方案。我们正在通过Java QueueClient中的长时间不活动和频繁MessageLockLostException 背景,java,azure,azureservicebus,messaging,Java,Azure,Azureservicebus,Messaging,我们有一个以Azure Service Bus作为消息代理的数据传输解决方案。我们正在通过x队列从x数据集传输数据-以x专用QueueClients作为发送者。有些发件人每两秒钟发布一封邮件,而另一些发件人每15分钟发布一封邮件 数据源端(发送方所在地)的应用程序工作正常,为我们提供了所需的吞吐量 另一方面,我们有一个应用程序,每个队列有一个QueueClient接收器,配置如下: maxConcurrentCalls=1 autoComplete=true(如果接收模式=RECEIVEAND
x
队列从x
数据集传输数据-以x
专用QueueClient
s作为发送者。有些发件人每两秒钟发布一封邮件,而另一些发件人每15分钟发布一封邮件
数据源端(发送方所在地)的应用程序工作正常,为我们提供了所需的吞吐量
另一方面,我们有一个应用程序,每个队列有一个QueueClient接收器,配置如下:
=maxConcurrentCalls
1
=autoComplete
(如果接收模式=true
)和RECEIVEANDDELETE
(如果接收模式=false
)-我们有一些接收器,如果它们意外关闭,将希望保留服务总线队列中的消息PEEKLOCK
=maxautronewduration
分钟(所有队列上的锁定持续时间=3
秒)30
- 具有单个线程的执行器服务
MessageHandler
执行以下操作:
public CompletableFuture-onMessageAsync(最终IMessage消息){
//反序列化消息体
final CustomObject CustomObject=(CustomObject)SerializationUtils.deserialize((字节[])message.getMessageBody().getBinaryData().get(0));
//异步处理processDB1()和processDB2()
最终列表processFutures=新的ArrayList();
processFutures.add(processDB1(customObject));//processDB1()返回布尔值
processFutures.add(processDB2(customObject));//processDB2()返回布尔值
//将两个completablefutures连接起来以获得结果布尔值
List results=CompletableFuture.allOf(processFutures.toArray(新的CompletableFuture[processFutures.size()])。然后应用(future->processFutures.stream())
.map(CompletableFuture::join).collect(Collectors.toList())
if(results.contains(false)){
//如果结果包含false,则显示死信消息
返回getQueueClient().deadLetterAsync(message.getLockToken());
}否则{
//否则,请完成此消息
getQueueClient().completeAsync(message.getLockToken());
}
}
我们使用以下场景进行了测试:
场景1-接收模式=RECEIVEANDDELETE
,消息发布速率:30/分钟
预期行为
消息应该以恒定的吞吐量连续接收(不一定是消息发布的源的吞吐量)
实际行为
我们观察到QueueClient随机长时间处于不活动状态(从分钟到小时不等)没有来自服务总线名称空间的传出消息(在指标图表上观察到),并且在相同的时间段内没有消耗日志
场景2-接收模式=PEEKLOCK
,消息发布速率:30/分钟
预期行为
消息应该以恒定的吞吐量连续接收(不一定是消息发布的源的吞吐量)
实际行为
在应用程序运行20-30分钟后,我们不断看到MessageLockLostException
我们试着做了以下几点-
0
),以减少为客户端锁定的消息数量maxAutoRenewDuration
增加到5分钟-我们的processDB1()
和processDB2()
在几乎90%的情况下不需要超过一两秒钟-因此,我认为30秒的锁定持续时间和maxAutoRenewDuration
在这里不是问题CompletableFuture.get()
,并使处理同步COMPLETE
或RENEWMESSAGELOCK
抛出了MessageLockLostException
我们需要帮助找到以下问题的答案:
QueueClient
长期处于非活动状态消息LockLostException
s,因为锁确实已过期?我们怀疑锁不会过早过期,因为我们的处理只需一两秒钟。禁用预取也不能解决这一问题- Java-
openjdk-11-jre
- Azure服务总线命名空间层:
Standard
- Java SDK版本-
3.4.0
另请注意:创建队列后不能启用/禁用重复检测。只能在创建队列时启用/禁用重复检测。对于场景1: 如果已启用,则有可能根据