本文概述了在节点上激活应用程序时 Azure Service Fabric 中发生的事件, 并介绍了控制行为的各种群集配置。
在继续阅读之前,请确保了解在 Service Fabric 中为应用程序建模中所述的概念及其相互关系。
备注
本文使用了一些专用术语。 除非另有说明:
- “副本”指有状态服务的副本或无状态服务的实例。
- CodePackage 被视为与注册 ServiceType 的 ServiceHost 进程相同。 它承载该 ServiceType 的服务副本。
激活 ApplicationPackage 或 ServicePackage:
- 下载 ApplicationPackage(例如 ApplicationManifest.xml)。
- 设置应用程序的环境。 例如,创建用户。
- 开始跟踪应用程序的停用情况。
- 下载 ServicePackage(例如 ServiceManifest.xml、代码、配置文件和数据包)。
- 设置 ServicePackage 的环境。 例如,设置防火墙并为终结点分配端口。
- 开始跟踪 ServicePackage 的停用情况。
- 启动 CodePackage 的 SetupEntryPoint,并等待其完成。
- 启动 CodePackage 的 MainEntryPoint。
ServiceTypeDisableFailureThreshold
确定允许的激活、下载和 CodePackage 失败的次数。 达到阈值后,系统将安排 ServiceType 列入阻止列表。 第一次激活失败、下载失败或 CodePackage 崩溃会安排将 ServiceType 加入阻止列表。
ServiceTypeDisableGraceInterval
配置确定在节点上将 ServiceType 列入阻止列表之前的宽限间隔。 在此过程中,将并行重试激活、下载和 CodePackage 重启。 例如,重试意味着会安排 CodePackage 在崩溃后再次启动,或者 Service Fabric 将再次尝试下载包。
在 ServiceType 列入阻止列表时,你会看到运行状况错误:'System.Hosting' reported Error for property 'ServiceTypeRegistration:ServiceType'. The ServiceType was disabled on the node.
如果发生以下任何事件,则会在节点上再次启用 ServiceType:
- 激活成功。 如果失败,会达到
ActivationMaxFailureCount
最大重试次数。 - 下载成功。 如果失败,会达到
DeploymentMaxFailureCount
最大重试次数。 - 已崩溃的 CodePackage 会启动并成功注册 ServiceType。
ActivationMaxFailureCount
和 DeploymentMaxFailureCount
是 Service Fabric 在节点上激活或下载应用程序的最大尝试次数。 达到最大值后,Service Fabric 会重新启用 ServiceType 以进行激活。
这些阈值为服务提供了另一种激活机会。 如果激活成功,则问题会自动修复。
新放置或激活的副本可能会触发新的激活或下载操作。 此操作不是成功就是再次使 ServiceType 列入阻止列表。
备注
发生崩溃的 CodePackage 只要不注册 ServiceType 就不会影响 ServiceType。 它只有在承载副本时才会影响 ServiceType。
当 CodePackage 崩溃时,Service Fabric 会使用退避来再次启动它。 无论 CodePackage 是否已向 Service Fabric 运行时注册类型,都将应用退避。
退避值为 Min(RetryTime, ActivationMaxRetryInterval)
。 该值根据 ActivationRetryBackoffExponentiationBase
配置设置在常数、线性或指数量中递增:
- 常数:如果
ActivationRetryBackoffExponentiationBase == 0
,则RetryTime = ActivationRetryBackoffInterval
。 - 线性:如果
ActivationRetryBackoffExponentiationBase == 0
,则RetryTime = ContinuousFailureCount ActivationRetryBackoffInterval
,其中ContinuousFailureCount
是 CodePackage 崩溃或激活失败的次数。 - 指数:
RetryTime = (ActivationRetryBackoffInterval in seconds) * (ActivationRetryBackoffExponentiationBase ^ ContinuousFailureCount)
。
可通过更改值来控制行为。 例如,如果需要多次快速重启尝试,可通过将 ActivationRetryBackoffExponentiationBase
设置为 0
并将 ActivationRetryBackoffInterval
设置为 10
来使用线性值。 因此,如果 CodePackage 崩溃,启动间隔将在 10 秒后。 如果包继续崩溃,则退避将更改为 20 秒、30 秒、40 秒,依此类推,直到 CodePackage 成功激活或 CodePackage 被停用。
出现故障后 Service Fabric 退避(即等待)的最长时间取决于 ActivationMaxRetryInterval
。
如果 CodePackage 崩溃并重新启动,则需要在 CodePackageContinuousExitFailureResetInterval
指定的时间段内保持运行。 此间隔过后,Service Fabric 会将 CodePackage 视为正常。 然后 Service Fabric 将之前的错误运行状况报告覆盖为“正常”,并重置 ContinuousFailureCount
。
如果 CodePackage 保持正常运行,并且预计会注册一个 ServiceType 但却未这样做,那么 Service Fabric 会在 ServiceTypeRegistrationTimeout
后生成一个警告运行状况报告。 报告指示 ServiceType 未在预期的时间内注册。
如果 Service Fabric 在激活过程中发现错误,它始终会使用线性退避,此行为与处理 CodePackage 崩溃的行为相同。 按以下间隔重试后,将放弃激活操作:(0 + 10 + 20 + 30 + 40) = 100 秒。 (第一次重试是即时进行的。)在此序列后,不会重试激活。
最大激活退避可以为 ActivationMaxRetryInterval
。 重试可以为 ActivationMaxFailureCount
。
如果在下载过程中发现错误,Service Fabric 始终会使用线性退避。 按以下间隔重试后,将放弃激活操作:(0 + 10 + 20 + 30 + 40) = 100 秒。 (第一次重试是即时进行的。)在此序列后,不会重试下载。
下载的线性退避等于 ContinuousFailureCount
* DeploymentRetryBackoffInterval
。 最大退避可以为 DeploymentMaxRetryInterval
。 与激活一样,下载操作的重试限制可为 ActivationMaxFailureCount
。
备注
更改这些设置之前,请记住以下示例:
如果 CodePackage 不断地崩溃并退出,则会禁用 ServiceType。 但如果激活配置了快速重启,则 CodePackage 可在 ServiceType 实际列入阻止列表之前启动几次。
例如,假定 CodePackage 启动后将 ServiceType 注册到 Service Fabric,然后崩溃。 在这种情况下,在宿主收到类型注册后,会取消
ServiceTypeDisableGraceInterval
时间段。 此过程可以重复执行,直到 CodePackage 退避到的值大于ServiceTypeDisableGraceInterval
时间段。 然后,ServiceType 将在节点上被列入阻止列表。 将 ServiceType 列入阻止列表所需的时间可能比预期的要长。在激活的情况下,如果 Service Fabric 系统需要在节点上放置一个副本,重新配置代理会要求宿主子系统激活应用程序, 并每隔 15 秒重试激活请求。 (持续时间取决于
RAPMessageRetryInterval
配置设置。)Service Fabric 无法知道 ServiceType 是否已列入阻止列表,除非宿主中激活操作的持续时间长于重试间隔和ServiceTypeDisableGraceInterval
。例如,假设群集的
ActivationMaxFailureCount
设置为 5,ActivationRetryBackoffInterval
设置为 1 秒。 在这种情况下,激活操作将在 (0 + 1 + 2 + 3 + 4) = 10 秒的间隔后放弃。 (第一次重试是即时进行的。)在此序列之后,宿主会放弃重试。 激活操作完成,将不会在 15 秒后重试。Service Fabric 已在 15 秒内用尽了允许的所有重试。 因此,重新配置代理中的每次重试都会在宿主子系统中创建新的激活操作,并且此模式会不断重复。 这样一来,ServiceType 在节点上永远不会被列入阻止列表。 由于 ServiceType 在节点上不会被列入阻止列表,因此不会移动副本或在另一个节点上尝试。
在节点上激活 ServicePackage 时,会跟踪其停用情况。 停用的工作方式有两种:
- 定期停用:每隔
DeactivationScanInterval
秒,系统就会检查是否有从未承载过副本的服务包,并将其标记为要停用的候选项。 - ReplicaClose 停用:如果副本已关闭,Deactivator 会获取
DecrementUsageCount
。 当 ServicePackage 不承载任何副本时,计数为 0;因此 ServicePackage 是停用的候选项。
激活模式确定安排何时停用候选项。 在共享模式下,安排在 DeactivationGraceInterval
后停用候选项。 在独占模式下,安排在 ExclusiveModeDeactivationGraceInterval
后停用它们。 如果在这段时间内进行了新的副本放置操作,则会取消停用。
有关详细信息,请参阅独占模式和共享模式。
下面是定期停用的一些示例:
示例 1:假设 Deactivator 开始扫描的时间为 T (
DeactivationScanInterval
)。 其下次扫描的时间将是 2T。 假设 ServicePackage 的激活时间为 T + 1。 此 ServicePackage 未承载副本,因此需要将其停用。ServicePackage 处于“无副本”状态的时间至少需要为 T 才能成为停用的候选项。 它会在 2T + 1 秒的时候符合停用条件。 因此,在 2T 的时候,扫描时看不到此 ServicePackage 作为停用候选项出现。
下一个停用周期 3T 会安排停用此 ServicePackage,因为此时该包处于“无副本”状态的时间已为 T。
示例 2:假设 ServicePackage 在 T - 1 的时候激活,Deactivator 在 T 的时候开始扫描。ServicePackage 未承载副本。 在 2T 的时候进行下一次扫描时,ServicePackage 会显示为停用候选项,因此系统会安排停用它。
示例 3:假设 ServicePackage 在 T - 1 的时候激活,Deactivator 在 T 的时候开始扫描。ServicePackage 尚未承载副本。 现在会在 T + 1 的时候放置副本。 也就是说,宿主会获得一个
IncrementUsageCount
,这意味着已创建副本。在 2T 的时候,系统不会安排停用此 ServicePackage。 由于该包包含副本,因此停用将遵循 ReplicaClose 逻辑,如本文的下一部分所述。
示例 4:假设你的 ServicePackage 是 10 GB。 由于包很大,因此在节点上下载需要时间。 激活应用程序后,Deactivator 会跟踪其生命周期。 如果
DeactivationScanInterval
设置为较小的值,ServicePackage 可能没有时间在节点上激活,因为下载需要时间。 若要解决此问题,可在节点上提前下载 ServicePackage 或增加DeactivationScanInterval
。
备注
ServicePackage 可以在(DeactivationScanInterval
到 2 * DeactivationScanInterval
) + DeactivationGraceInterval
/ExclusiveModeDeactivationGraceInterval
之间的任何时候停用。
备注
此部分引用以下配置设置:
- DeactivationGraceInterval/ExclusiveModeDeactivationGraceInterval:为 ServicePackage 留出的时间,如果它已承载任意副本,则可在此时间内承载另一个副本。
- DeactivationScanInterval:为 ServicePackage 留出的最小时间,如果它从未承载任何副本(即从未使用过),则可在此时间内承载一个副本。
系统会保留 ServicePackage 保存的副本数。 如果 ServicePackage 保存了一个副本,而该副本处于关闭或故障状态,则宿主会获得一个 DecrementUsageCount
。 打开副本时,宿主会获得一个 IncrementUsageCount
。
减量表示 ServicePackage 承载的副本数已减少一个副本。 当计数降到 0 时,ServicePackage 将被安排停用。 停用的时间将为 DeactivationGraceInterval
/ExclusiveModeDeactivationGraceInterval
。
例如,假设在 T 发生减量,并安排在 2T + X (DeactivationGraceInterval
/ExclusiveModeDeactivationGraceInterval
) 停用。 在这段时间内,如果宿主因为创建了一个副本而获得了一个 IncrementUsage
,则会取消停用。
如果 ServicePackage 传递 DeactivationGraceInterval
/ExclusiveModeDeactivationGraceInterval
并且仍未承载副本,则无法取消停用。 Codepackage 接收 Ctrl + C 处理程序。 因此现在必须完成停用管道才能使进程停止运行。
在该时间内,如果尝试放置同一 ServicePackage 的新副本,则操作会失败,因为进程无法从停用转变为激活。
本节列出了会影响激活和停用的配置默认值。
- ServiceTypeDisableFailureThreshold:默认值:1. 失败计数的阈值,到达此值后,就会通知 FailoverManager 禁用该节点上的服务类型并尝试在另一个节点上放置对象。
- ServiceTypeDisableGraceInterval:默认值:30 秒。 时间间隔,超过该时间间隔后禁用服务类型。
- ServiceTypeRegistrationTimeout:默认值:300 秒。 ServiceType 向 Service Fabric 注册的超时。
- ActivationRetryBackoffInterval:默认值:10 秒。 每次激活失败的退避间隔。
- ActivationMaxFailureCount:默认值:20。 系统在放弃之前重试失败激活的最大次数。
- ActivationRetryBackoffExponentiationBase:默认值:1.5。
- ActivationMaxRetryInterval:默认值:3,600 秒。 失败后激活的最大退避重试间隔。
- CodePackageContinuousExitFailureResetInterval:默认值:300 秒。 为 CodePackage 重置连续退出失败计数的超时间隔。
- DeploymentRetryBackoffInterval:默认值:10。 部署失败的退避间隔。
- DeploymentMaxRetryInterval:默认值:3,600 秒。 部署失败后的最大退避间隔。
- DeploymentMaxFailureCount:默认值:20。 重试
DeploymentMaxFailureCount
次应用程序部署后,节点上该应用程序的部署才会失败。
- DeactivationScanInterval:默认值:600 秒。 为 ServicePackage 留出的最小时间,如果它从未承载任何副本(即从未使用过),则可在此时间内承载一个副本。
- DeactivationGraceInterval:默认值:60 秒。 在共享进程模型中为 ServicePackage 留出的时间,在此时间内,允许其在承载任意副本后再重新承载另一个副本。
- ExclusiveModeDeactivationGraceInterval:默认值:1 秒。 在独占进程模型中为 ServicePackage 留出的时间,在此时间内,允许其在承载任意副本后再重新承载另一个副本。