• DevOps之持续集成SonarQube代码质量扫描


    一、SonarQube介绍

          SonarQube是一个用于代码质量检测管理的开放平台,可以集成不同的检测工具,代码分析工具,以及持续集成工具。SonarQube 并不是简单地把不同的代码检查工具结果直接显示在 Web 页面上,而是通过不同的插件对这些结果进行再加工处理,通过量化的方式度量代码质量的变化。
      SonarQube不仅提供了对 IDE 的支持,可以在Eclipse和IntelliJ IDEA这些工具里联机查看结果;同时 SonarQube 还对大量的持续集成工具提供了接口支持,可以很方便地在持续集成中使用SonarQube,另外Sonar的插件还可以对Java以外的其他编程语言提供支持。

    二、代码质量

    1.编码规范:是否遵守了编码规范,遵循了最佳实践。
    2.潜在的BUG:可能在最坏情况下出现问题的代码,以及存在安全漏洞的代码。
    3.文档和注释:过少(缺少必要信息)、过多(没有信息量)、过时的文档或注释。
    4.重复代码:违反了Don’tRepeat Yourself原则。
    5.复杂度:代码结构太复杂(如圈复杂度高),难以理解、测试和维护。
    6.测试覆盖率:编写单元测试,特别是针对复杂代码的测试覆盖是否足够。
    7.设计与架构:是否高内聚、低耦合,依赖最少。

    三、SonarQube部署

    1、部署SonarQube

    官方地址
    https://www.sonarqube.org/downloads/

     ①Sonar需要至少JDK 1.8及以上版本

    #解压上传的jdk#
    tar xf jdk-8u161-linux-x64.tar.gz -C /usr/local/
    ln -s /usr/local/jdk1.8.0_161 /usr/local/jdk
    ln -s /usr/local/jdk/bin/java /usr/bin/java
    #配置环境变量#
    vim /etc/profile
    export JAVA_HOME=/usr/local/jdk
    export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
    export PATH=$JAVA_HOME/bin:$PATH
    source  /etc/profile

    ②部署SonarQube数据库(mysql5.6 或者更高版本)

    wget http://dev.mysql.com/get/mysql-community-release-el7-5.noarch.rpm
    rpm -ivh mysql-community-release-el7-5.noarch.rpm
    yum install mysql-community-server
    systemctl start mysqld.service
    #初次安装mysql是root账户是没有密码的#
    set password for ‘root’@‘localhost’ = password('mypasswd');
    flush privileges;

    执行SQL语句

    CREATE DATABASE sonar CHARACTER SET utf8 COLLATE utf8_general_ci;
    GRANT ALL ON sonar.* TO 'sonar'@'localhost' IDENTIFIED BY 'sonar@pw';
    GRANT ALL ON sonar.* TO 'sonar'@'%' IDENTIFIED BY 'sonar@pw';
    FLUSH PRIVILEGES;

    配置Sonar数据库

    vim /usr/local/sonarqube/conf/sonar.properties
    
    sonar.web.host=0.0.0.0       #监听的IP地址
    sonar.web.port=9003          #监听的端口
    sonar.jdbc.username=sonar    #数据库用户名
    sonar.jdbc.password=sonar@pw #数据库密码
    sonar.jdbc.url=jdbc:mysql://192.168.29.176:3306/sonar?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&useConfigs=maxPerformance

    Oracle数据库

    手动复制驱动类到${SONAR_HOME}/extensions/jdbc-driver/oracle/目录下

    参考官方文档:http://docs.sonarqube.org/display/HOME/SonarQube+Platform

    ③启动SonarQube

    /usr/local/sonarqube/bin/linux-x86-64/sonar.sh start
    tail /usr/local/sonarqube/logs/sonar.log #日志文件

    Web页面登陆:http://IP:9003 默认为9000端口,默认用户名密码admin/admin

    ④SonarQube插件

    存放插件目录/usr/local/sonarqube/extensions/plugins/

    Sonar页面汉化:Chinese Pack

    2、SonarQube Scanner扫描器

    ①官方文档

    https://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner
    #Sonar通过Scanner(扫描器)来对代码进行质量分析#

    ②下载Scanner扫描器

    #上传插件包:sonar-scanner-2.8.zip#
    unzip sonar-scanner-2.8.zip
    mv sonar-scanner-2.8 /usr/local/
    ln -s /usr/local/sonar-scanner-2.8/ /usr/local/sonar-scanner

    ③SonarQube集成Scanner

    vim /usr/local/sonar-scanner/conf/sonar-scanner.properties
    sonar.host.url=http://192.168.29.175:9006    #sonar地址
    sonar.sourceEncoding=UTF-8                   #字符集
    sonar.jdbc.username=sonar                    #数据库账号
    sonar.jdbc.password=sonar@pw                 #数据库密码
    sonar.jdbc.url=jdbc:mysql://192.168.29.175:3306/sonar?useUnicode=true&characterEncoding=utf8    #数据库连接地址

    ④项目代码库测试

    github:https://github.com/SonarSource/sonar-examples 
    下载软件包:https://github.com/SonarSource/sonar-examples/archive/master.zip

    ⑤项目代码下配置sonar-project.properties

    sonar.projectKey=
    sonar.projectName=#这个名称会显示在Sonar的web页面
    sonar.projectVersion=
    sonar.sources=.   #源码路径
    sonar.language=java
    sonar.sourceEncoding=UTF-8

    ⑥代码质量扫描

    #进入到项目下执行#
    /usr/local/sonar-scanner/bin/sonar-scanner

    部分扫描Log信息

    INFO: Java Main Files AST scan (done) | time=28351ms
    INFO: Java Test Files AST scan
    INFO: 0 source files to be analyzed
    INFO: 502/502 source files have been analyzed
    INFO: Java Test Files AST scan (done) | time=0ms
    INFO: Sensor JavaSquidSensor [java] (done) | time=28795ms
    INFO: Sensor NoSonar Sensor [php]
    INFO: Sensor NoSonar Sensor [php] (done) | time=0ms
    INFO: Sensor CoberturaSensor [cobertura]
    INFO: 0/0 source files have been analyzed
    WARN: Cobertura report not found at /app/idc/apps/jenkins/work/workspace/12ctb_thematic_web/target/site/cobertura/coverage.xml
    INFO: Sensor CoberturaSensor [cobertura] (done) | time=1ms
    INFO: Sensor Coverage Report Import [csharp]
    INFO: Sensor Coverage Report Import [csharp] (done) | time=0ms
    INFO: Sensor Coverage Report Import [csharp]
    INFO: Sensor Coverage Report Import [csharp] (done) | time=0ms
    INFO: Sensor Unit Test Results Import [csharp]
    INFO: Sensor Unit Test Results Import [csharp] (done) | time=0ms
    INFO: Sensor SurefireSensor [java]
    INFO: parsing /app/idc/apps/jenkins/work/workspace/12ctb_thematic_web/target/surefire-reports
    INFO: Sensor SurefireSensor [java] (done) | time=1ms
    INFO: Sensor JaCoCoSensor [java]
    INFO: JaCoCoSensor: JaCoCo report not found : /app/idc/apps/jenkins/work/workspace/12ctb_thematic_web/target/jacoco.exec
    INFO: Sensor JaCoCoSensor [java] (done) | time=1ms
    INFO: Sensor JaCoCoItSensor [java]
    INFO: JaCoCoItSensor: JaCoCo IT report not found: /app/idc/apps/jenkins/work/workspace/12ctb_thematic_web/target/jacoco-it.exec
    INFO: Sensor JaCoCoItSensor [java] (done) | time=0ms
    INFO: Sensor JaCoCoOverallSensor [java]
    INFO: Sensor JaCoCoOverallSensor [java] (done) | time=0ms
    INFO: Sensor XmlFileSensor [java]
    INFO: Sensor XmlFileSensor [java] (done) | time=2ms
    INFO: Sensor Analyzer for "php.ini" files [php]

    3、Jenkins集成SonarQube

    ①安装插件:SonarQube Scanner

    Jenkins-系统管理-插件管理

    ②Jenkins集成Sonar

     4、SonarQube遇到的问题

    ①ERROR: Error during SonarQube Scanner execution

    ERROR: Error during SonarQube Scanner execution
    org.sonar.squidbridge.api.AnalysisException: Please provide compiled classes of your project with sonar.java.binaries property
        at org.sonar.java.JavaClasspath.init(JavaClasspath.java:59)
        at org.sonar.java.AbstractJavaClasspath.getElements(AbstractJavaClasspath.java:281)
        at org.sonar.java.SonarComponents.getJavaClasspath(SonarComponents.java:141)
        at org.sonar.java.JavaSquid.<init>(JavaSquid.java:83)
        at org.sonar.plugins.java.JavaSquidSensor.execute(JavaSquidSensor.java:83)
        at org.sonar.scanner.sensor.SensorWrapper.analyse(SensorWrapper.java:53)
        at org.sonar.scanner.phases.SensorsExecutor.executeSensor(SensorsExecutor.java:88)
        at org.sonar.scanner.phases.SensorsExecutor.execute(SensorsExecutor.java:82)
        at org.sonar.scanner.phases.SensorsExecutor.execute(SensorsExecutor.java:68)
        at org.sonar.scanner.phases.AbstractPhaseExecutor.execute(AbstractPhaseExecutor.java:88)
        at org.sonar.scanner.scan.ModuleScanContainer.doAfterStart(ModuleScanContainer.java:177)
        at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:135)
        at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:121)
        at org.sonar.scanner.scan.ProjectScanContainer.scan(ProjectScanContainer.java:291)
        at org.sonar.scanner.scan.ProjectScanContainer.scanRecursively(ProjectScanContainer.java:286)
        at org.sonar.scanner.scan.ProjectScanContainer.doAfterStart(ProjectScanContainer.java:264)
        at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:135)
        at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:121)
        at org.sonar.scanner.task.ScanTask.execute(ScanTask.java:48)
        at org.sonar.scanner.task.TaskContainer.doAfterStart(TaskContainer.java:84)
        at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:135)
        at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:121)
        at org.sonar.scanner.bootstrap.GlobalContainer.executeTask(GlobalContainer.java:121)
        at org.sonar.batch.bootstrapper.Batch.doExecuteTask(Batch.java:116)
        at org.sonar.batch.bootstrapper.Batch.executeTask(Batch.java:111)
        at org.sonarsource.scanner.api.internal.batch.BatchIsolatedLauncher.execute(BatchIsolatedLauncher.java:62)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.sonarsource.scanner.api.internal.IsolatedLauncherProxy.invoke(IsolatedLauncherProxy.java:60)
        at com.sun.proxy.$Proxy0.execute(Unknown Source)
        at org.sonarsource.scanner.api.EmbeddedScanner.doExecute(EmbeddedScanner.java:233)
        at org.sonarsource.scanner.api.EmbeddedScanner.runAnalysis(EmbeddedScanner.java:151)
        at org.sonarsource.scanner.cli.Main.runAnalysis(Main.java:110)
        at org.sonarsource.scanner.cli.Main.execute(Main.java:74)
        at org.sonarsource.scanner.cli.Main.main(Main.java:61)
    ERROR: 
    ERROR: Re-run SonarQube Scanner using the -X switch to enable full debug logging.
    [Pipeline]

    解决:SonarQube6.7.6版本下面的sonar-java插件为 sonar-java-plugin-4.15.0.12310.jar

    更换为其他版本:sonar-java-plugin-4.3.0.7717.jar

    插件地址:

    https://github.com/SonarSource/sonar-java

    ②Sonar - OutOfMemoryError: Java heap space

    #在sonar.properties文件中排除对一些无用扩展名文件进行扫描
    sonar.exclusions=**/*.doc,**/*.docx,**/*.ipch
    
    #SonarQube Scanner 2.5以上的版本修改扫描器参数
    export SONAR_SCANNER_OPTS="-Xmx3062m -XX:MaxPermSize=512m -XX:ReservedCodeCacheSize=128m"
  • 相关阅读:
    Linux sed命令
    Linux之read命令使用
    Linux shell之数组
    Linux Shell脚本攻略:shell中各种括号()、(())、[]、[[]]、{}的作用
    shell中的${},##, %% , :- ,:+, ? 的使用
    hostname命令
    进度条的制作-python
    33 Python 详解命令解析
    Python 学习笔记 多进程 multiprocessing--转载
    Spring注解(生命周期)
  • 原文地址:https://www.cnblogs.com/yanxinjiang/p/10279627.html
Copyright © 2020-2023  润新知