背景
研发团队需要代码质量门禁,要求:
- SonarQube 26.3.0 最新版本
- 支持多分支扫描(社区版无此功能)
- 集成 GitLab CI 自动扫描
- 低内存环境(4G)稳定运行
环境要求
| 项目 | 配置 |
|---|---|
| 系统 | Amazon Linux 2023 |
| JDK | 21(Amazon Corretto) |
| 内存 | 4G |
| 端口 | 9000 |
| 数据库 | PostgreSQL |
系统参数优化
cat >> /etc/sysctl.conf <<'EOF'
# ES & SonarQube 必需
fs.file-max = 131072
vm.max_map_count = 655360
vm.overcommit_memory = 1
vm.swappiness = 0
kernel.shmall = 4294967296
kernel.pid_max = 1000000
# TCP 高并发优化
net.core.somaxconn = 2048
net.core.rmem_max = 2097152
net.core.wmem_max = 2097152
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.tcp_window_scaling = 1
net.ipv4.ip_local_port_range = 1024 60999
EOF
sysctl -p
安装 JDK 21
sudo dnf install -y java-21-amazon-corretto-devel
# 切换默认 Java
sudo alternatives --config java
# 验证
java -version
# openjdk version "21.0.x" 202x-xx-xx LTS
SonarQube 部署
下载解压
cd /usr/local/src
wget https://binaries.sonarsource.com/Distribution/sonarqube/sonarqube-26.3.0.120487.zip
unzip sonarqube-26.3.0.120487.zip
mv sonarqube-26.3.0.120487 /opt/sonarqube
# 创建专用用户(不能用 root 启动)
useradd sonar
chown -R sonar:sonar /opt/sonarqube
内存优化配置
核心:极度压缩 JVM 内存,防止 OOM 崩溃
cat > /opt/sonarqube/conf/sonar.properties <<'EOF'
# 数据库配置
sonar.jdbc.username=sonar
sonar.jdbc.password=sonar@123
sonar.jdbc.url=jdbc:postgresql://localhost/sonarqube
# === 内存调优 (极度压缩,防 OOM 崩溃) ===
# Compute Engine: 512M
sonar.ce.javaOpts=-Xmx512m -Xms128m -XX:+HeapDumpOnOutOfMemoryError
# Web: 512M
sonar.web.javaOpts=-Xmx512m -Xms128m -XX:+HeapDumpOnOutOfMemoryError
# Elasticsearch: 1024M (ES 对内存极其敏感)
sonar.search.javaOpts=-Xmx1024m -Xms1024m -XX:MaxDirectMemorySize=256m -XX:+HeapDumpOnOutOfMemoryError
# Web 绑定
sonar.web.host=0.0.0.0
sonar.web.port=9000
sonar.es.startup.timeout=60000
sonar.search.httpTimeout=30000
EOF
chown -R sonar:sonar /opt/sonarqube
Systemd 服务
cat > /etc/systemd/system/sonarqube.service <<'EOF'
[Unit]
Description=SonarQube Service
After=network.target syslog.target
[Service]
Type=forking
User=sonar
Group=sonar
ExecStart=/opt/sonarqube/bin/linux-x86-64/sonar.sh start
ExecStop=/opt/sonarqube/bin/linux-x86-64/sonar.sh stop
ExecReload=/opt/sonarqube/bin/linux-x86-64/sonar.sh restart
Environment="SONAR_JAVA_PATH=/usr/lib/jvm/java-21-amazon-corretto/bin/java"
Restart=on-failure
RestartSec=5
LimitNOFILE=131072
LimitNPROC=8192
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable sonarqube.service
sudo systemctl start sonarqube.service
Nginx 代理
server {
listen 80;
server_name qa-sonar.kun.global;
# 大型工程代码推送扫描时防止 413
client_max_body_size 100M;
location / {
proxy_pass http://10.4.239.100:9000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# SonarQube 计算庞大分析包时延长超时
proxy_read_timeout 300s;
proxy_connect_timeout 300s;
proxy_send_timeout 300s;
proxy_buffering off;
}
}
分支扫描插件
社区版不支持分支扫描,需安装插件:
cd /usr/local/src
wget https://github.com/mc1arke/sonarqube-community-branch-plugin/releases/download/26.2.0/sonarqube-community-branch-plugin-26.2.0.jar
# 复制到两个目录
SONAR_HOME=/opt/sonarqube
cp sonarqube-community-branch-plugin-26.2.0.jar $SONAR_HOME/extensions/plugins/
cp sonarqube-community-branch-plugin-26.2.0.jar $SONAR_HOME/lib/extensions/
# 权限
chown -R sonar:sonar $SONAR_HOME/extensions/plugins/
chown -R sonar:sonar $SONAR_HOME/lib/extensions/
chmod 644 $SONAR_HOME/extensions/plugins/*.jar
chmod 644 $SONAR_HOME/lib/extensions/*.jar
配置插件注入
cat >> /opt/sonarqube/conf/sonar.properties <<'EOF'
# 注入 Web 进程代理
sonar.web.javaAdditionalOpts=-javaagent:./extensions/plugins/sonarqube-community-branch-plugin-26.2.0.jar=web
# 注入 Compute Engine 进程代理
sonar.ce.javaAdditionalOpts=-javaagent:./extensions/plugins/sonarqube-community-branch-plugin-26.2.0.jar=ce
EOF
替换前端包
cd /opt/sonarqube
mv web web_back
wget https://github.com/mc1arke/sonarqube-community-branch-plugin/releases/download/26.2.0/sonarqube-webapp.zip
unzip sonarqube-webapp.zip -d web
chown -R sonar:sonar /opt/sonarqube/web
systemctl restart sonarqube
SonarScanner CLI 安装
供 GitLab Runner 远程调用:
cd /usr/local/src
wget https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-8.0.1.6346-linux-x64.zip
unzip sonar-scanner-cli-8.0.1.6346-linux-x64.zip
mv sonar-scanner-8.0.1.6346-linux-x64 /opt/sonar-scanner
# 配置远程 SonarQube 服务器
cat > /opt/sonar-scanner/conf/sonar-scanner.properties <<'EOF'
sonar.host.url=http://10.4.239.100:9000
EOF
# 环境变量
echo 'export PATH=$PATH:/opt/sonar-scanner/bin' >> ~/.bashrc
source ~/.bashrc
# 验证
sonar-scanner --version
# SonarScanner CLI 8.0.1.6346
GitLab CI 集成示例
# .gitlab-ci.yml
sonarqube-check:
stage: test
image: registry.cn-shanghai.aliyuncs.com/mrchi/sonar-scanner:latest
variables:
SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar"
GIT_DEPTH: "0"
cache:
key: "${CI_JOB_NAME}"
paths:
- .sonar/cache
script:
- sonar-scanner
-Dsonar.projectKey=${CI_PROJECT_NAME}
-Dsonar.sources=.
-Dsonar.host.url=http://qa-sonar.kun.global
-Dsonar.login=${SONAR_TOKEN}
allow_failure: true
only:
- merge_requests
- master
- develop
复盘
问题根因:默认 JVM 配置在 4G 内存机器上频繁 OOM
解决:
- Web/CE 压缩至 512M
- ES 固定 1024M(不可再压缩)
- 增加 HeapDumpOnOutOfMemoryError 便于排查
改进措施:
- 内存使用监控告警
- 扫描任务队列限流
- 大项目分模块扫描策略
本文首发于 wr.mrchi.cn,转载请注明出处。