Jenkins流水线执行Smoke Test时请求超时问题排查
问题分析与修复方案
从你的日志和代码来看,核心问题是Connection refused被Jenkins的httpRequest插件映射为408超时,导致流水线异常终止,同时你的重试逻辑和错误处理也存在一些不合理的地方。下面具体拆解问题并给出修复方案:
1. 当前代码存在的核心问题
- 重试逻辑不分场景:不管是网络连接错误(比如连接拒绝、超时)还是版本不匹配,都会触发重试。但版本不匹配是部署结果错误,重试多少次都没用,属于无效重试。
httpRequest默认处理太严苛:默认情况下,插件会把底层连接错误(比如Connection refused)映射为408超时,且只要响应码不在100-399范围就直接抛出异常,让你无法灵活处理这类场景。- 批量检测的重试粒度不合理:遍历多个端口时,只要一个端口失败就终止整个循环并全量重试,会重复检测已经成功的端口,浪费资源。
2. 修复后的Pipeline代码
void smoketests() { SMOKE_TEST_PORTS.each { port -> // 对每个端口单独执行重试逻辑,避免全量重复检测 retry(3) { try { String url = isReleaseBranch() ? "https://<url>:${port}/actuator/info" : "http://<url>:${port}/actuator/info" // 自定义httpRequest配置,接管错误处理 def response = httpRequest( consoleLogResponseBody: true, timeout: 60, httpMode: 'GET', ignoreSslErrors: true, url: url, ignoreReturnCode: true, // 不自动抛出异常,自己处理响应 validResponseCodes: '' // 清空默认的有效响应码范围 ) // 专门处理连接拒绝类错误 if (response.status == 408 || response.content.contains("Connection refused")) { throw new IOException("Failed to connect to ${url}: ${response.content}") } // 处理非2xx的正常响应错误 if (response.status < 200 || response.status >= 300) { throw new Exception("Unexpected status code ${response.status} for ${url}") } // 解析响应并校验版本 def responseJson = readJSON(text: response.content) if (!responseJson.build.version.equals(POM.getVersion())) { // 版本不匹配直接终止,不重试 throw new IllegalStateException("Version mismatch: expected ${POM.getVersion()}, got ${responseJson.build.version}") } println "Smoke test passed for ${url}" } catch (IOException e) { // 仅网络类异常触发重试,休眠后抛出异常让retry捕获 println "Network error: ${e.message}, retrying after 20s..." sleep(time: 20, unit: 'SECONDS') throw e } catch (IllegalStateException e) { // 版本不匹配直接终止流程 println e.message throwError("Smoke test failed due to version mismatch") } catch (Exception e) { // 其他未知错误直接终止 println "Unexpected error: ${e.message}" throwError("Smoke test failed unexpectedly") } } } if (isReleaseBranch()) { sendMattermostMsg("released ${PROJECT} with version ${POM.getVersion()} on UAT") } }
3. 关键改进说明
- 按端口独立重试:每个端口的检测逻辑单独重试,避免一个端口失败导致所有端口重复检测。
- 异常类型区分处理:
- 仅网络类异常(
IOException)触发重试,重试前休眠20秒。 - 版本不匹配的异常直接终止流程,不做无效重试。
- 仅网络类异常(
- 接管
httpRequest错误处理:通过ignoreReturnCode: true关闭插件默认的异常抛出逻辑,自己处理连接错误和响应码,更灵活。 - 清晰的错误日志:每种错误场景都有明确的日志输出,便于后续排查问题。
额外排查建议
你提到浏览器能正常访问但流水线请求失败,还可以检查:
- Jenkins代理服务器是否能访问目标端口(比如防火墙规则、网络路由限制)。
- 目标应用的
/actuator/info端点是否对Jenkins代理的IP开放权限。
内容的提问来源于stack exchange,提问作者m1well
相关产品推荐
相关产品推荐

