我有一个有1000个分区和1个副本的有状态服务。
RunAsync方法中的这个服务有一个infinte while循环,我调用Reliable Queue来获取消息。 如果没有消息我等待5秒钟,然后重试。 我曾经使用Azure存储队列成功完成了这项工作。
但是,随着Service Fabric I成千上万的 FabricNotReadableExceptions ,服务变得不稳定,我无法更新或删除它,我需要取消整个群集。 我试图更新它,18小时后它仍然卡住了,所以我正在做的事情有一些非常错误。
这是方法代码:
public async Task<QueueObject> DeQueueAsync(string queueName)
{
var q = await StateManager.GetOrAddAsync<IReliableQueue<string>>(queueName);
using (var tx = StateManager.CreateTransaction())
{
try
{
var dequeued = await q.TryDequeueAsync(tx);
if (dequeued.HasValue)
{
await tx.CommitAsync();
var result = dequeued.Value;
return JSON.Deserialize<QueueObject>(result);
}
else
{
return null;
}
}
catch (Exception e)
{
ServiceEventSource.Current.ServiceMessage(this, $"!!ERROR!!: {e.Message} - Partition: {Partition.PartitionInfo.Id}");
return null;
}
}}
这是RunAsync
protected override async Task RunAsync(CancellationToken cancellationToken)
{
while (true)
{
var message = await DeQueueAsync("MyQueue");
if (message != null)
{
//process, takes around 500ms
}
else
{
Thread.Sleep(5000);
}
}
}
我还使用Task.Delay更改了Thread.Sleep(5000)并且有数千个&#34;任务被取消&#34;错误。
我在这里失踪了什么? 周期太快,SF无法及时更新其他副本? 我应该删除只留下一个副本的所有副本吗?
我应该使用新的ConcurrentQueue吗?
我在生产中遇到问题,在本地有50或1000个分区,这没什么关系。
我很困惑和困惑。 感谢答案 0 :(得分:0)
您需要遵守传递到cancellationToken
实施的RunAsync
。 Service Fabric会在出于任何原因(包括升级)停止服务时取消令牌,并且在取消令牌后它将无限期地等待RunAsync
返回。这可以解释为什么您无法升级您的应用程序。
我建议您检查循环中的cancellationToken.IsCancelled
,如果已取消,则会发出错误。
FabricNotReadableException
可能由于各种原因而发生 - this question的答案有全面的解释,但外卖是
您可以将FabricNotReadableException视为可重复。如果您看到它,只需再次尝试呼叫,最终它将解析为NotPrimary或Granted。