0

抱歉标题含糊不清,很难解释。我有以下设置:

至于问题。上述解决方案在 1 节点集群上运行良好,但在 5 节点集群上运行时会导致处理“重复”。问题在于,在一个 5 节点集群上,当然有 5 个相同ScheduledTasks的运行,并且都将同时访问FTP上的同一个文件。

我已经意识到这在某种程度上是由于关注点分离不当造成的——也就是 API 不应该对此负责,而是应该由一个完全独立的进程来处理这个问题。

这让我想到了 Service Fabric 支持的不同服务(有状态、无状态、Actor 和 Hosted Guest Exe)。Actor似乎是唯一一个运行单线程的,即使在 5 节点集群上也是如此。此外, anActor似乎不太适合这种情况,因为它需要被触发。就我而言,我基本上需要一个按计划一直运行的守护进程。如果我没记错的话,其他有状态/无状态服务也将使用 5 个“克隆”运行,并且只会导致与我目前遇到的相同问题。

我想我的问题是:如何使用Service Fabric进行高效的后台处理并避免这些多线程/重复问题?提前感谢您的任何意见。

4

1 回答 1

1

在服务 farbic 中,您有 2 个演员选项:

您可以使用状态来确定参与者是否已处理您的 ftp 文件。

看看这篇博文,看看他们如何使用每 30 秒运行一次的提醒。

重要的是,您的 actor 中的代码允许reantrancy。基本上因为演员是可靠的,你的代码可能会被多次执行并在执行过程中被取消。

而不是这样做:

public void Method()
{
    _ftpService.Process(file);
}

考虑这样做:

public void Method(int fileId)
{
    if (_ftpService.IsNotProcessed(fileId))
    {
        _ftpService.Process(file);
        _ftpService.SetProcessed(fileId);
    }
}

如果您的演员在处置时遇到问题,您可能需要检查您是否在代码中处理取消令牌。我从来没有遇到过这个问题,但是我们正在使用 autofac,使用Autofac.ServiceFabric来注册我们的演员,RegisterActor<T>()并且我们的大部分逻辑中都有取消令牌。CancellationTokenSource的文档也可以为您提供帮助。例子

public Ctor()
{
    _cancelationTokenSource = new CancellationTokenSource();
    _cancellationToken= _cancelationTokenSource.Token;
}

public async Task SomeMethod()
{
    while(/*condition*/)
    {
       _cancellationToken.ThrowIfCancellationRequested();
       /*Other code*/
    }
}

protected override async Task OnDeactivateAsync()
{
    _cancelationTokenSource.Cancel();
}
于 2020-09-04T10:55:03.177 回答