Jenkins流水线触发超时后、杀进程前生成进程转储的方法
在Jenkins流水线超时终止测试前执行自定义命令的实现方案
完全可以实现这个需求,核心是通过Jenkins Pipeline的异常捕获机制,在超时触发时先执行自定义操作(比如生成进程转储),再终止测试进程。以下是具体的实现思路和代码示例:
核心实现逻辑
Jenkins的timeout步骤在超时后会抛出FlowInterruptedException异常,我们可以捕获这个异常,判断是否由超时引发,然后执行转储命令,最后重新抛出异常让流水线正常终止。同时需要提前捕获测试进程的PID,确保能精准定位目标进程执行转储。
示例代码
pipeline { agent any stages { stage('Run Unit Tests') { steps { script { def testPid = null try { // 设置超时时间(示例为30分钟) timeout(time: 30, unit: 'MINUTES') { // 后台启动测试脚本,捕获进程PID testPid = sh( script: './start-unit-tests.sh & echo $!', returnStdout: true ).trim() // 等待测试进程完成 sh "wait ${testPid}" } } catch (org.jenkinsci.plugins.workflow.steps.FlowInterruptedException e) { // 验证中断是否由超时触发 def isTimeout = e.causes.any { it instanceof org.jenkinsci.plugins.workflow.steps.TimeoutStepExecution.Timeout } if (isTimeout) { echo "测试进程超时,开始生成线程转储..." // 执行转储命令(以Java测试为例,用jstack生成线程栈) sh "jstack ${testPid} > test-thread-dump-${BUILD_NUMBER}.txt" // 若测试进程未自动终止,手动强制终止 sh "kill -9 ${testPid}" } // 重新抛出异常,保持流水线的终止状态 throw e } } } } } post { always { // 归档转储文件,方便后续分析 archiveArtifacts artifacts: 'test-thread-dump-*.txt', allowEmptyArchive: true } } }
关键注意事项
- 进程PID捕获:必须确保能正确获取测试进程的PID,避免误操作其他进程。如果测试启动了多个子进程,可能需要用更精准的方式定位(比如通过进程名过滤)。
- 转储命令适配:不同类型的测试框架需要对应不同的转储工具:
- Java测试:
jstack(线程栈)、jmap(内存快照) - Python测试:
py-spy dump(线程栈) - C++/原生程序:
gcore(核心转储)
- Java测试:
- 权限问题:Jenkins agent执行转储命令需要足够权限,比如Java进程的转储需要和进程运行用户一致,否则可能需要sudo权限。
- 容器内测试:如果测试在Docker容器中运行,需要在容器内部执行转储命令,或者通过
docker exec进入容器操作。
内容的提问来源于stack exchange,提问作者hardfork
相关产品推荐
相关产品推荐

