我有一个Service Fabric无状态服务,该服务作为后台作业运行并从队列中读取。对于收到的每条消息,它都会调用一个外部API。
如果外部呼叫的故障率很高,我想关闭该服务的特定实例。如果我无法处理消息,则不想从队列中读取消息。
从RunAsync()方法关闭实例的最佳方法是什么?我抛出OperationCanceledException来关闭实例,但这是正确的方法吗?
protected override async Task RunAsync(CancellationToken cancellationToken)
{
while (true)
{
cancellationToken.ThrowIfCancellationRequested();
if (/* error rate is high*/)
{
throw new OperationCanceledException();
}
await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken);
}
}
答案 0 :(得分:1)
关闭服务实例将无法解决您的问题。
主要是因为服务关闭时,SF会在没有SF请求的情况下再次将其重新启动(重新启动),并且服务将在不到一分钟的时间内开始处理消息。因此,关闭服务将无法解决问题。
处理服务中的这些失败的最佳方法是实施重试/后退/断路器策略,以在尝试之间留出更多时间,或者设置一个标志来暂停处理直到特定时间。
另一种选择是实施监视服务,该服务会在发生这些问题时删除服务,这实际上具有您期望的效果,但是可能比仅在代码中实现更复杂,因为您将必须实现在使用该消息的服务中通知时,监视器将监听这些事件,然后与SF联系以关闭该服务,稍后,您还需要重新创建服务以继续处理,除非您确实需要保存分配给该资源的资源。服务,这不会带来比服务中处理更多的好处。
这一切都取决于它的复杂程度。