【服务总线 Azure Service Bus】Service Bus在使用预提取(prefetching)后出现Microsoft.Azure.ServiceBus.MessageLockLostException异常问题
问题描述
Service Bus接收端的日志中出现大量的MessageLockLostException异常。完整的错误消息为:
Microsoft.Azure.ServiceBus.MessageLockLostException: The lock supplied is invalid. Either the lock expired, or the message has already been removed from the queue. Reference:b2b452db-bf32-41c1-8b76-e546fbdc3856, TrackingId:625929b5-7392-4bf2-9beb-63c132837fc8_B0, SystemTracker:nchn-pr-dep-iot-bus:Queue:dep-iot-input-st-output, Timestamp:2020-12-01T06:13:15 |
问题原因
在接收方使用预提取后,Service Bus服务将锁定此次预提取的消息。通过锁定操作,其他接收方则无法接收到此预提取的消息(保持消息唯一消费)。如果接收方在锁定过期之前无法完成此消息,则该消息便对其他接收方可用。
预提取的消息的副本则保留在缓存中。 使用过期的缓存副本的接收方会在尝试完成该消息时接收到一个异常(MessageLockLostException)。
默认情况下,消息锁定在 30 秒后过期。 这一值可延长到 5 分钟。 通常在创建队列时进行设置。 这是队列级别的属性,不能在消息基础上进行更改。如下图中的Message lock duration(可以点击Change Link进行修改).
解决问题
方法一:修改Message Lock Duration的时间长度,最大可以修改到5分钟。
方法二:在设定消息CompleteAsync前,判断时间 message.LockedUntilUtc中的时间是否已经超过了Message Lock Duration,如果消息未到期但即将到期,可通过调用RenewLock,延续和扩展又一默认锁定时间段
if(message.LockedUntilUtc.Minute <= 1)
message.RenewLock();
应用程序可能收到包含到期或即将到期的锁定的消息。 如果是这样,应用程序可能处理该消息,但随后发现,因锁定到期而无法完成处理。 应用程序可查看 LockedUntilUtc 属性(受代理时钟和本地计算机时钟之间的时钟偏差约束)。 如果消息锁定已到期,则应用程序必须忽略该消息,不应对该消息或通过该消息调用任何 API。 如果消息未到期但即将到期,可通过调用 message.RenewLock() 延续和扩展又一默认锁定时间段
如果锁定在预提取缓冲区静默地到期,则视为已放弃该消息,且可再次将消息用于从队列进行检索。 这可能导致将消息提取到预提取缓冲区,并置于末尾。 如果在消息过期期间往往无法使用预提取缓存区,这将导致重复预提取消息,但始终无法将其以可用(有效锁定)状态有效送达,并最终在超出最大传送数后移动到死信队列。
扩展问题
1:既然预提取更快,为何不是默认选项?(https://docs.azure.cn/zh-cn/service-bus-messaging/service-bus-prefetch#if-it-is-faster-why-is-prefetch-not-the-default-option)
预提取可加快消息流程,方法是在应用程序请求消息时及请求消息前,准备好消息用于本地检索。 这种吞吐量提升是应用程序作者不得不明确作出的某种权衡的结果:
通过 ReceiveAndDelete 接收模式,预提取缓存区获取的所有消息在队列中不再可用,仅驻留在内存中预提取缓存区,直到应用程序通过 Receive/ReceiveAsync 或 OnMessage/OnMessageAsync API 接收到它们 。 如果在应用程序接收到消息前终止应用程序,这些消息将丢失,且不可恢复。
在 PeekLock 接收模式下,提取到预提取缓存区的消息将以锁定状态进入缓存区,并且将超时时钟用于锁定计时。 如果预提取缓存区很大,且处理所需时间过长,以致消息锁定在驻留于预提取缓存区,甚至应用程序还在处理消息时就到期,可能出现一些令人困惑的事件要应用程序处理。 如MessageLockLostException
如果消息处理需要高度的可靠性,且处理需要大量精力和时间,则建议谨慎使用或者丝毫不用预提取功能。
如果需要较高吞吐量且消息处理通常比较便宜,则预提取会产生显著的吞吐量优势。
参考资料
Windows Azure MessageLockLostException : https://stackoverflow.com/questions/15303711/windows-azure-messagelocklostexception
使用服务总线消息传递改进性能的最佳实践: https://docs.azure.cn/zh-cn/service-bus-messaging/service-bus-performance-improvements?tabs=net-standard-sdk#prefetching
【服务总线 Azure Service Bus】Service Bus在使用预提取(prefetching)后出现Microsoft.Azure.ServiceBus.MessageLockLostException异常问题的更多相关文章
- The thumbprint of same asymmetric key is not same in 'SQL Server Connector for Microsoft Azure Key Vault' 1.0.4.0 and 'SQL Server Connector for Microsoft Azure Key
https://support.microsoft.com/en-us/help/4470999/db-backup-problems-to-sql-server-connector-for-azur ...
- 通过Microsoft Azure服务设计网络架构的经验分享(转)
原文:http://www.infoq.com/cn/articles/azure-networking-tips 本文从产品设计和架构角度分享了 Microsoft Azure 网络服务方面的使用经 ...
- Microsoft Azure Web Sites应用与实践【1】—— 打造你的第一个Microsoft Azure Website
Microsoft Azure Web Sites应用与实践 系列: [1]—— 打造你的第一个Microsoft Azure Website [2]—— 通过本地IIS 远程管理Microsoft ...
- 使用VNET-to-VNET连接Microsoft Azure国际版和中国版
Microsoft Azure的VNET-to-VNET功能可以实现跨虚拟网络的VPN连接,通过VNET-to-VNET互联的两个虚拟网络可以在同一个订阅下或者隶属不同的订阅,而且可以跨数据中心.这实 ...
- Microsoft Azure Web Sites应用与实践【4】—— Microsoft Azure网站的“后门”
Microsoft Azure Web Sites应用与实践 系列: [1]—— 打造你的第一个Microsoft Azure Website [2]—— 通过本地IIS 远程管理Microsoft ...
- Microsoft Azure Web Sites应用与实践【2】—— 通过本地IIS 远程管理Microsoft Azure Web Site
Microsoft Azure Web Sites应用与实践 系列: [1]—— 打造你的第一个Microsoft Azure Website [2]—— 通过本地IIS 远程管理Microsoft ...
- Microsoft Azure Web Sites应用与实践【3】—— 通过Visual Studio Online在线编辑Microsoft Azure 网站
Microsoft Azure Web Sites应用与实践 系列: [1]—— 打造你的第一个Microsoft Azure Website [2]—— 通过本地IIS 远程管理Microsoft ...
- C# 消息队列-Microsoft Azure service bus 服务总线
先决条件 Visual Studio 2015或更高版本.本教程中的示例使用Visual Studio 2015. Azure订阅. 注意 要完成本教程,您需要一个Azure帐户.您可以激活MSDN订 ...
- 【服务总线 Azure Service Bus】ServiceBus 队列中死信(DLQ - Dead Letter Queue)问题
Azure Service Bus 死信队列产生的原因 服务总线中有几个活动会导致从消息引擎本身将消息推送到 DLQ. 如 超过 MaxDeliveryCount 超过 TimeToLive 处理订阅 ...
随机推荐
- [Luogu P4215] 踩气球 (线段树)
题面 传送门:https://www.luogu.org/problemnew/show/P4215 Solution 这题十分有意思. 首先,我们可以先想想离线做法,因为在线做法可以从离线做法推出. ...
- [游记] 2020ZJOI 爆零记
DAY 0 凌晨一点打完CF,身心俱疲,由于头痛和困意原本可做的E没做出来,懊悔地睡下,竟然又过了一个多小时才睡着? 早上醒来,感觉身体轻飘飘的,("我真的睡过觉了吗")--听说打 ...
- MarkdownPad 2中编辑
一级标题 二级标题 三级标题 四级标题 五级标题 六级标题 #######七级标题 ########八级标题 #!/bin/bash declare -i evenSum=0 declare -i i ...
- 动态链接的PLT与GOT
本文同时发表在https://github.com/zhangyachen/zhangyachen.github.io/issues/147 最近在研究缓冲区溢出攻击的试验,发现其中有一种方法叫做re ...
- n阶行列式的全排列求解(Java)
上一个随笔,我介绍了全排列的递归求解,其中还有排列的逆序数等代码,这次我来介绍如何使用全排列计算行列式的值. 使用全排列求行列式的值,简单的描述就是: 对这个行列式每一行选取一个数,这些数处于行列式的 ...
- layui常用的公共属性
这个是今天看官网是觉得应该很有用的东西,记录在此.位置位于官网页面元素下的HTML规范:常用公共属性中.解释如下: lay-skin=" " 定义相同元素的不同风格,如checkb ...
- php执行exec、xsell_exec命令失败
在php.ini下进行更改 查找disable_function 去掉exec xsell_exec 重启php
- 【JVM第七篇】执行引擎
写在前面的话:本文是在观看尚硅谷JVM教程后,整理的学习笔记.其观看地址如下:尚硅谷2020最新版宋红康JVM教程 执行引擎是Java虚拟机中的核心组成部分. 执行引擎的作用就是解析虚拟机字节码指令, ...
- dp背包 面试题 08.11. 硬币
https://leetcode-cn.com/problems/coin-lcci/ 硬币.给定数量不限的硬币,币值为25分.10分.5分和1分,编写代码计算n分有几种表示法.(结果可能会很大,你需 ...
- gethostname(获取主机名)、gethostbyname(由主机名获取IP地址)
int gethostname(char *name, size_t len);获取本地主机名存入name[len],成功返回0,失败返回-1: struct hostent * gethostbyn ...