Service Management Automation:检查点、挂起和恢复 Runbooks
Windows PowerShell 工作流的主要特性之一是支持检查点,这是工作流保持状态的一种能力,如果工作流被故意中断,或者因错误或故障而中断,它可以立即在中断点或靠近中断点的地方被恢复。Service Management Automation(SMA)使用 PowerShell 工作流作为运行 Runbooks 的引擎。因此,检查点是用于 SMA Runbooks 的有力工具。检查点的适当使用允许您创建可靠、自动、长期运行 IT 进程的 Runbooks,安全访问大量不同的网络系统,保证不执行那些代价高昂的重复操作,并且可以通过手动步骤来中断重复性操作。
在这篇博客中,我将讨论为什么、什么时候以及如何在 SMA Runbooks 中使用检查点。“PowerShell 工作流中的检查点”中有些相关信息,您应该学习一下,以便帮助您能更好地理解。
什么是检查点?
检查点是 Runbook 作业当前状态的快照,包括变量的当前值、输出和其他可序列化的状态信息。每个检查点都会保存到存储空间。如果一个 Runbook 被有意或无意挂起,然后恢复,工作流引擎会使用最新检查点中的数据来还原和恢复 Runbook。
SMA 中的检查点
在 SMA 中,当您持续执行一个 Runbook 作业时,检查点就会被创建,继而存储在 SMA 数据库中。每个作业只有最新的检查点会存储进数据库:每个检查点会替换之前的检查点。如果 Runbook 被挂起并恢复,那么存储的检查点就会被用来还原和恢复该 Runbook。
PowerShell 工作流将检查点存储在托管工作流会话的机器硬盘上,而 SMA 则将检查点存储在 SMA 数据库中。如果您把 SMA 数据库和 Runbook Workers 部署在不同的机器上,如果运行在 Runbook 上的 Worker 发生故障,那么已重新启动的 Worker 或其他 Worker 可以继续作业并使用数据库中最新的检查点恢复该作业。
为什么使用检查点?
以下是在 Runbooks 中使用检查点的几点原因。
- 确保不重复某些操作
- 当一个 Runbook 被挂起并恢复时,检查点对于保证非重复性操作(非幂等)是十分有用的。举个例子,创建虚拟机后在 Runbook 中使用检查点,当 Runbook 作业被挂起并恢复后,就不会再创建虚拟机副本。
- 保护长期运行的任务
- 在现实世界中,错误经常发生。多个步骤的长期任务容易因网络问题、机器重启或死机、超时、停电等原因中断。为了避免重做这些代价高昂的工作,在关键时刻使用 Runbook 中的检查点可以保证任何重新启动的 Runbook 都不会重做这些工作。
- 允许计划或手动中断
- 在有些情况下,您可能想故意挂起运行中的 Runbook。比如因等待审批而挂起 Runbook 作业、因等待修复计划外或计划内的系统问题而挂起 Runbook 作业。
如何向Runbook 中添加检查点?
Checkpoint-Workflow 活动(检查点 - 工作流活动)
Checkpoint-Workflow 活动(别名 Persist)是一个标准的 PowerShell 工作流活动,它可用于在 Runbook 中于某一特定的点上创建检查点。而这一特定的点就是指 Checkpoint-Workflow 活动发生的位置。
…
Download-Updates
Reboot-VM
Checkpoint-Workflow
Email-Team
Checkpoint-Workflow
…
-PSPersist Activity 的常见参数
调用一个活动时,可以使用 –PSPersist 的常见参数。这将迫使活动完成后立即创建检查点。
…
Download-Updates
Reboot-VM –PSPersist $True
Email-Team –PSPersist $True
…
$PSPersistPreference 工作流首选项变量
在 Runbook 中,您可以使用包含 $PSPersistPreference = $True 的语句。作用是在每个遵循首选项语句的活动之后获取检查点。如果您在 Runbook 的最开始设置首选项,那么在 Runbook 中每个活动结束后就会产生一个检查点。您可以使用 $PSPersistPreference = $False (Runbook 的默认语句)语句关闭检查点的自动执行,活动完成后的运行将不包括自动检查点。
请注意,每个活动完成后,基于性能和策略原因的持久化或许不是最好的方法。每个检查点都需要处理,进而将工作流状态序列化并存储在数据库中。同时,在有些情况下(如下例所示),如果 Runbook 被挂起,您希望重复操作多个活动。
…
$PSPersistPreference = $True
Download-Updates
Update-VM
Email-Team
$PSPersistPreference = $False
…
Suspend-Workflow Activity (挂起 - 工作流活动)
当 Suspend-Workflow 活动用于 Runbook 时,即刻的反应是使用 Runbook 中的检查点然后挂起。在 Runbook 中您会用到这个活动,比如您需要 Runbook 做某项工作而等待审批时。
…
Download-Updates
# Get permission to apply updates
Suspend-Workflow
# Continue if resumed
Reboot-VM –PSPersist $True
Email-Team –PSPersist $True
…
在哪里添加检查点?
一般来说,最好是添加在您想持久化工作流的地方。相较于在每次活动后通过设置 $PSPersistPreference 变量来获取总检查点的方法,在持久化工作流的地方经过深思熟虑并合理地使用 Checkpoint -Workflow 活动和 Suspend-Workflow 活动或 –PSPersist 参数更有意义。还有那些您明确想要和绝对不想持久化工作流的地方(例子在下面)。同时请记住,持久化工作流需要一定的工作量,并且会影响工作流的性能。
最佳实践: 在下列情况下,在您的工作流中添加检查点:
- 活动完成后您不想重复的操作(非幂等)。
- 在活动之前,有较高概率引起失败和工作流挂起问题。当工作流恢复并保证活动完成时,您想要重复该活动。比如访问易受网络问题影响的远程系统的活动。
- 因成本问题您不想再重复操作的任何长期运行或代价高昂的活动。
演示场景:更新虚拟机
- 从 Windows Update 下载最新补丁
- 重启虚拟机,应用补丁
- 检查点
- 给团队发邮件,报告更新已应用
- 检查点
- …
在这一场景中,可以重复步骤 1 (幂等),但不重复步骤 2 或步骤 3。因此,在步骤 2 和步骤 3 之后都将需要检查点。每次活动之后会自动执行持久化;然而,在步骤 1 之后添加检查点,就不必再向系统中添加工作。
演示场景:通知客户
- 从数据库中获取客户列表
- 给客户发送关于新政策的电子邮件
- 检查点
- 管理客户发出的电子邮件
- 检查点
- …
有时您有一组不想重复的活动,但前提是这组中的所有活动都成功。在这一场景中,步骤 1 和步骤 2 应该一起运行,从而保证邮件发出时检索到的客户列表是最新的。因此,如果 Runbook Worker 在步骤 2 之前崩溃(给客户发邮件时),当 Runbook 作业恢复后,我们想要它从步骤 1 重新开始(检索客户列表)。然而,如果在步骤 3 之前发生故障或挂起,那么我们想确保不重复步骤 2 (不想再次给客户发邮件)。
最佳实践: 请记住,您不能在工作流中的 InlineScript 块或功能中添加检查点。因为 InlineScript 块和功能中的代码是以纯 PowerShell 脚本运行,而不是以工作流运行。因此,为了充分利用工作流的持久性,应将您的工作流代码拆分成多个允许在活动中添加检查点的模块化活动,或者如果您需要 InlineScript,那么使用多个 InlineScript 块来允许检查点在其中工作。
挂起和恢复Runbooks
检查点与挂起/恢复 Runbooks 的关系十分紧密。在 Runbook 中添加检查点,以便在其挂起时从最新的检查点中恢复。
SMA 中的 Runbok 作业有以下几种挂起方式:
- 在 SMA 门户 UI 中故意挂起
- 使用 SMA 门户 UI,选择挂起一个运行的 Runbook 作业。
- 该作业将在下个检查点被挂起。如果您没有授权 Runbook 中的任何检查点,那么 Runbook 会继续运行至结束,显示的状态为“已挂起”。
- 在 Runbook 中使用 Suspend-Workflow 的故意挂起
- 包括 Runbook 中的 Suspend-Workflow 活动。
- 在该作业中使用检查点,然后在调用 Suspend-Workflow 的地方挂起。
- 使用 Suspend-SmaJob cmdlet 的故意挂起
- 在 PowerShell 脚本中可以使用 Suspend-SmaJob 命令来挂起正在运行的 SMA Runbook 作业。
- 该作业将在下个检查点被挂起。如果您没有授权 Runbook 中的任何检查点,那么 Runbook 会继续运行至结束,显示的状态为“已挂起”。
- Runbook 发生异常,通过 SMA 工作流引擎引起的无意挂起。
- 当一个运行的作业出现异常,会从 Runbook Worker 中被卸载,它的状态也会被设置为“已挂起”。
- 由于 Runbook Worker 故障引起的无意挂起
- 如果一个 Runbook Worker 发生故障,运行在这个 Worker 中的作业会立即终止。而这些处于数据库中的作业状态仍为“正在运行”。
有几种方法可以对 SMA 中的 Runbook 作业进行恢复。在所有情况下,作业都将从最新的检查点中恢复,如果没有检查点,则从最老的可用日志文件进行恢复。
-
- 在 SMA 门户 UI 中手动恢复
- 使用 SMA 门户 UI,选择恢复一个挂起的作业。
- 使用 Resume-SmaJob 命令恢复
- 在 PowerShell 脚本中使用 Resume-SmaJob 命令恢复一个挂起的作业。
- 自动跟踪 Runbook Worker 故障
- 当 Worker 恢复联机或当其他 Worker 已被分配,那么该 Worker 就会在数据库中寻找分配给它的作业。状态为“正在运行”的作业以及尚未在 Worker 中运行的作业,Worker 会自动恢复它们。
- 如果一个 Runbook Worker 发生故障并且不可恢复,您可以通过使用 New-SmaRunbookWorkerDeployment 命令让其他 Worker 继续进行作业。
- 在 SMA 门户 UI 中手动恢复
总结
正如您所看到的,如果您想充分利用 PowerShell 工作流的主要功能并创建中断-恢复 Runbooks,那么向您的 Runbooks 中添加检查点是十分重要的。添加检查点十分简单。在 Runbook 授权期间稍有预见性,便可以在发生意外中断时保护长期运行和代价高昂的任务,同时创建真正强大可靠的 Runbooks。