我使用Microsoft azure服务总线队列来处理计算,我的程序可以正常运行几个小时,但后来我开始为从那时起处理的每条消息都获得此异常。我不知道从哪里开始,因为前几个小时一切正常。我的代码似乎也很准确。我将发布处理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<StockData>>(sandpKey);
var dateTask = cache.GetAsync<DateTime>(dateKey);
var symbolinfoTask = cache.GetAsync<SymbolInfo>(symbolclassKey);
var stockdataTask = cache.GetAsync<List<StockData>>(stockdataKey);
var stockcomparedataTask = cache.GetAsync<List<StockMarketCompare>>(stockcomparedataKey);
await Task.WhenAll(sandpTask, dateTask, symbolinfoTask,
stockdataTask, stockcomparedataTask);
List<StockData> sandp = sandpTask.Result;
DateTime date = dateTask.Result;
SymbolInfo symbolinfo = symbolinfoTask.Result;
List<StockData> stockdata = stockdataTask.Result;
List<StockMarketCompare> 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);
}
到目前为止,我所知道的是我的代码运行一段时间并且更新锁被调用并且有效但我仍然得到锁定异常并且在该异常内部,我输出timeleft并且它不断增加时间代码运行时的差异让我相信锁定到期之前的时间没有以某种方式改变?
答案 0 :(得分:17)
我花了几个小时试着理解为什么我得到MessageLockLostException
。我的原因是由于AutoComplete默认为真。
如果您要打电话给messsage.Complete()
(或CompleteAsync()
),那么您应该实例化一个OnMessageOptions
对象,将AutoComplete
设置为false,然后将其传递给您的{ {1}}致电。
OnMessage
答案 1 :(得分:6)
我遇到了类似的问题。消息正在成功处理,但是当它们完成时,服务总线不再具有有效锁定。事实证明我的TopicClient.PrefetchCount太高了。
看起来锁一旦被取出就会在所有预取消息上开始。如果累积消息处理时间超过锁定超时,则每个其他预取消息都将无法完成。它将返回服务总线。
答案 2 :(得分:0)
在创建客户端订阅时,不要手动更新锁定,而是尝试使用客户端的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);
}
答案 3 :(得分:0)
就我而言,我只是在本地机器上开发 V2,而 V1 已经部署并运行。
由于 V1 部署在 Azure 中(更接近同一队列)并在发布模式下编译(相对于我在调试模式下的本地版本),部署版本总是“赢得”队列资源的并发性。
这就是消息不再在队列中的原因:它被我的代码的部署版本消耗了。我知道它有点愚蠢。
答案 4 :(得分:0)
我花了 2 天的时间来解决类似的问题 - 同样的异常。
这个异常可能有多种原因,我将描述几个可能对你有帮助的配置选项......
在找到正确的值(针对给定系统进行了优化)后,我不再观察到任何问题。