代码之家  ›  专栏  ›  技术社区  ›  Nick Randell

Service Fabric可靠的队列长操作

  •  9
  • Nick Randell  · 技术社区  · 10 年前

    我正在尝试了解服务结构的一些最佳实践。

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

    1. 在一个事务中使用TryPeekAsync进行处理,如果成功,则使用TryDequeueAsync最后退出队列。
    2. 使用TryDequeueAsync删除项目,将其放入字典,完成后从字典中删除。启动服务时,检查 队列之前的任何待处理内容的字典。

    两种方式都感觉有点不对,但我无法确定是否有更好的方法。

    2 回复  |  直到 10 年前
        1
  •  14
  •   anderso    10 年前

    一个选项是在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,那么它现在可以成为无状态的。尽管这增加了对第三方服务(在本例中为ServiceBus)的依赖性,但这可能不是您的选择。

    另一种选择是创建一个持久的pub/sub实现来充当队列。我之前做过测试,使用actor进行测试,这似乎是一个可行的选择,不需要花费太多时间,因为依赖ServiceBus我们没有任何问题。这是另一个SO Pub/sub pattern in Azure Service Fabric

        2
  •  3
  •   user1496062    9 年前

    如果速度很慢,请使用两个队列。一个是快速队列,您可以在不中断的情况下存储工作,另一个是慢速队列来处理工作。RunAsync用于将消息从快移到慢。