一、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

      查看数据库是否创建

Jenkins集成SonarQube实现代码质量检查_SonarQube

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

Jenkins集成SonarQube实现代码质量检查_SonarQube_02


Jenkins集成SonarQube实现代码质量检查_Jenkins_03


Jenkins集成SonarQube实现代码质量检查_Jenkins_04


六、管理SonarQube服务器

6.1 安装中文插件

Jenkins集成SonarQube实现代码质量检查_Jenkins_05

Jenkins集成SonarQube实现代码质量检查_SonarQube_06


Jenkins集成SonarQube实现代码质量检查_SonarQube_07


      此时查看插件路径发现多了一个插件

Jenkins集成SonarQube实现代码质量检查_Jenkins_08


6.2 权限管理​

​Sonarqube默认是不允许匿名访问的,需要给Jenkins创建相关访问令牌

点击配置->权限->用户,具体操作如下:​

Jenkins集成SonarQube实现代码质量检查_SonarQube_09

Jenkins集成SonarQube实现代码质量检查_SonarQube_10


七、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插件

    Jenkins集成SonarQube实现代码质量检查_Jenkins_11

    8.3.2 添加SonarQube的地址和验证令牌

    点击系统管理->系统配置,具体操作如下:

    Jenkins集成SonarQube实现代码质量检查_Jenkins_12

    Jenkins集成SonarQube实现代码质量检查_SonarQube_13

         由于SonarQube默认不允许匿名访问,还需要添加认证

    Jenkins集成SonarQube实现代码质量检查_SonarQube_14


    8.3.3 Jenkins添加Sonar Scanner扫描器​

    点击系统管理->全局工具配置,操作如下:

    Jenkins集成SonarQube实现代码质量检查_SonarQube_15

    8.3.4 Pipeline 集成 SonarQube 实现代码检测通知 Jenkins

          实现当Sonarqube检测失败时,不会继续进行后面的构建编译等步骤。

    1. 在 SonarQube 添加 Jenkins的回调接口

    在SonarQube上添加webhook(网络调用),以便于Jenkins通过SonarQube Quality Gate插件调用其"质量阈"信息,决定是否继续执行下面的构建步骤。       

    点击配置->网络调用->创建

    Jenkins集成SonarQube实现代码质量检查_SonarQube_16

    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.查看构建结果

    Jenkins集成SonarQube实现代码质量检查_Jenkins_17


    Jenkins集成SonarQube实现代码质量检查_Jenkins_18


    Jenkins集成SonarQube实现代码质量检查_SonarQube_19


    5.执行问题代码的构建

    SonarQube修改默认质量阈

    Jenkins集成SonarQube实现代码质量检查_Jenkins_20


    查看构建结果

    Jenkins集成SonarQube实现代码质量检查_Jenkins_21


    Jenkins集成SonarQube实现代码质量检查_SonarQube_22


    Jenkins集成SonarQube实现代码质量检查_Jenkins_23