
1. 版本选型与安装前思考SonarQube 9.9 LTS 是现在做 Java、前端、Python 等多语言代码质量管控绕不开的一套工具很多团队拿它接 Jenkins、GitLab CI做 MR 门禁和增量检查。之所以选择 9.9 LTS 而不是追新版本核心原因是 LTS 版本有官方长期维护承诺社区插件兼容性最稳网上能搜到的踩坑案例也最多。你要是直接上 10.x 甚至 11.x部分插件还没跟进出问题连个参考都难找。安装之前先花两分钟确认一套硬性要求。CentOS 7 下跑 SonarQube 9.9官方明确要求 JDK 17不能拿 8 或 11 硬顶启动时会直接报版本不兼容。内存方面我建议至少 4GB 可用内存否则 Elasticsearch 组件一启动就容易被系统杀掉尤其是 Java 进程的默认堆设置是物理内存的一半小内存机器要手动调整。CPU 双核够用但如果你准备接入大量项目和频繁做全量扫描四核更稳妥。部署架构上也提一句9.9 LTS 支持内置 H2 数据库仅适合快速体验生产环境一定要外接 PostgreSQL官方推荐 13-15 版本后面我会给出具体操作。整个安装流程拆成四步装 JDK、装数据库、下载并配置 SonarQube、用 systemd 托管服务。把每一步做扎实整个安装过程大概半小时搞定如果遇到问题照着本文的排查清单逐项核对即可。提示我在下文用到的目录统一为 /opt/sonarqube数据目录由安装包内部分配用户统一用 sonar 系统账户运行。生产环境不建议用 root 直接跑 SonarQube后面会解释原因。2. 环境配置与依赖处理这一节是安装过程中最容易踩坑的地方很多人卡在启动失败倒不是 SonarQube 本身的问题而是底层系统参数没调好。我按顺序拆开讲。2.1 JDK 17 安装与验证CentOS 7 自带的 yum 源通常只有 OpenJDK 1.8 或 11所以直接 yum 安装拿不到 17。两个办法一个是下载官方 RPM 包手动安装另一个是用 tar.gz 解压到指定目录。我个人习惯用 tar.gz因为不污染系统全局卸载也方便。# 创建 JDK 存放目录 mkdir -p /usr/local/java cd /usr/local/java # 下载 OpenJDK 17以 x64 架构为例 wget https://download.java.net/java/GA/jdk17.0.2/dfd4a8d0985749f896bed50d7138ee7f/8/GPL/openjdk-17.0.2_linux-x64_bin.tar.gz # 解压并重命名 tar -zxvf openjdk-17.0.2_linux-x64_bin.tar.gz mv jdk-17.0.2 jdk17 # 写入环境变量 cat /etc/profile EOF export JAVA_HOME/usr/local/java/jdk17 export PATH$JAVA_HOME/bin:$PATH EOF # 立即生效并验证 source /etc/profile java -version这里有个细节如果你用的服务器是 ARM 架构比如华为鲲鹏下载链接要把 x64 换成 aarch64否则会报 cannot execute binary file。另外写 /etc/profile 是给交互式 shell 用的后面配置 systemd 服务时还需要在 service 文件里单独指定 JAVA_HOME别只依赖这个全局变量。2.2 系统内核参数与资源限制SonarQube 内置 Elasticsearch对系统参数非常敏感最经典的报错是max virtual memory areas vm.max_map_count [65530] is too low。CentOS 7 默认值就是 65530必须调大。# 临时生效 sysctl -w vm.max_map_count262144 # 永久生效 echo vm.max_map_count262144 /etc/sysctl.conf sysctl -p此外还要调整文件描述符限制和线程数限制。用 root 执行下面命令创建 limits 配置cat /etc/security/limits.conf EOF sonar - nofile 65536 sonar - nproc 4096 EOF这两项如果漏掉启动日志里会出现Too many open files或max number of threads之类的报错。注意-表示同时设置软限制和硬限制用sonar而不是通配符避免影响其他用户。2.3 PostgreSQL 安装与初始化9.9 LTS 官方支持 PostgreSQL 13-15CentOS 7 默认源里的版本偏低建议用 PostgreSQL 官方源装 13稳定且兼容性好。# 安装 PostgreSQL 官方源 yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm # 安装 PostgreSQL 13 yum install -y postgresql13-server postgresql13-contrib # 初始化数据库 /usr/pgsql-13/bin/postgresql-13-setup initdb # 启动并设置开机自启 systemctl start postgresql-13 systemctl enable postgresql-13接下来创建 SonarQube 使用的数据库和用户。注意密码别用太简单的生产环境建议随机生成强密码。# 切换到 postgres 系统用户 su - postgres # 进入 psql 命令行 psql # 在 psql 中执行以下 SQL CREATE USER sonar WITH PASSWORD sonar_passwd; CREATE DATABASE sonar OWNER sonar; GRANT ALL PRIVILEGES ON DATABASE sonar TO sonar; \q执行完成后验证一下能否用 sonar 用户登录psql -U sonar -d sonar -h 127.0.0.1 -W这一步很关键因为 SonarQube 的 sonar.properties 里如果配置 localhost 连接PostgreSQL 默认只监听 127.0.0.1。如果后面连接报错优先检查 pg_hba.conf 里的认证方式。提示安装完记得把 postgresql 的密码保存到密码管理器里后续 SonarQube 升级、备份恢复数据库都要用到。忘记密码虽然可以重设但没必要给自己挖坑。3. 核心实操SonarQube 下载与配置环境准备做完剩下的安装步骤就顺了。提前说一句SonarQube 安装包分为社区版、开发者版、企业版和数据中心版本文用的是社区版功能上已经覆盖大部分团队的日常需求。3.1 下载与目录规划# 创建安装目录并下载 9.9 LTS 社区版安装包 mkdir -p /opt cd /opt wget https://binaries.sonarsource.com/Distribution/sonarqube/sonarqube-9.9.8.100196.zip # 安装解压工具如果还没有 unzip yum install -y unzip # 解压 unzip sonarqube-9.9.8.100196.zip # 重命名方便后续升级替换 mv sonarqube-9.9.8.100196 sonarqube为什么不直接解压在 /root 下因为 SonarQube 不允许用 root 用户启动即使你把目录权限放开它内部检测到 root 也会拒绝启动。因此需要新建一个普通系统用户并赋予目录权限。useradd -r sonar chown -R sonar:sonar /opt/sonarqube我习惯把安装目录的 owner 设为 sonar后续所有文件都由这个用户管理。如果团队有统一的部署目录规范改成别的路径也行只要保证配置文件和 data、logs、temp 目录可写即可。3.2 核心配置 sonar.properties 详解打开conf/sonar.properties主要改三块内容数据库连接、Web 服务端口、搜索引擎监听地址。# 数据库连接配置 sonar.jdbc.usernamesonar sonar.jdbc.passwordsonar_passwd sonar.jdbc.urljdbc:postgresql://127.0.0.1:5432/sonar # Web 服务配置 sonar.web.host0.0.0.0 sonar.web.port9000 sonar.web.javaOpts-Xmx2048m -Xms1024m # Elasticsearch 配置按需调整非必须 sonar.search.javaOpts-Xmx1024m -Xms1024m关于sonar.web.host默认是 0.0.0.0也就是监听所有网卡。如果你只打算本机访问改成 127.0.0.1 更安全如果需要给团队共享保持 0.0.0.0但务必在防火墙里限制来源 IP。sonar.web.javaOpts和sonar.search.javaOpts这两个参数在内存不够时非常重要。SonarQube 默认会按照物理内存大小自动分配 JVM 堆内存一个 8G 内存的机器可能 Web 进程、ES 进程各自吃掉 2G还没开始扫描内存就见底了。手动设置-Xmx是最直接的干预手段。3.3 首次启动与初始化启动之前先确认目录权限没问题然后用 sonar 用户执行启动脚本su - sonar -c /opt/sonarqube/bin/linux-x86-64/sonar.sh start如果启动后没有任何输出不代表成功要去看日志tail -f /opt/sonarqube/logs/sonar.log首次启动会做数据库初始化、创建表结构、加载插件通常需要 1-3 分钟。看到SonarQube is up类似的关键日志说明启动成功了。接着访问http://服务器IP:9000默认管理员账号是admin/admin首次登录会强制要求修改密码。注意启动过程如果只提示SonarQube is running不代表 Web 服务已经完全就绪。Elasticsearch 组件还在初始化时页面上会短暂报 503。别急等一下再看日志。3.4 用 systemd 管理服务sbin/sonar.sh可以用但它不是系统服务机器重启后不会自动拉起。生产环境我更推荐用 systemdcat /etc/systemd/system/sonarqube.service EOF [Unit] DescriptionSonarQube service Aftersyslog.target network.target postgresql-13.service [Service] Typeforking Usersonar Groupsonar ExecStart/opt/sonarqube/bin/linux-x86-64/sonar.sh start ExecStop/opt/sonarqube/bin/linux-x86-64/sonar.sh stop Restarton-failure LimitNOFILE65536 LimitNPROC4096 [Install] WantedBymulti-user.target EOF systemctl daemon-reload systemctl enable sonarqube systemctl start sonarqube这里把 Linux 的 limits 配置在 service 文件里又写了一遍是双保险。因为 systemd 管理的服务有时不一定走/etc/security/limits.conf直接在 unit 文件里声明LimitNOFILE和LimitNPROC是最稳妥的。有个小坑是Typeforking与 sonar.sh 的匹配。sonar.sh 启动后脚本本身会退出但后台进程仍在运行所以 fork 类型是契合的。如果你换成Typesimplesystemd 会误判服务退出导致重启循环。4. 常见问题排查实录安装 SonarQube 的过程中我遇到的典型问题基本集中在系统参数、权限和内存三个方面。下面按症状和解决办法整理成速查表方便你对照处理。症状可能原因解决办法启动后 sonar.log 显示max virtual memory areas vm.max_map_count [65530] is too low内核参数未调大执行sysctl -w vm.max_map_count262144并写入 /etc/sysctl.conf日志报can not run elasticsearch as root用 root 启动了服务创建 sonar 用户并用su - sonar -c启动日志报no write permission to /opt/sonarqube/data目录 owner 不对执行chown -R sonar:sonar /opt/sonarqube日志报Process exited with 1或Error occurred during initialization of VMJVM 堆内存设置过大物理内存不足降低 sonar.web.javaOpts 和 sonar.search.javaOpts 中的 -Xmx 参数Web 页面能打开但执行分析时FAILED ... status401token 未配置或已过期在 SonarQube 后台生成新的分析 token替换 CI 配置数据库连接报FATAL: password authentication failedPostgreSQL 用户密码不匹配或 pg_hba.conf 限制核对密码检查 pg_hba.conf 是否允许 md5/scram 认证端口 9000 无法访问防火墙或 SELinux 拦截放行端口firewall-cmd --permanent --add-port9000/tcp firewall-cmd --reload或调整 SELinux 策略下面挑几个高频问题展开说一下。4.1 Elasticsearch 启动失败内存与文件描述符SonarQube 内置的 ES 对内存限制非常严格一方面不能超过系统物理内存的一半否则启动时直接报错另一方面如果机器本身内存太小OOM Killer 会在刚启动时把它杀掉。你可以在日志中看到Killed字样这种情况光调大-Xmx没用要么升级配置要么把 ES 堆内存压低。我的建议是 4G 内存机器上用-Xmx512m8G 用-Xmx1g给系统留足余量。另外日志中如果出现max file descriptors [4096] for elasticsearch process is too low说明 nofile 限制没生效。用ulimit -Hn检查当前值再用 2.2 的双保险配置重新拉起服务。4.2 启动后立即退出且无明确报错这种问题最让人头疼。排查思路是先看logs/es.log和logs/sonar.log的尾部几百行大部分隐藏信息都会在这里。常见的原因是数据库驱动问题新版 SonarQube 已经内置了 PostgreSQL 驱动所以不用手动拷贝 jar但如果连接串、用户名密码写错日志里会出现Connection refused或The server requested password-based authentication之类的提示。在调整配置后记得先停掉服务再删除data/es目录下的临时文件然后重启。这个目录存的是 ES 的索引缓存不是业务数据删掉不影响项目扫描结果但能解决某些索引损坏导致的启动异常。4.3 防火墙与 SELinux 导致访问异常CentOS 7 默认开启 firewalld如果你本机能 curl 通localhost:9000但外部机器访问不了先检查防火墙firewall-cmd --list-all firewall-cmd --permanent --add-port9000/tcp firewall-cmd --reloadSELinux 最好也别忽略。执行getenforce查看状态如果显示 Enforcing并且不想完全关闭可以给端口打标签semanage port -a -t http_port_t -p tcp 9000这个命令需要安装policycoreutils-python工具包如果提示找不到 semanage先装依赖。4.4 升级与迁移时的先备份再操作如果后续要从 9.9 小版本升级到更新的补丁版务必养成备份习惯。SonarQube 的数据主要存在 PostgreSQL 中文件系统层面的 data 目录也有插件、临时索引。升级前至少做一次数据库备份pg_dump -U sonar -h 127.0.0.1 -d sonar -F c -f /backup/sonar-$(date %F).dump然后停服务、备份整个 /opt/sonarqube不含 logs/data 中不必要的缓存或至少备份 conf 目录再替换安装包。千万别图省事直接覆盖旧目录插件配置很容易被抹掉。5. 安装完成后的验证与调优建议到这里SonarQube 已经能正常访问了。不过正式投入使用前建议再做几个验证和微调动作避免上线后频繁返工。5.1 验证系统健康状态登录管理后台点击Administration - System看各组件状态是否显示绿色。Compute Engine负责后台处理扫描结果如果挂了前端页面能看到任务但一直显示 pending。Elasticsearch存储项目索引和度量数据状态非绿色会导致搜索和仪表盘数据异常。Web Server就是访问入口本身正常时显示 UP。如果某个组件是红色点开右侧日志按钮直接查看对应组件的日志定位更快。5.2 修改管理员密码与生成令牌默认账号 admin 首次登录会强制改密但我见过有人跳过强制修改流程直接用 admin 去生成令牌。这是个安全隐患建议第一次登录就换强密码并且在后续 CI 集成中不再使用账号密码方式而是通过My Account - Security - Generate Token生成令牌。令牌生成后只显示一次记得立即复制保存到 CI 变量里。如果丢了删掉重新生成即可不影响历史数据。5.3 调整扫描器内存配置如果是用 SonarQube Scanner 在命令行或 CI 中扫描大型项目扫描器本身也需要内存。可以在conf/sonar-scanner.properties里设置sonar.sourceEncodingUTF-8 sonar.java.xmx2048m这里的sonar.java.xmx是给分析 JVM 用的不是 SonarQube 服务端 JVM别混淆。大型项目建议 2G 起步扫描过程中如果出现OutOfMemoryError优先调这个参数。5.4 与 CI/CD 集成的准备SonarQube 装好之后下一步通常是接 Jenkins 或 GitLab CI。这里提前说两点经验一是给 Jenkins 配置 SonarQube Scanner 时服务端 URL 和 token 要一一对应不要在多个项目里混用同一个 token排查问题时会很痛苦二是尽量开启sonar.branch.name等分支参数让 MR 场景下的增量分析更准确。这些内容展开讲又是一篇长文先把安装搞稳后续集成会顺畅很多。6. 我踩过的几个坑写出来给你避雷最后把这些年在安装和运维 SonarQube 时踩过的坑集中说一下不是教程里会写的内容但实际工作中特别容易遇到。第一千万别在资源紧张的情况下一次性打开好几个项目的后台分析任务。SonarQube 的计算引擎是串行处理的任务排队不仅慢还会让服务端内存飙升。如果团队扫描频率很高建议在 Jenkins 侧做好流水线节流别让 SonarQube 机器承受爆发性压力。第二数据库连接池别乱调。网上能看到各种调节 sonar.jdbc 连接池的特技但对 9.9 LTS 来说默认值已经适配绝大多数场景。乱改 maxPoolSize 这类参数反而可能造成 PostgreSQL 连接数打满应用报错更频繁。第三不要在晚上批量升级 SonarQube 插件。我吃过一次亏默认的插件市场在后台自动下载更新结果某些插件升级后和核心版本不兼容最终不得不回滚数据。现在我的做法是每次升级前先看 release notes确认兼容性再在非业务高峰执行升级。第四SELinux 如果完全关闭记得写进部署文档。团队里如果有多个人维护环境有人改了 SELinux 配置下次重启后 SonarQube 可能就莫名其妙访问不了排查半天最后发现是 setenforce 恢复成了 Enforcing。把这类系统级改动记录下来能省下不少沟通成本。安装这件事本身不难但每一步背后的原因值得琢磨透了再动手。希望这篇文章能让你少走一些弯路顺利把代码质量平台跑起来。