Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/358.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java QueueClient中的长时间不活动和频繁MessageLockLostException 背景_Java_Azure_Azureservicebus_Messaging - Fatal编程技术网

Java QueueClient中的长时间不活动和频繁MessageLockLostException 背景

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

我们有一个以Azure Service Bus作为消息代理的数据传输解决方案。我们正在通过
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

我们试着做了以下几点-

  • 我们将预取计数(从20*处理率-如最佳实践指南中所述)降至最低(在一个测试周期内甚至
    0
    ),以减少为客户端锁定的消息数量
  • maxAutoRenewDuration
    增加到5分钟-我们的
    processDB1()
    processDB2()
    在几乎90%的情况下不需要超过一两秒钟-因此,我认为30秒的锁定持续时间和
    maxAutoRenewDuration
    在这里不是问题
  • 删除了阻塞
    CompletableFuture.get()
    ,并使处理同步
  • 这些调整都没有帮助我们解决问题。我们观察到,
    COMPLETE
    RENEWMESSAGELOCK
    抛出了
    MessageLockLostException

    我们需要帮助找到以下问题的答案:

  • 为什么在场景1中,
    QueueClient
    长期处于非活动状态
  • 我们如何知道抛出了
    消息LockLostException
    s,因为锁确实已过期
    ?我们怀疑锁不会过早过期,因为我们的处理只需一两秒钟。禁用预取也不能解决这一问题
  • 版本和服务总线详细信息
    • Java-
      openjdk-11-jre
    • Azure服务总线命名空间层:
      Standard
    • Java SDK版本-
      3.4.0

    对于场景1:

    如果已启用,则根据下面解释的场景,可能会发生此行为:

    我已经启用了30秒。我不断用重复的消息点击服务总线(im我的案例消息,来自客户端的消息ID相同-30/分钟)。我将看到该窗口的无活动传出。虽然在servicebus上从发送客户端接收到消息,但我无法在传出消息中看到它们。您可能会检查是否再次遇到已筛选的重复消息,从而导致传出过程中处于不活动状态


    另请注意:创建队列后不能启用/禁用重复检测。只能在创建队列时启用/禁用重复检测。

    对于场景1:

    如果已启用,则有可能根据