提供的锁无效。 锁已过期,或者消息已从队列中删除
我正在使用Microsoft azure服务总线队列来处理计算,我的程序可以正常运行几个小时,但后来我开始为我从那时开始处理的每条消息获得此exception。 我不知道从哪里开始,因为前几个小时一切正常。 我的代码似乎也很准确。 我将发布处理azure服务总线消息的方法。
public static async Task processCalculations(BrokeredMessage message) { try { if (message != null) { if (connection == null || !connection.IsConnected) { connection = await ConnectionMultiplexer.ConnectAsync("connection,SyncTimeout=10000,ConnectTimeout=10000"); //connection = ConnectionMultiplexer.Connect("connection,SyncTimeout=10000,ConnectTimeout=10000"); } cache = connection.GetDatabase(); string sandpKey = message.Properties["sandp"].ToString(); string dateKey = message.Properties["date"].ToString(); string symbolclassKey = message.Properties["symbolclass"].ToString(); string stockdataKey = message.Properties["stockdata"].ToString(); string stockcomparedataKey = message.Properties["stockcomparedata"].ToString(); var sandpTask = cache.GetAsync<List>(sandpKey); var dateTask = cache.GetAsync(dateKey); var symbolinfoTask = cache.GetAsync(symbolclassKey); var stockdataTask = cache.GetAsync<List>(stockdataKey); var stockcomparedataTask = cache.GetAsync<List>(stockcomparedataKey); await Task.WhenAll(sandpTask, dateTask, symbolinfoTask, stockdataTask, stockcomparedataTask); List sandp = sandpTask.Result; DateTime date = dateTask.Result; SymbolInfo symbolinfo = symbolinfoTask.Result; List stockdata = stockdataTask.Result; List stockcomparedata = stockcomparedataTask.Result; StockRating rating = performCalculations(symbolinfo, date, sandp, stockdata, stockcomparedata); if (rating != null) { saveToTable(rating); if (message.LockedUntilUtc.Minute <= 1) { await message.RenewLockAsync(); } await message.CompleteAsync(); // getting exception here } else { Console.WriteLine("Message " + message.MessageId + " Completed!"); await message.CompleteAsync(); } } } catch (TimeoutException time) { Console.WriteLine(time.Message); } catch (MessageLockLostException locks) { Console.WriteLine(locks.Message); } catch (RedisConnectionException redis) { Console.WriteLine("Start the redis server service!"); } catch (MessagingCommunicationException communication) { Console.WriteLine(communication.Message); } catch (Exception ex) { Console.WriteLine(ex.Message); Console.WriteLine(ex.StackTrace); } }
更新:我检查锁定到期之前的时间,如果需要它我会调用锁更新,但它更新锁定没有错误,但我仍然得到这个例外。
timeLeft = message.LockedUntilUtc - DateTime.UtcNow; if (timeLeft.TotalMinutes <= 2) { //Console.WriteLine("Renewed lock! " + ((TimeSpan)(message.LockedUntilUtc - DateTime.UtcNow)).TotalMinutes); message.RenewLock(); } catch (MessageLockLostException locks) { Console.WriteLine("Delivery Count: " + message.DeliveryCount); Console.WriteLine("Enqueued Time: " + message.EnqueuedTimeUtc); Console.WriteLine("Expires Time: " + message.ExpiresAtUtc); Console.WriteLine("Locked Until Time: " + message.LockedUntilUtc); Console.WriteLine("Scheduled Enqueue Time: " + message.ScheduledEnqueueTimeUtc); Console.WriteLine("Current Time: " + DateTime.UtcNow); Console.WriteLine("Time Left: " + timeLeft); }
到目前为止我所知道的是我的代码运行良好一段时间并且更新锁被调用并且工作但我仍然得到锁exception并且在该exception中,我输出timeleft并且它随着代码运行而不断增加时差这让我相信锁定到期的时间不会以某种方式改变?
我花了几个小时试着理解为什么我得到MessageLockLostException
。 我的原因是由于AutoComplete默认为true。
如果您要调用messsage.Complete()
(或CompleteAsync()
),则应实例化OnMessageOptions
对象,将AutoComplete
设置为false,并将其传递给OnMessage
调用。
var options = new OnMessageOptions(); options.AutoComplete = false; client.OnMessage(processCalculations, options);
我遇到了类似的问题。 消息正在成功处理,但是当它们完成时,服务总线不再具有有效锁定。 事实certificate我的TopicClient.PrefetchCount太高了。
一旦获取,锁似乎就会在所有预取消息上开始。 如果累积消息处理时间超过锁定超时,则每个其他预取消息都将无法完成。 它将返回服务总线。
在创建客户端订阅时,请尝试使用客户端的OnMessageOptions()自动续订,而不是手动更新锁定,如下所示:
OnMessageOptions options = new OnMessageOptions(); options.AutoRenewTimeout = TimeSpan.FromMinutes(1); try { client = Subscription.CreateClient(); client.OnMessageAsync(MessageReceivedComplete, options); } catch (Exception ex) { throw new Exception (ex); }
- 操作未在分配的00:01:00超时内完成
- 无法将REST API用于Windows Server 1.1的Service Bus(OnPremises)
- 无法使用Microsoft.Azure.ServiceBus连接到Azure ServiceBus
- Service Bus 1.1使用WindowsAzure.ServiceBus dll创建队列
- 为什么手动引发的瞬态错误exception被处理为AggregateException?
- Azure Service Bus – 使用OnMessage()方法接收消息
- 如何在Azure Service Bus主题上删除DeadLetter消息
- Azure Service Bus中死信队列中的邮件是否过期?
- Azure Service Bus中BrokeredMessage主体的编码