从自身内部关闭 Service Fabric 上的 StatelessService 实例的最佳实践

Best practice for shutting down a StatelessService instance on Service Fabric from within itself

我正在处理一个 ServiceFabric 场景,在该场景中我生成了一个无状态服务实例,以便 运行 执行一些任务。我正在使用 FabricClient.ServiceManager.CreateServiceAsync 创建实例,这按预期工作。

一旦我的任务完成,我希望我生成的服务自行关闭,所以我使用 FabricClient.ServiceManager.DeleteServiceAsync.

服务按预期关闭,但是我的调试器在 Program.Main class 这一行停止:

// Prevents this host process from terminating so services keep running.
Thread.Sleep(Timeout.Infinite);

没有例外,发生这种情况后,我可以按预期点击继续和我的应用程序 运行s。但是我必须错过一个步骤才能正确关闭我的服务。有 "Best Practices" 的方法吗?

我考虑过让我的服务请求另一个服务(如保管人)来处理关闭,但这对我来说似乎开销太大。

我的偏好是服务本身应该能够自行处理,除非事实证明这是一种不好的做法。

更新:

我将服务的删除移动到 ManagerService 来处理关闭它,但我的调试器仍然像以前一样在删除服务的 Program.Main 处停止.我还添加了屏幕截图(下方)。

如果我点击继续,一切都会保持 运行ning 正常。这是因为调试器仍处于连接状态并且不了解该服务不再 运行ning 在 fabric 下吗?这可以忽略并发布到生产中吗?

更新 2

我收到很多反馈,因为我有调试器 运行ning,一旦我在结构上没有该特定服务的实例 运行ning,它就会出现预期的行为了。如果我从自身或外部服务中删除服务,我会得到相同的行为,所以我想对这种情况下的最佳实践有一些想法...

理想情况下让服务自行清理是最好的,因为它不依赖于外部服务,它不那么复杂,而且要编写的代码也少得多(也不太容易出错)。

除了必须调用 FabricClient 之外,当然还有执行此操作的最佳实践吗?是否有某种 "Shutdown" 覆盖? CancellationToken 在这里发挥作用吗?

您从外部创建您的服务。从外部删除服务也是有意义的。就个人而言,我会向 "custodian" 发送一条消息,表明服务已完成,可以删除。

我在调试服务结构时遇到过这种情况。通常,当我的调试器连接很长时间时,我会看到这种行为。只要关闭该服务,并且您可以在 DeleteServiceAsync 完成后验证它不再存在,使用 Service Fabric Explorer 站点,应该没问题。

您描述的行为是预期的(如果您在 main 中启动它,您的调试器可能一直处于该超时线上)。宿主进程的生命周期与其内部托管的服务的生命周期不同。

当主机进程为空时,Service Fabric 在关闭它之前会稍等片刻,因为服务主机在生产中通常不会为空,并且它会尝试避免创建和销毁进程的开销(这会减慢后续服务创作)。

默认情况下,Service Fabric 大约每分钟检查一次进程是否为空,然后将其标记为关闭,然后每 10 分钟左右进行一次扫描并关闭空进程,因此您可以看到空进程持续存在大约 11 分钟,如果你的时间恰到好处。