c# - 如何避免在 Service Fabric 托管服务中重复后台任务处理?
问题描述
抱歉标题含糊不清,很难解释。我有以下设置:
- 我正在运行托管在 Service Fabric 中的 .NET Core 2.2 Web API。
- 此 API 的部分职责是监视外部 FTP 存储中是否有新的传入文件。
- 每个文件都会触发一个 Mediator
Command
来调用处理逻辑。 - 我已经实现了一个基于https://docs.microsoft.com/en-us/dotnet/architecture/microservices/multi-container-microservice-net-applications/background-tasks-with-ihostedservice和https://docs.microsoft.com/en-us/dotnet/architecture/microservices/multi-container-microservice-net-applications/background-tasks-with-ihostedservice 的混合解决方案:/ /blog.maartenballiauw.be/post/2017/08/01/building-a-scheduled-cache-updater-in-aspnet-core-2.html。本质上,这是在此 API
IHostedService
中注册的实现。Startup.cs
它基本上是一个在进程中运行的后台服务。
至于问题。上述解决方案在 1 节点集群上运行良好,但在 5 节点集群上运行时会导致处理“重复”。问题在于,在一个 5 节点集群上,当然有 5 个相同ScheduledTasks
的运行,并且都将同时访问FTP上的同一个文件。
我已经意识到这在某种程度上是由于关注点分离不当造成的——也就是 API 不应该对此负责,而是应该由一个完全独立的进程来处理这个问题。
这让我想到了 Service Fabric 支持的不同服务(有状态、无状态、Actor 和 Hosted Guest Exe)。Actor
似乎是唯一一个运行单线程的,即使在 5 节点集群上也是如此。此外, anActor
似乎不太适合这种情况,因为它需要被触发。就我而言,我基本上需要一个按计划一直运行的守护进程。如果我没记错的话,其他有状态/无状态服务也将使用 5 个“克隆”运行,并且只会导致与我目前遇到的相同问题。
我想我的问题是:如何使用Service Fabric进行高效的后台处理并避免这些多线程/重复问题?提前感谢您的任何意见。
解决方案
在服务 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();
}
推荐阅读
- javascript - EXACTLY return 语句的工作原理
- c++ - C++ - 散列/映射一个 std::vector
在单个 uint64_t - sql-server - 设置 exec sp_executesql 变量
- spring - Flux 为 StepVerifier 返回未排序的数据
- r - 带有ggplot2的发散堆积条形图:图例中的因子排序问题
- javascript - “npm run build”导致 ETXTBSY: text file is busy 错误
- laravel - Laravel 从没有 id 数组的模型中更新特定数据
- google-colaboratory - 无法导入名称“TextVectorization”
- python - 无法加载动态库“libcuda.so.1”;dlerror:libcuda.so.1:
- amazon-web-services - aws ApiGatewayWebACLAssociation “模型验证失败(#/ResourceArn:预期 minLength:20,实际:10)”