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

时间:2017-03-08 22:55:25

标签: c# azure azure-service-fabric

我正在开发一个ServiceFabric场景,我在其中生成一个无状态服务的实例,以便运行某些任务。我正在使用 FabricClient.ServiceManager.CreateServiceAsync 来创建实例,这可以按预期工作。

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

该服务按预期关闭,但我的调试器在此行的 Program.Main 类中停止:

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

没有例外,我可以点击继续,我的应用程序会在发生这种情况后按预期运行。但我必须错过一步才能正常关闭我的服务。是否有“最佳实践”方法来实现这一目标?

我考虑让我的服务请求另一个服务(比如监护人)来处理关闭,但这对我来说似乎太多了。

我的偏好是服务本身应该能够自己处理,除非它当然是一种不好的做法。

更新

我将删除服务移至ManagerService以处理关闭服务,但我的调试器仍然停止在已删除服务的 Program.Main 之前。我还添加了一个截图(下图)。

如果我点击继续,一切都会继续运行。这是因为调试器仍然附加,并且不理解该服务不再在结构下运行?这可以被忽略并投入生产吗?

enter image description here

更新2

我得到了很多反馈,因为我有调试器运行它是预期的行为,一旦我没有在Fabric上运行该特定服务的实例,它就会打嗝。因为如果我从内部或从外部服务中删除服务,我会得到相同的行为,我想对这个场景的最佳实践有所了解......

理想情况下,让服务自身清理是最好的,因为没有外部服务的依赖性,它不那么复杂,编写的代码要少得多(而且不会出错)。

当然,除了必须调用 FabricClient 之外,还有最好的做法吗?是否存在某种“关闭”覆盖? CancellationToken 是否会在这里发挥作用?

3 个答案:

答案 0 :(得分:3)

您所描述的行为是预期的(如果您在main中启动它,那么您的调试器可能始终位于该超时行)。主机进程的生命周期与托管在其中的服务的生命周期不同。

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

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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

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