Workiva Scripting 会自动监控每次脚本运行所使用的资源,包括内存、CPU、磁盘使用情况和运行时间。当脚本超出其配置的资源限制时,脚本功能会尝试在保持平台稳定性的同时安全地停止该脚本。此外,该系统会给脚本一些时间进行清理和退出,然后再完全停止它们,从而最大限度地减少对用户的干扰。
本文解释了脚本如何处理终止场景,日志中会显示哪些详细信息,并包含参考屏幕截图。
有关所有系统限制的详细信息,请参阅 Workiva Scripting 限制。
场景
| 应用场景 | 行为 | 日志详情 |
| 非常短的 | 运行成功 | 未记录任何资源使用数据 |
| 正常完成 | 运行成功 | 已记录完整的资源使用情况汇总信息(除非资源使用时间过短而无法采样)。 |
| 超出内存限制 | 优雅终止 | 显示内存阈值已超出,并显示平均和峰值使用量 |
| 超出磁盘限制 | 优雅终止 | 显示磁盘阈值已超出,并显示平均和峰值使用率 |
| 超出分配时间 | 优雅终止 | 显示运行时间超出部分和总使用时间 |
| 手动取消 | 优雅终止 | 完整资源发布,资源摘要已记录 |
| 意外终止 | 不体面的解雇 | 记录的使用数据不完整或不完全 |
Workiva Scripting 通过自动强制执行资源限制并提供详细日志(如下面的屏幕截图所示),确保了平台的可靠性和透明度,方便开发人员构建和优化自动化脚本。
运行成功完成后终止
当脚本正常完成且未超出限制时,日志将包含 资源使用情况摘要 显示内存、CPU、磁盘和执行时间的平均使用情况和峰值使用情况。此信息可以显示成功完成的运行的性能特征。
注意: 如果脚本运行速度非常快(例如,不到 1 秒),则可能不会进行资源采样。在这种情况下,日志中不会报告任何资源使用数据。
脚本运行速度过快,无法进行采样。
如果脚本执行过快,监控器将无法捕获使用情况数据。
脚本有一个正常的退出程序
如果脚本执行完毕且未超出任何限制,则资源使用统计信息将完整显示在日志中。
当超出限制时终止
如果脚本运行超出其配置的限制(例如,内存、磁盘使用量或分配的时间),脚本功能将:
- 尝试安全地停止脚本——当超出限制时,脚本首先发送终止信号(SIGTERM),让脚本在 15 秒内清理并退出。
- 如果脚本在 15 秒内没有退出,脚本会发送 SIGKILL 信号,立即停止进程而不进行任何清理。这是强制终止,运行将以失败状态完成(在日志中以红色显示)。此状态表示脚本系统错误。
- 记录停止的原因——日志将显示达到哪个限制并总结脚本的资源使用情况。
接下来的章节将举例说明当脚本超出限制而没有代码处理这些信号时会发生什么情况。要了解如何修改脚本以优雅地响应这些信号,请参阅 脚本中的系统信号处理。
内存限制已超出
当脚本超出配置的内存限制时,日志将包含终止原因以及超出阈值的详细信息。
磁盘使用量已超出限制
当脚本超出配置的磁盘使用限制时,日志将包含终止原因以及达到限制时磁盘使用情况的详细信息。
分配时间已超时
当脚本运行时间超过其配置的分配时间时,日志将记录终止原因和总运行时间。
用户取消运行时终止运行
如果用户手动取消运行,脚本首先会发送中断信号(SIGINT)来告知脚本应该停止运行。脚本有 15 秒的时间来清理、保存进度或回滚,否则将关闭。经过 15 秒的宽限期后,将执行上述相同的序列:发送终止信号 (SIGTERM) 以允许脚本再有 15 秒的时间完成清理工作,如果脚本仍未退出,则发送最终终止信号 (SIGKILL)。
下图显示了当脚本不包含处理中断信号的代码时,脚本日志的显示方式。
要了解如何修改脚本以优雅地响应这些信号,请参阅 脚本中的系统信号处理。
非计划终止
在极少数情况下,例如当脚本消耗内存的速度超过脚本系统监控消耗速度时,系统可能会在检测到超出限制之前终止脚本。当这种情况发生时,脚本会记录一个不完整的使用情况报告,仅显示终止前收集的数据点。
在脚本中处理系统信号
信号处理可以让脚本在被系统取消或停止时干净利落地关闭。通过捕获和响应系统信号,您的脚本可以释放资源、保存工作并优雅地退出(例如,当状态报告为“完成”时),而不是被强制终止。
当脚本因用户取消或超出平台限制而停止运行时,脚本会发出中断、终止和杀死信号。有关如何触发中断、终止和杀死信号的更多信息,请参阅前面的章节。
脚本信号及其处理方式
本节提供代码块和完整的示例,可用于处理这些信号。
你可以保持信号处理程序简洁,并在一个地方使用 try/finally 块来处理清理工作,该块总会在关闭时运行。这样可以保持脚本的可预测性和易于维护性。
无论接收到什么信号,脚本中处理信号的总体结构都是相同的:
- 文件顶部:导入 模块并定义处理程序
- 提前初始化: 在执行任何工作之前注册处理程序
- 在你的代码周围: 将主要代码包裹在
try/finally代码块中,以便清理操作始终运行
用户取消运行(信号情报)
当用户点击 取消 来取消脚本运行时,就会发生这种情况。
# --- 文件顶部 --- import signal, sys # 微型处理程序:请求立即退出,优雅退出 def _graceful_exit(signum, frame): print("收到 SIGINT 信号:请求取消。清理…") raise SystemExit(0) # --- 提前初始化 --- signal.signal(signal.SIGINT, _graceful_exit) 关于你的工作(稍后在文件中):
try: # 在此处执行长时间运行的工作... finally: # 用于关闭文件、清除日志等的中心位置 print("退出前的最终清理") 下图显示了处理中断信号(SIGINT)时脚本日志的显示方式。
直接处理 KeyboardInterrupt
Workiva Scripting 还会在向主线程传递 SIGINT 信号时引发KeyboardInterrupt 异常。您可以在 try 块中捕获此异常,并调用由 _graceful_exit()定义的相同清理路径。
try: # 此处执行长时间运行的任务... except KeyboardInterrupt: print("收到键盘中断:退出前需要清理…") _graceful_exit(None, None) finally: # 集中关闭文件、刷新日志等操作 print("退出前最终清理") 下图显示了通过键盘中断处理中断信号时脚本日志的显示方式。
脚本终止信号在宽限期后停止(SIGTERM)
脚本会要求你的脚本停止运行(例如,在超出限制后)。您的脚本有一个很短的退出宽限期。
# --- 文件顶部 --- def _graceful_term(signum, frame): print("收到 SIGTERM 信号:平台请求终止。正在完成…") raise SystemExit(0) # --- 提前初始化 --- signal.signal(signal.SIGTERM, _graceful_term) 下图显示了处理终止信号(SIGTERM)时脚本日志的显示方式。
脚本发出终止信号以立即停止(SIGKILL)
如果脚本在宽限期内没有退出,脚本程序将发送 SIGKILL 信号。你无法捕获 SIGKILL。收到 SIGINT/SIGTERM 信号时立即退出,以便在发生终止操作之前执行 finally 代码块。
前面章节中的截图显示了发出终止信号后日志的格式。
完整示例(可直接复制粘贴)
此模板注册最少的处理程序,并将清理工作集中在 中。将其粘贴到 Workiva Scripting 中,并将标记区域替换为您的逻辑。
在哪里添加你的代码:将 # ===== 你的代码从这里开始 ===== 下的示例循环替换为你的实际任务。避免长时间的不可中断调用,以便脚本可以在平台升级到 SIGKILL 之前执行到 finally 块。
"""Workiva 脚本模板:最小化处理程序 + finally 中的清理 - 小型处理程序在收到 SIGINT/SIGTERM 信号时引发 SystemExit(0) - 无论脚本如何停止,单个 finally 代码块都会运行以进行清理 - 保持代码简洁且可预测""" import signal import time # --- 信号处理程序(保持简洁) --- def _graceful_exit(signum, frame): print("收到 SIGINT 信号:请求取消。" 清理…") raise SystemExit(0) def _graceful_term(signum, frame): print("收到 SIGTERM:平台请求终止。正在完成…") raise SystemExit(0) # --- 在执行任何繁重工作之前注册处理程序 --- signal.signal(signal.SIGINT, _graceful_exit) signal.signal(signal.SIGTERM, _graceful_term) # --- 脚本的主要工作 --- def main(): print("开始工作…") # ===== 你的代码从这里开始 ===== # 示例长时间运行的循环。请替换为你的实际情况。 for i in range(1, 1_000_000): # 模拟一个工作单元(请替换为实际逻辑) print(f"正在处理项目 {i}…") time.sleep(1) # ===== 你的代码到此结束 ===== if __name__ == "__main__": try: main() finally: # 始终运行的集中式清理(包括 SIGINT/SIGTERM 信号) print("退出前的最终清理")