【发布时间】:2017-03-28 19:20:04
【问题描述】:
我有一个有 1000 个分区和 1 个副本的有状态服务。
RunAsync 方法中的这个服务有一个无限循环,我调用一个可靠队列来获取消息。 如果没有消息我等待 5 秒,然后重试。 我曾经使用 Azure 存储队列成功地做到了这一点。
但是使用 Service Fabric,我收到了数千个 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) 并且出现了数千个“任务已取消”错误。
我在这里缺少什么? 是周期太快,SF无法及时更新其他副本? 我应该删除所有副本,只留下一个吗?
我应该改用新的 ConcurrentQueue 吗?
我在生产和本地有 50 或 1000 个分区的问题,没关系。
我陷入困境和困惑。 谢谢
【问题讨论】: