Skip to content
云间札记
Go back

SonarQube 26.3.0 生产部署:内存优化、分支扫描与 GitLab CI 集成

Updated:

背景

研发团队需要代码质量门禁,要求:

环境要求

项目配置
系统Amazon Linux 2023
JDK21(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

解决

改进措施

本文首发于 wr.mrchi.cn,转载请注明出处。



Previous Post
Kubernetes 部署 Nacos 2.4.0 集群:StatefulSet + NFS + MySQL 持久化
Next Post
TiDB 生产集群部署:医链商务端实时查询架构设计与性能优化