Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Orchestrator 的一个妙处是它可以自动处理 Runbook 的多实例线程,或者根据您的需要将它们排队。例如,您可以将处理新用户的 Runbook 添加到 Active Directory,对于大公司而言,可能存在多个并发请求,因此可能需要运行 Runbook 的多个实例。或者,您可能有一个更改系统的事务类型的流程,并希望确保在多个用户请求更改时将这些请求排队并按顺序运行,以避免相互之间发生潜在冲突。通过 Runbook 的“属性”对话框中的“作业并发”选项卡可以轻松控制此 Runbook 行为:
默认情况下,该值设置为 1,这意味着一个 Runbook 将运行一个实例,并将所有其他请求排队。如果希望增加此数字,以允许多个并发实例,只需将该数字调大一些即可。相当容易,不是吗?
但是,如果您有一些作业需要作为单一实例运行,但希望在当前作业完成之前忽略所有其他请求,应该怎么办?此情况的一个示例是云服务的自动横向扩展。让我们假定您在使用 Operations Manager 监视一个服务,一个性能警报触发一个 Runbook,开始横向扩展该服务。该横向扩展进程可能需要一些时间,并且在该进程完成之后可能还需要一段时间,以使性能平均数下降到一个可接受的范围(我们称其为“冷却”期间)。无论出于何种原因,都可能会再次触发警报,告诉 Orchestrator 纵向扩展该服务。如果已经有一个 Runbook 正在纵向扩展该服务,您不希望接受任何其他请求,当然也不希望只是将它们排队。您知道您只是想忽略或丢弃任何请求,直到此 Runbook 完成之后为止。那么如何处理此情况?
注意: 与任何示例一样,我向您展示的是一个相对简单的视图,在现实世界中,您拥有的可能是一些更为详细的逻辑。不过,我认为通过这个基本示例可以学到这种理念,并在自己的环境中根据情况举一反三。
首先,创建一个新的 Runbook。现在,如果希望避免将 Runbook 作业的请求排队,我们首先需要做的是增加同步作业的数量。在上面所示的对话框中,我们将该数字增加到了 10(这样,如果后续请求快速连发,我们可以处理它们而无需排队)。
接下来,将“初始化数据”活动和“查询数据库”活动拖放到 Runbook 并将它们链接起来。
我们在这里完成的工作基本上是,在 Orchestrator 数据库中查询包含此 Runbook 中“初始化数据”活动的活动 ID 的任何活动作业 (TimeEnded = NULL)。但是我们需要采取迂回的办法完成此工作。在运行时我们无法访问 Runbook 的 ID,因此我们需要使用连接两个表的查询从活动 ID 中推测该 ID,如下图所示:
您可能会注意到,查询中执行了一些奇怪的字符串替换。此问题是由于每个活动的活动 ID 属性都格式化为带花括号的 GUID 形式,如下所示:
{5AC4D430-BF24-4E70-B117-C3ABB69A06F5}
不过,数据库中的数据格式不带花括号,因此需要重新格式化 ID 以剥离花括号。幸运的是,SQL 提供了一些格式化字符串的简单方法,因此我们不必在这两个活动之间放置其他活动来转换字符串。
我要再向 Runbook 添加一些其他活动,以便它可以执行一些操作。
我在其中放置了一个“sleep”(休眠)活动,以保持该作业运行 60 秒,与此同时我激活更多实例来测试此功能。我还添加了一个“发送平台事件”活动,以便在故意丢弃新作业时我可以得到通知。我还从 Query Database 活动中修改了链接条件,以相应地路由进程流。对于指向 [Sleep 60](休眠 60 秒)活动(以及指向“real”Runbook 的操作部分)的链接,我将链接条件设置为:如果此 Runbook 只有一个正在运行的实例(包括此 Runbook),则执行操作。
对于“发送平台事件”活动链接,我将其设置为:如果存在此 Runbook 的多个最新实例,则执行此路由。
在 Runbook 中检查之后,我切换到 Orchestration 控制台并浏览到该 Runbook。然后在“操作”窗格上,我单击“启动 Runbook”,然后单击“开始”按钮,重复了几遍同样的操作。在刷新视图之后,可以看到我的原始实例仍在运行,但我启动的其他两个实例已经完成。
在左窗格中单击“事件”,可以看到早先完成的两个 Runbook 生成了预期的事件。
在页面底部,可以看到此消息的描述:
现在,就我个人而言,如果在 Runbook 的预期完整操作完成之前停止了它,我不一定希望该 Runbook 显示为成功完成。我可能想让它显示为一个警告,以便引起我的注意,而不像事件通知那样(当前每种情况各不相同)。因此,在此情况下,我可以创建一个自定义活动,该活动不执行任何操作,只是从 Runbook 抛出警告,导致该 Runbook 停止并带一个警告状态。我将在以后的博客中提供此代码的示例。