在DevOps实践中,代码质量是确保软件持续交付和高效运维的关键要素。SonarQube,作为一款强大的代码审查工具,凭借其丰富的语言支持、全面的质量检查能力和高度的集成性,在软件质量分析领域占据领先地位。本文将深入探讨SonarQube在DevOps工程技术价值流中的应用,并通过实战案例展示其如何助力企业有效应对技术债务危机,提升软件整体质量。
一、技术债务危机的终结者
软件质量分为内部质量和外部质量。内部质量涉及代码和设计的质量,可通过最佳实践、持续一致的开发和交付流程来提升。外部质量则通过验收测试等使用过程来度量。内部质量不佳会长期影响外部质量,导致技术债务累积,开发时间延长。
技术债务危机主要分为两类:无意识债务(如初级开发者编写的低质量代码)和有意识债务(团队为快速解决问题而采用的拙劣设计)。这些危机主要表现为重复代码、糟糕的复杂性分布、设计风格问题、缺乏单元测试、代码标准缺失、潜在bug、注释不当等。
为应对这些危机,企业可在DevOps建设过程中,基于持续集成的代码构建和自动化分析,通过多个维度评价代码设计的内部质量。SonarQube正是这样一款质量度量平台,它可对代码复杂度、重复度、代码风格、单元测试、测试覆盖率等进行持续监控,促进技术债务的及时处理,提高软件系统的总体开发运维效益。
二、强大的代码质量管理平台
SonarQube是一款开源的代码质量管理平台,支持超过25种编程语言,提供重复代码、编码标准、单元测试、代码覆盖率、代码复杂度、潜在bug、注释和软件设计等多维度的质量报告。其特性包括:
-
支持多种编程语言:满足跨语言开发团队的需求。
-
全面的质量检查:通过插件集成Findbugs、Checkstyle等工具,检测潜在缺陷。
-
历史记录与趋势分析:提供指标历史记录、计划图和微分查看,帮助团队追踪质量改进情况。
-
高度集成性:与Maven、Ant、Gradle等构建工具以及Jenkins等持续集成平台无缝集成。
-
开发环境集成:支持Eclipse、IDEA等主流IDE,实现本地代码分析。
-
外部工具集成:与JIRA、Mantis、LDAP、Fortify等外部工具集集成,方便问题跟踪和管理。
-
插件扩展性:支持自定义插件开发,满足特定需求。
三、SonarQube架构与工作流程
1 SonarQube架构
SonarQube采用服务器/客户端架构,由四个核心组件组成:SonarQube Server、SonarQube Database、SonarQube Plugins和SonarQube Scanner。它们共同协作,实现代码质量的持续监控和改进。
-
SonarQube Server:
-
SonarQube Web服务器:供开发者、管理人员浏览质量指标和进行SonarQube的配置
-
基于Elasticsearch的搜索
-
Compute Engine:负责处理代码分析报告并将其保存在SonarQube数据库中
-
-
SonarQube Database: 存储SonarQube的配置与质量报告,各种视图数据
-
SonarQube Plugins:SonarQube插件支持,包括开发语言,SCM,持续集成,安全认证等
-
SonarQube Scanner:在构建/持续集成服务器上运行一个或多个SonarScanner,以分析项目
(1)SonarQube Server有3个主要进程。
① Web Server:提供Web页面的服务,以供开发人员查看软件质量报告和配置实例。
② Search Server:提供Web页面中的搜索服务,基于Elasticsearch。
③ Compute Engine:计算引擎负责处理代码分析报告并将其保存在数据库中。
(2)Database Server用于存储平台的数据。
①源代码文件:包括代码文件的路径、大小、修改次数、版本控制信息等;
②代码分析结果:代码静态分析,检测代码中的潜在问题和缺陷,并将这些数据存储在数据库中,包括代码质量指标、代码规则、问题数量和严重程度等。
(3)Scanner是SonarQube的内置扫描工具,用于扫描源代码和依赖项,并将生成的代码中存在问题和缺陷的报告存入数据库。
2 SonarQube工作流程
SonarQube在进行代码质量管理时,从以下七个维度分析项目质量:架构、代码重复、单元测试、复杂度、潜在bug、编码规则和注释。为实现持续监测,需要数据库和持续集成工具(如Jenkins)的支持。
下图是使用 SonarQube 做代码持续审查的流程图:
-
本地分析:开发者在IDE中使用SonarLint进行本地代码分析,及时发现问题。
-
代码提交:开发者向SCM(如Git、SVN等)提交代码,触发持续集成流程。
-
自动构建与分析:持续集成平台(如Jenkins)自动构建项目,并通过SonarQube Scanner执行代码分析。
-
报告处理:持续集成平台将分析报告发送至SonarQube Server,由Compute Engine处理并生成可视化视图。
-
数据存储与展示:处理后的分析报告保存至数据库,开发者可在SonarQube UI查看、评论并管理问题。
-
问题管理:开发者通过解决问题来减少技术债务,提升代码质量。
-
数据导出与监控:SonarQube支持导出报表,使用API提取数据,并基于JMX进行深度监控和优化。
四、SonarQube安装
1 创建需要持久化的目录
mkdir -p /home/docker/sonar/{data,sonarqube_extensions}
2 获取镜像
docker pull sonarqube:10.6-community
3 编写docker docker-compose.yml
version: "3.1"
services:
db:
image: postgres
container_name: db
ports:
- 5432:5432
networks:
- sonarnet
environment:
POSTGRES_USER: sonar
POSTGRES_PASSWORD: sonar
volumes:
- db_data:/var/lib/postgresql/data
sonarqube:
image: sonarqube:10.6-community
container_name: sonarqube
depends_on:
- db
ports:
- "9000:9000"
networks:
- sonarnet
environment:
SONAR_JDBC_URL: jdbc:postgresql://db:5432/sonar
SONAR_JDBC_USERNAME: sonar
SONAR_JDBC_PASSWORD: sonar
volumes:
- /home/docker/sonar/conf:/opt/sonarqube/conf # 配置文件的持久化卷
- /home/docker/sonar/extensions:/opt/sonarqube/extensions # 扩展插件的持久化卷
- /home/docker/sonar/logs:/opt/sonarqube/logs # 日志文件的持久化卷
- /home/docker/sonar/data:/opt/sonarqube/data # 数据的持久化卷
networks:
sonarnet:
driver: bridge
volumes:
db_data:
driver: local
sonarqube_data:
driver: local
sonarqube_extensions:
driver: local
sonarqube_logs:
driver: local
4 启动容器
docker-compose up -d
5 设置sysctl.conf文件信息
为了优化SonarQube在Docker中的运行,需要修改Linux系统的sysctl.conf
文件,以调整虚拟内存的数量。有助于防止SonarQube(特别是其内置的Elasticsearch)因资源限制而运行失败。
在/etc/sysctl.conf
文件中添加或修改以下行:
vm.max_map_count=262144
然后运行sysctl -p
命令以使更改生效。这个设置增加了虚拟内存映射的数量,这对于Elasticsearch(SonarQube在7.9版本及以后内置的搜索引擎)来说是非常重要的。
6 访问Sonar Qube首页
-
访问SonarQube登录页面:
-
打开浏览器,在地址栏输入
http://localhost
:port(或实际配置的IP地址和端口号)进入SonarQube的登录页面。
-
-
登录并修改密码:
-
使用默认的用户名(admin)和密码(admin)登录。
-
登录成功后,系统会提示修改默认密码。按照页面上的提示,输入当前密码(admin)、新密码以及确认新密码。
-
点击“Change password”按钮保存修改。
-
7 插件安装
7.1 中文插件
7.1.1 通过管理界面安装插件
7.1.2 手动下载插件
-
如果通过Marketplace安装失败,可以手动下载插件。打开终端(Linux命令行界面)。
-
使用
wget
命令下载插件:
wget https://github.com/xuhuisheng/sonar-l10n-zh/releases/download/sonar-l10n-zh-plugin-10.6/sonar-l10n-zh-plugin-10.6.jar
-
确保下载的文件名为
sonar-l10n-zh-plugin-10.6.jar
,并且文件将复制到SonarQube的extensions/plugins
。
7.1.3 重启SonarQube服务
安装成功后,会查看到重启按钮,点击即可
7.1.4 重启后查看效果
7.2 安装多分支插件
#进入插件目录
cd sonarqube_extensions/plugins/
#下载插件
wget https://github.com/mc1arke/sonarqube-community-branch-plugin/releases/download/1.23.0/sonarqube-community-branch-plugin-1.23.0.jar
#切换到配置文件目录
cd /home/docker/sonar/conf
#编辑配置文件
vi sonar.properties
#添加以下配置(注意版本号要和插件一致)
sonar.web.javaAdditionalOpts=-javaagent:./extensions/plugins/sonarqube-community-branch-plugin-1.23.0.jar=web
sonar.ce.javaAdditionalOpts=-javaagent:./extensions/plugins/sonarqube-community-branch-plugin-1.23.0.jar=ce
#重启sonarqube
docker restart sonarqube
8 安装Scanner
8.1 下载和解压
# 下载SonarQube Scanner
wget https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-6.2.0.4584.zip
# 解压下载的zip文件
unzip sonar-scanner-cli-6.2.0.4584.zip -d /home/docker/sonar/scanner
8.2 设置环境变量
# 设置SonarQube Scanner环境变量
export SONAR_SCANNER_HOME=/home/docker/sonar/scanner/sonar-scanner-cli-6.2.0.4584
export PATH=$SONAR_SCANNER_HOME/bin:$PATH
注意:如果你的JDK版本比较低,如果是1.8安装6.2.0.4584版本不匹配,要求至少jdk17,要么降级sonarqube及sonarsanner版本,要么用docker安装sonarsanner ,还有可以安装jdk17,在sonarscanner的启动脚本中增加
export SONAR_SCANNER_HOME=/home/docker/sonar/scanner/sonar-scanner-cli-6.2.0.4584
export PATH=$SONAR_SCANNER_HOME/bin:$PATH
8.3 测试安装
sonar-scanner -v
8.4 Jenkins安装SonarQube插件
-
登录Jenkins管理界面。
-
进入“Manage Jenkins” > “Manage Plugins”。
-
在“Available”标签页中搜索“SonarQube Scanner”。
-
选中插件并点击“Install without restart”或“Download now and install after restart”。
8.5 Jenkins配置SonarQube服务器
-
在Jenkins管理界面,进入“Manage Jenkins” > “Configure System”。
-
向下滚动到“SonarQube servers”部分。
-
添加一个新的SonarQube服务器,填写服务器URL和令牌(Token)。令牌通常需要从SonarQube Web界面生成。
8.6 Jenkins配置SonarQube Scanner
-
仍在“Manage Jenkins” > “Configure System”中。
-
找到“SonarQube Scanners”部分。
-
添加一个新的SonarQube Scanner,通常只需指定名称和安装路径(即
$SONAR_SCANNER_HOME
)。
五、SonarQube系统集成
SonarLint+gitlib+jenkins+SonarQube
5.1 SonarLint:在IDE中即时反馈代码质量
SonarLint是一个强大的IDE插件,它能够在您键入代码时提供即时反馈。为了最大化其效果,以下是一些优化建议:
-
同步SonarLint与SonarQube: 确保SonarLint插件与SonarQube服务器保持同步,以便IDE中的规则与SonarQube上的规则一致。这可以通过在SonarLint中配置SonarQube服务器URL和登录令牌来实现。
-
配置代码质量阈值: 在IDE中设置适当的代码质量阈值,以便在代码质量低于此阈值时给出警告或错误。这有助于开发人员及时发现问题并进行修复。
-
定期更新: 定期检查并更新SonarLint插件和SonarQube服务器上的规则库,以确保它们包含最新的最佳实践和安全问题。
5.2 GitLab触发Jenkins流水线
详见下列博客第三部分内容:
https://blog.youkuaiyun.com/heijunwei/article/details/144131612?spm=1001.2014.3001.5502
5.3 编辑构建jenkins流水线
pipeline {
agent any
stages {
stage('拉取Git代码') {
steps {
checkout([$class: 'GitSCM', branches: [[name: '*/master']], extensions: [], userRemoteConfigs: [[credentialsId: '', url: '']]])
}
}
stage('构建代码') {
steps {
sh '/var/jenkins_home/gradle/bin/gradle clean build -x test'
}
}
stage('检测代码质量') {
steps {
sh '/home/docker/sonar/scanner/sonar-scanner-6.2.0.4584/bin/sonar-scanner -Dsonar.sources=./ -Dsonar.projectname=${JOB_NAME} -Dsonar.projectKey=${JOB_NAME} -Dsonar.java.binaries=build/classes/java/main -Dsonar.login=xxxxxxxxxxxxxxx'
}
}
}
}