Service Fabric可靠队列长操作

时间:2016-03-01 22:08:30

标签: azure-service-fabric

我试图了解服务架构的一些最佳做法。

如果我有一个由Web服务或其他机制添加的队列和后端任务来处理该队列,那么在后台处理长时间运行操作的最佳方法是什么。

  1. 在一个事务中使用TryPeekAsync,进程然后如果成功使用TryDequeueAsync最终出列。
  2. 使用TryDequeueAsync删除项目,将其放入字典中,然后在完成后从字典中删除。在启动服务时,请检查 队列前待处理的任何内容的字典。
  3. 两种方式都有点不对劲,但如果有更好的方法,我就无法解决问题。

2 个答案:

答案 0 :(得分:13)

一种选择是在RunAsync中处理队列,类似于:

protected override async Task RunAsync(CancellationToken cancellationToken)
{
    var store = await StateManager.GetOrAddAsync<IReliableQueue<T>>("MyStore").ConfigureAwait(false);
    while (!cancellationToken.IsCancellationRequested)
    {
        using (var tx = StateManager.CreateTransaction())
        {
            var itemFromQueue = await store.TryDequeueAsync(tx).ConfigureAwait(false);
            if (!itemFromQueue.HasValue)
            {
                await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken).ConfigureAwait(false);
                continue;
            }

            // Process item here
            // Remmber to clone the dequeued item if it is a custom type and you are going to mutate it.
            // If success, await tx.CommitAsync();
            // If failure to process, either let it run out of the Using transaction scope, or call tx.Abort();
        }
    }
}

关于克隆已出列项目的评论,如果要改变它,请在此处的“建议”部分下查看: https://azure.microsoft.com/en-us/documentation/articles/service-fabric-reliable-services-reliable-collections/

可靠集合(队列和字典)的一个限制是,每个分区只有1个并行度。因此,对于高活动队列,它可能不是最佳解决方案。这可能是您遇到的问题。

我们一直在做的是在写入量非常低的情况下使用ReliableQueues。对于更高吞吐量的队列,我们​​需要耐用性和规模,我们正在使用ServiceBus主题。这也为我们提供了这样的优势:如果一个服务仅因为具有ReliableQueue而处于Stateful状态,那么它现在可以变为无状态。虽然这会增加对第三方服务(在本例中为ServiceBus)的依赖性,但这可能不适合您。

另一种选择是创建一个持久的pub / sub实现来充当队列。我之前已经完成了使用演员的测试,这似乎是一个可行的选择,没有花太多时间,因为我们根据ServiceBus没有任何问题。这是关于Pub/sub pattern in Azure Service Fabric

的另一个问题

答案 1 :(得分:3)

如果非常慢,则使用2个队列..一个是快速的,您可以在不中断的情况下存储工作,而缓慢的则可以处理它。 RunAsync用于将消息从快速移动到慢速。