Rundeck归档任务无法通过UI正常终止的问题求助
问题解决:Rundeck终止作业后PHP归档脚本仍继续执行
问题背景
使用Rundeck 2.10.7-1执行数据归档作业,通过UI终止作业后,PHP脚本仍会持续完成所有数据迁移,日志显示作业已失败但进程未停止:
query, job_273::moveRecords, 1.7757458686829, DANGER 12:00:32 **** job_273::moveRecords time taken 1.8048849105835 sec, offset: 6000 12:00:32 12:00:32 **** Job 273:: Success, data archived successfully!! 12:00:32 12:00:35 query, job_273::moveRecords, 1.5157968997955, DANGER 12:00:35 **** job_273::moveRecords time taken 1.5820739269257 sec, offset: 7000 12:00:35 12:00:35 **** Job 273:: Success, data archived successfully!! 12:00:35 12:00:39 query, job_273::moveRecords, 1.6569089889526, DANGER 12:00:39 **** job_273::moveRecords time taken 1.689309835434 sec, offset: 8000 12:00:39 12:00:39 **** Job 273:: Success, data archived successfully!! **** Job 290:: Success, data archived successfully!! 12:00:39 12:00:43 Result: 2147483647 12:00:43 Failed: NonZeroResultCode: Result code was 2147483647 12:00:43 java.util.concurrent.CancellationException 12:00:43 at java.util.concurrent.FutureTask.report(FutureTask.java:121) 12:00:43 at java.util.concurrent.FutureTask.get(FutureTask.java:192) 12:00:43 at com.google.common.util.concurrent.Uninterruptibles.getUninterruptibly(Uninterruptibles.java:135) 12:00:43 at com.google.common.util.concurrent.Futures$4.run(Futures.java:1158) 12:00:43 at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) 12:00:43 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) 12:00:43 at java.lang.Thread.run(Thread.java:750) 12:00:43 Cancellation while running step [1] 12:00:43 Execution failed: 4503990 in project BIM_QA: [Workflow result: , step failures: {1=Interrupted: Cancellation while running step [1]}, flow control: Continue, status: failed]
核心原因
- PHP脚本未处理Rundeck发送的终止信号(SIGTERM/SIGINT),默认会执行到脚本结束。
- 老版本Rundeck对进程的中断机制存在缺陷,无法强制终止未响应信号的子进程。
解决方案
1. 给PHP脚本添加信号处理逻辑
在归档脚本开头添加信号捕获代码,收到终止信号时立即停止操作并清理资源:
declare(ticks=1); // 信号处理函数 function terminateScript($signal) { global $dbConnection; // 回滚未提交的数据库事务 if (isset($dbConnection) && $dbConnection->inTransaction()) { $dbConnection->rollback(); } // 关闭数据库连接 if (isset($dbConnection)) { $dbConnection = null; } // 退出脚本,返回非零状态码 exit(1); } // 注册SIGTERM(Rundeck终止信号)和SIGINT(手动中断信号)处理 pcntl_signal(SIGTERM, 'terminateScript'); pcntl_signal(SIGINT, 'terminateScript');
2. 优化脚本批量处理逻辑
将大批次数据拆分为小批量处理,每处理完一批就触发信号检查,确保能及时响应终止指令:
// 假设每次处理100条记录 $batchSize = 100; $totalRecords = getTotalRecordsToArchive(); // 自定义函数获取总记录数 for ($offset = 0; $offset < $totalRecords; $offset += $batchSize) { // 获取当前批次数据 $records = getBatchRecords($offset, $batchSize); // 自定义函数获取批次数据 // 处理当前批次 foreach ($records as $record) { archiveRecord($record); // 自定义函数归档单条记录 } // 触发信号检查,确保能及时捕获终止信号 pcntl_signal_dispatch(); }
3. 调整Rundeck作业配置
- 进入作业编辑页面,找到"Step"配置,将Step Execution Mode设置为
Interruptible(若版本支持),确保Rundeck能向脚本发送中断信号。 - 检查Rundeck配置文件
rundeck-config.properties,确保rundeck.execution.interruptible=true(默认开启,老版本可手动确认)。
4. 升级Rundeck版本(推荐)
Rundeck 2.10.7是多年前的老版本,后续3.x、4.x版本修复了大量进程管理和中断相关的bug,升级到稳定版能从根源减少此类问题。
内容的提问来源于stack exchange,提问作者Hemant Kumar
相关产品推荐
相关产品推荐

