一、SonarQube简介
SonarQube 是一个开源平台,用于管理源代码的质量。Sonar 不只是一个质量数据报告工具,更是代码质量管理平台。支持Java、Python、C、C++、Go等多种语言。
SonarQube是一种自动代码审查工具,用于检测代码中的错误和代码异常,它集成到现有的工作流程,以便在项目分支和拉取请求之间进行连续的代码检查。此外SonarQube 支持多种插件,实现和Jenkins等CI&CD工具的集成。
主要特点如下:
- 代码覆盖:通过单元测试,将会显示哪行代码被选中
- 改善编码规则
- 搜寻编码规则:按照名字,插件,激活级别和类别进行查询
- 项目搜寻:按照项目的名字进行查询
- 对比数据:比较同一张表中的任何测量的趋势
二、七个维度检测代码质量
1. 可维护性(maintainability)
所谓“代码易维护”就是指,在不破坏原有代码设计、不引入新的bug的情况下,能够快速地修改或者添加代码。
2. 可读性(readability)
在编写代码的时候,时刻要考虑到代码是否易读、易理解。除此之外,代码的可读性在非常大程度上会影响代码的可维护性。看代码是否符合编码规范、命名是否达意、注释是否详尽、函数是否长短合适、模块划分是否清晰、是否符合高内聚低耦合等等。 code review 是一个很好的测验代码可读性的手段
3. 可扩展性(extensibility)
表示代码应对未来需求变化的能力。跟可读性一样,代码是否易扩展也很大程度上决定代码是否易维护。代码的可扩展性表示,在不修改或少量修改原有代码的情况下,通过扩展的方式添加新的功能代码
4. 灵活性(flexibility)
如果一段代码易扩展、易复用或者易用,都可以称这段代码写得比较灵活
5. 简洁性(simplicity)
KISS 原则:尽量保持代码简单。代码简单、逻辑清晰,也就意味着易读、易维护
6. 可复用性(reusability)
代码的可复用性可以简单地理解为,尽量减少重复代码的编写,复用已有的代码
7. 可测试性(testability)
代码可测试性的好坏,能从侧面上非常准确地反应代码质量的好坏。代码的可测试性差,比较难写单元测试,那基本上就能说明代码设计得有问题
三、SonarQube架构和集成
SonarQube四个主要组件分别介绍如下:
- SonarQube Server。包括三个主要部分:
- Web Server: UI 界面
- Search Server :为UI提供搜索功能,基于ElasticSearch实现
- Compute Engine Server:处理代码分析报告,并将之存储到 SonarQube Database。
- SonarQube Database: 负责存储 SonarQube 的配置,以及项目的质量快照等
- SonarQube Plugin: 可以在 SonarQube Server 安装丰富的插件,实现支持各种开发语言、SCM、集成、身份验证和治理等功能
- Code analysis Scanners: 代码扫描器,是SonarQube Server的客户端, 将代码扫描后得出报告提交给 SonarQube Server
四、SonarQube安装环境准备
#Java环境依赖
apt -y install openjdk-11-jdk
#系统内核优化
vim /etc/sysctl.conf
vm.max_map_count=262144 #此项必须修改,否则无法启动
fs.file-max=65536 #此项可不改,默认值满足要求
#创建SonarQube服务用户
useradd -s /bin/bash -m sonarqube
五、安装SonarQube服务器
5.1 数据库准备
5.1.1 安装和配置PostgreSql数据库
apt-get -y install postgresql
#修改监听地址支持远程连接
vim /etc/postgresql/12/main/postgresql.conf
listen_addresses = '0.0.0.0'
#开启远程访问
vim /etc/postgresql/12/main/pg_hba.conf
# IPv4 local connections:
host all all 127.0.0.1/32 md5
host all all 0.0.0.0/0 md5
之后重启postgresql
5.1.2 创建数据库和用户授权
#使用postgres用户登录(postgresql安装后该用户会自动创建)
su – postgres
#登录postgre数据库
psql -U postgres
#为了安全起见,修改数据库管理员postgres的密码
postgres=# ALTER USER postgres WITH ENCRYPTED PASSWORD '123456';
ALTER ROLE
#创建用户和数据库并授权
postgres=# CREATE USER sonar WITH ENCRYPTED PASSWORD '123456';
CREATE ROLE
postgres=# CREATE DATABASE sonarqube OWNER sonar;
CREATE DATABASE
postgres=# GRANT ALL PRIVILEGES ON DATABASE sonarqube TO sonar;
GRANT
查看数据库是否创建
5.2 下载SonarQube和修改配置文件
#下载
wget https://binaries.sonarsource.com/Distribution/sonarqube/sonarqube-8.9.10.61524.zip
#解压并移到适当路径下
unzip sonarqube-8.9.10.61524.zip
mv sonarqube-8.9.10.61524 /usr/local/sonarqube
#设置属性
chown -R sonarqube.sonarqube /usr/local/sonarqube
##设置SonarQube连接数据库
vim usr/local/sonarqube/conf/sonar.properties
#修改连接postgresql数据库的账号和密码,和前面的配置必须匹配
sonar.jdbc.username=sonar
sonar.jdbc.password=123456
#修改数据库相关的信息,这里必须和此前配置的postgresql内容相匹配,其中localhost为DB服务器的地址,而sonarqube为数据库名称 sonar.jdbc.url=jdbc:postgresql://localhost/sonarqube
#设置 SonarQube 的提供的 Web Server监听的地址和端口
sonar.web.host=0.0.0.0 #此为默认值,可不做修改
sonar.web.port=9000 #此为默认值,可不做修改
5.3 启动SonarQube
-
#用systemd方式启动SonarQube
vim /lib/systemd/system/sonarqube.service
[Unit]
Descriptinotallow=SonarQube service
After=syslog.target network.target
[Service]
Type=simple
User=sonarqube
Group=sonarqube
Permissinotallow=true
ExecStart=/usr/bin/nohup /usr/bin/java -Xms32m -Xmx32m -Djava.net.preferIPv4Stack=true -jar /usr/local/sonarqube/lib/sonar-application-8.9.10.61524.jar
StandardOutput=syslog
LimitNOFILE=65536
LimitNPROC=4096
TimeoutStartSec=5
Restart=always
[Install]
WantedBy=multi-user.target
之后执行如下命令:
systemctl daemon-reload
systemctl enable --now sonarqube
systemctl status sonarqube
5.4 登录web界面
访问http://SonarQube服务器ip:9000,用户名&密码均为admin
六、管理SonarQube服务器
6.1 安装中文插件
此时查看插件路径发现多了一个插件
6.2 权限管理
Sonarqube默认是不允许匿名访问的,需要给Jenkins创建相关访问令牌
点击配置->权限->用户,具体操作如下:
七、Jenkins服务器部署扫描器sonar-scanner
#在Jenkins服务器部署sonar-scanner
wget https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.8.0.2856-linux.zip
unzip sonar-scanner-cli-4.8.0.2856-linux.zip
mv sonar-scanner-4.8.0.2856-linux /usr/local/sonar-scanner
##配置sonar-scanner连接sonarqube服务器
vim /usr/local/sonar-scanner/conf/sonar-scanner.properties
#指向SonarQube服务器的地址和端口
sonar.host.url=http://xxx.xxx.xxx.xxx:9000
sonar.sourceEncoding=UTF-8
八、Jenkins Pipeline和SonarQube集成实现代码扫描
8.1 说明
Jenkins借助于SonarQube Scanner插件将SonarQube提供的代码质量检查能力集成到pipeline上,从而确保质量阈检查失败时,能够避免继续进行后续的操作,例如发布等。一般流程如下:
- Jenkins Pipeline启动
- SonarQube Scanner分析代码,并将报告发送至SonarQubeServer
- SonarQube Server分析代码检测的结果是否符合预定义的质量阈
- SonarQube Server将通过(passed)或者失败(failed)的结果发送回Jenkins上的SonarQube Scanner插件暴露的 Webhook
- 质量阈相关的阶段成功通过则Jenkins pipeline继续后面的Stage,否则Pipeline将终止
注意:生产环境下质量阈是由开发定义
8.2 SonarQube质量阈
质量阙是一组预定义的评估条件。当代码质量扫描结果可满足这组条件时,项目才会被标记为“passed”。管理员也可以在SonarQube上按需自定义并调用质量阈
8.3 Jenkins安装SonsrQube插件实现代码扫描
配置Jenkins使用sonar-scanner进行代码质量扫描,并将结果报告给SonarQube Server的主要步骤如下:
- 在 Jenkins上安装SonarQube插件
- 配置Jenkins对接到SonarQube Server
- 配置Jenkins的全局工具sonar-scanner
- 在SonarQube上添加回调Jenkins的Webhook
- 在Jenkins项目上调用sonar-scanner进行代码质量扫描
- 通过SonarQube确认扫描结果的评估
8.3.1 Jenkins安装SonarQube插件
8.3.2 添加SonarQube的地址和验证令牌
点击系统管理->系统配置,具体操作如下:
由于SonarQube默认不允许匿名访问,还需要添加认证
8.3.3 Jenkins添加Sonar Scanner扫描器
点击系统管理->全局工具配置,操作如下:
8.3.4 Pipeline 集成 SonarQube 实现代码检测通知 Jenkins
实现当Sonarqube检测失败时,不会继续进行后面的构建编译等步骤。
- 在 SonarQube 添加 Jenkins的回调接口
在SonarQube上添加webhook(网络调用),以便于Jenkins通过SonarQube Quality Gate插件调用其"质量阈"信息,决定是否继续执行下面的构建步骤。
点击配置->网络调用->创建
2.准备项目所需的Jenkinsfile文件
pipeline {
agent any
stages {
stage("SonarQube analysis"){
steps {
//注意:下面的SonarQube-Server和系统配置SonarQube installations的Name必须一致, 大小写敏感
withSonarQubeEnv("SonarQube-Server"){
sh 'mvn sonar:sonar'
}
}
}
stage("Quality Gate") {
steps {
//代码检测失败,将不再继续执行后面的任务,直接退出,报告返回的超时时长设为5分钟
timeout(time: 5,unit: 'MINUTES'){
waitForQualityGate abortPipeline: true
}
}
}
stage('Build') {
steps {
sh 'mvn clean package -Dmaven.test.skip=true'
}
}
stage('Test') {
steps {
echo "Test"
}
}
stage('Deploy') {
steps {
echo "Deploy"
}
}
}
post {
always {
mail to:"xxx@xx.com",
subject:"Status of pipeline: ${currentBuild.fullDisplayName}",
body:"${env.BUILD_URL} has result ${currentBuild.result}"
}
}
}
3.准备项目需要的sonar-project.properties文件
#项目的唯一标识
sonar.projectKey=sprint-boot-helloworld
#项目的名称,用于显示在 sonarqube web 界面
sonar.projectName=sprint-boot-helloworld
#项目版本
sonar.projectVersinotallow=1.0
#项目源码所在目录
sonar.sources=.
#项目源码编译生成的二进制文件路径
sonar.java.binaries=.
#编程语言
sonar.language=java
#编码格式
sonar.sourceEncoding=UTF-8
4.查看构建结果
5.执行问题代码的构建
SonarQube修改默认质量阈
查看构建结果