Jenkins Quiet Down模式下长时长Thread.sleep()未生效问题求助
问题成因
- 问题核心是
@NonCPS注解和Thread.sleep()的组合存在设计缺陷:- 被
@NonCPS标注的方法不会经过Jenkins流水线的CPS转换,会直接在JVM工作线程上同步执行,Thread.sleep()属于硬阻塞当前工作线程的操作 - Jenkins内置了对长时间阻塞工作线程的中断保护机制,默认阈值通常在30~60分钟区间,你设置120分钟的sleep远超过该阈值,执行sleep的线程会被Jenkins强制销毁,后续取消静默模式的代码根本没有执行机会
- 短时长的sleep没有触发中断阈值,因此可以正常跑完整个逻辑
- 被
- 你提到的CPS方法不匹配限制,本质是你把整个业务逻辑都加到了
@NonCPS方法里,所以无法调用Jenkins原生的sleep步骤,只要拆分逻辑即可规避该问题。
解决方案
你只需要把调用Jenkins内部API的逻辑单独拆分为小型@NonCPS方法,主逻辑不使用@NonCPS注解,就能直接调用Jenkins原生的sleep步骤,该步骤是CPS兼容的,采用流水线挂起机制而非硬阻塞线程,等待数小时也不会被中断:
// 开启静默模式,仅该方法加@NonCPS注解 @NonCPS def startQuietDown(String reason, int length) { length = length?.isInteger() ? length.toInteger() : 1 String fullReason = "${reason} Downtime is scheduled for ${length} minutes." Jenkins.instance.doQuietDown(false, length * 60, fullReason) } // 关闭静默模式,仅该方法加@NonCPS注解 @NonCPS def stopQuietDown() { Jenkins.instance.doCancelQuietDown() } // 主逻辑无需@NonCPS注解,可正常调用所有Jenkins原生步骤 def doAndCancelQuietDown(String reason, int length) { echo "Entering quiet down mode... " startQuietDown(reason, length) sleep time: length, unit: 'MINUTES' echo "Exiting quiet down mode... " stopQuietDown() }
内容的提问来源于stack exchange,提问作者Chris Maggiulli
相关产品推荐
相关产品推荐

