处理这类集成问题时,我通常会先记下两句判断:扫描结果没显示,不是扫描没执行,就是回调没送达。只要把 SonarQube 的历史记录和 Jenkins 的构建记录放在一起对比,很快就能看出断点在哪。常见的情况分成两种:一种是在 SonarQube 项目的后台页面里能看到最新一次分析,但 Jenkins 这边不显示任何质量门禁信息;另一种是 SonarQube 后台里也看不到新的分析记录,那问题就只能出在扫描端或者上报端。
先确认扫描阶段本身有没有成功
在 Jenkins 中打开具体构建的控制台输出,查找 SonarQube SonarQube Scanner 或 sonar-scanner 起始的命令行记录。如果能看到类似下面的输出:
INFO: Sensor Analysis Warnings import... (done) | time=...
INFO: ANALYZE SUCCESS... 说明扫描器已经完成代码分析,并且把结果发给了服务器。假如日志里出现 ERROR: SonarQube scanner exited with non-zero code,那就要回到 sonar-project.properties 里的路径、sonar.projectKey、源代码目录这些基础配置去排查。在 SonarQube 后台确认有没有收到报告
登录 SonarQube,搜索项目名或项目 key,打开“Projects”里的对应项目,看主页右上角是否显示“Last analysis xx minutes ago”。如果这里也没有更新,回到 Jenkins 控制台搜索 SONAR_HOST_URL 或 SONAR_AUTH_TOKEN,检查环境变量是否被填成占位符。
另一种做法是看 SonarQube 的服务日志,通常位于 $SONARQUBE_HOME/logs/sonar.log。收到分析成功上报时,日志里会出现 POST /api/ce/submit 或 Analyzers 相关的行。如果日志里看不到任何来自 Jenkins 的请求,重点是检查服务器地址和网络端口是否能从 Jenkins 所在机器正常访问。
Jenkins 并不是直接到 SonarQube 拉结果
新版 SonarQube(7.9 之后)采用“扫描器上传报告,服务器处理完毕后再通过 Webhook 通知 Jenkins”的方式。因此你必须做两件事:第一,在 Jenkins 的“系统管理 → SonarQube servers”里填写能让 SonarQube 访问到的 Jenkins 地址;第二,在 SonarQube 项目的 Webhook 配置里,添加一个指向 http://<jenkins>/sonarqube-webhook/ 的 URL。否则 Jenkins 永远不会收到质量门禁结果,即使扫描报告在 SonarQube 里已经正常显示。
如果项目是用流水线跑的,还应该在管线脚本里补充 waitForQualityGate 这一步。以前只靠 withSonarQubeEnv 触发扫描,流水线跑完并不会主动等待 SonarQube 回调。参考下面的片段:
stage('SonarQube') {
steps {
withSonarQubeEnv('SonarQube') {
sh 'sonar-scanner'
}
}
}
stage('Quality Gate') {
steps {
timeout(time: 5, unit: 'MINUTES') {
waitForQualityGate abortPipeline: true
}
}
} 加上这一步之后,如果 SonarQube 那边始终没有回调,流水线会一直停在 Quality Gate 阶段直到超时。这样反而能让你更快发现问题。
经常配错的三个细节
- SonarQube 服务器地址填了 localhost。Jenkins 上配的 SonarQube 地址是给扫描器用的,也是给 SonarQube 的 Webhook 用来回调 Jenkins 的。如果填了 127.0.0.1,从 Docker 容器里访问不到,分析就会卡住。
- Token 没有写入凭据。在流水线里直接写明文 token 时,sonar-scanner 会把它打印到临时环境变量里,但插件读取不到。建议 Jenkins 用“凭据绑定”,SonarQube 侧生成一个带 execute analysis 权限的 token。
- Webhook 指向了 SonarQube 自己。有些环境会把 SonarQube 的 Webhook URL 也配成 SonarQube 地址,结果 Jenkins 永远收不到通知。确认 URL 里是 Jenkins 的 8080 端口,并且结尾是
/sonarqube-webhook/。
从两份日志里找关键信息
在 Jenkins 所在机器执行 grep -i sonar /var/log/jenkins/jenkins.log | tail -n 100,看看 Jenkins 有没有收到 SonarQube 的 webhook 请求。收到时会出现类似 Received sonarqube webhook for ... 的行。如果这条都没有,说明问题出在 SonarQube 到 Jenkins 的路由,或者 Webhook 本身就没配成功。
SonarQube 这边的日志同样重要。打开 $SONARQUBE_HOME/logs/web.log,搜索 jenkins 或 webhook,能看到服务器向外发送 webhook 的 HTTP 状态码。如果状态码是 404,多半是 Jenkins 地址拼错了;如果 401,认证信息有问题。
把整条链路重新验证一次
修完配置后,不要只看 Jenkins 构建通过就认为结束。去 SonarQube 后台确认本次提交下生成了分析记录;再回到 Jenkins 任务页,看是否出现 SonarQube 图标和最近一次质量门禁状态。对于流水线任务,确认 Quality Gate 阶段确实执行到了,而不是被 timeout 或 abortPipeline 截断。
如果重启过 Jenkins 或 SonarQube 服务,需要重新跑一次扫描,因为插件持有的回调 token 可能失效。先完成一轮“扫描 → 报告 → 回调 → 展示”的完整闭环,再判断问题是否真正解决。