SonarQube & SonarQube Scanner

CentOS MySQL SonarQube SonarQube Scanner

SonarQube 简介

  • SonarQube 能够提供对代码的一整套检查扫描和分析功能,拥有一套服务器端程序,然后再通过客户端或者别的软件的插件的形式完成对各开发环境和软件的支持。

  • 对编程语言的支持非常广泛,包括 C、C++、Java、Objective C、Python、JavaScript、PHP、C#、Swift、Erlang、Groovy 等众多语言
    提供了对 HTML、CSS、JSON、XML、CSV、SQL、JSP/JSF 等类型的文档的支持

  • 提供了以 FindBugs、PMD、CheckStyle 方式执行代码分析和测试检查的功能

  • 登录认证方式支持 LDAP、Bitbucket、Azure Active Directory(AAD)、Crowd 等方式

  • 提供了优美的 3D 视图方式下查看代码分析和测试结果报告

SonarQube 能带来什么???

➢ 糟糕的复杂度分布:文件、类、方法等,如果复杂度过高将难以改变,这会使得开发人员难以理解它们,且如果没有自动化的单元测试,对于程序中的任何组件的改变都将可能导致需要全面的回归测试

➢ 重复:显然程序中包含大量复制粘贴的代码是质量低下的,sonar 可以展示源码中重复严重的地方

➢ 缺乏单元测试:sonar 可以很方便地统计并展示单元测试覆盖率

➢ 没有代码标准:sonar 可以通过 PMD、CheckStyle、Findbugs 等等代码规则检测工具规范代码编写

➢ 没有足够的或者过多的注释:没有注释将使代码可读性变差,特别是当不可避免地出现人员变动时,程序的可读性将大幅下降。而过多的注释又会使得开发人员将精力过多地花费在阅读注释上,亦违背初衷

➢ 潜在的 bug:sonar 可以通过 PMD、CheckStyle、Findbugs 等等代码规则检测工具检测出潜在的 bug

SonarQube 环境搭建

Tip:我这里安装的 SonarQube 6.3.1,需要 JDK 1.8 以上的版本,MySQL 版本建议 5.6 以上,若 MySQL 版本高于 5.6 可以直接进行第四步

  • 第一步:升级数据库
    重要的事情说三遍:先备份旧数据库,先备份旧数据库,先备份旧数据库,然后再删除,再安装新的
    安装包下载之后,按照以下步骤操作
验证MD5:md5sum mysql57-community-release-el6-9.noarch.rpm    
        验证包的MD5,务必要和官方给出的保持一致,确认无误才行

接着执行:rpm -ivh mysql57-community-release-el6-9.noarch.rpm
        -i 是安装指令install的简写,-v是详尽模式verbose的简写,-h是打印要安装的包的Hash码(与-v组合使用)

        开始安装MySQL的发布包,这个过程会瞬间完成。输出类似于下面这样的信息:
        Preparing...                ########################################### [100%]
           1:mysql57-community-relea########################################### [100%]
  • 第二步:执行yum install -y mysql-community-client mysql-community-server(这个过程会需要一些时间)

  • 第三步:安装完成之后,打开/etc/my.cnf文件,在[mysqld]节点下增加如下两行👇,然后重新启动mysqld服务

character_set_server=utf8  
init_connect='SET NAMES utf8'
FAQ:
1.如果启动' mysqld '服务时卡在Installing validate password plugin:这个步骤过不去,可以先中止这个过程,解决方案如下:
    ➯ vim /etc/my.cnf
    ➯ 在[mysqld]这个节下面添加一行内容`validate_password=off`
      这是临时禁止密码验证插件,可以在以后需要的时候再配置即可。
      此时的数据库已经正常工作了,但是我们还不能使用
    ➯ vim /var/log/mysqld.log,找到类似于下面的内容:
      A temporary password is generated for root@localhost: -?i;XHTuh5eH
      这里的' -?i;XHTuh5eH '就是临时密码,
    ➯ 重新启动mysqld服务之后,输入:mysql -u root -p,回车,之后输入临时密码
    ➯ 成功登录到MySQL,此时再使用命令:alter user 'root'@'localhost' identified by '123';
      更新root用户的默认密码,5.6以后的版本安全机制增强了,临时密码只允许登录,不允许操作数据库,所以必须更改。
2.忘记登录密码,解决方案如下:
    ➯ vim /etc/my.cnf
    ➯ 在文件中`[mysqld]`下添加skip-grant-tables,如图所示:
    ➯ 登录mysql:mysql -uroot -p (直接点击回车,密码为空)
    ➯ 设置用户密码:update mysql.user set authentication_string=PASSWORD('123456') where user='root';
    ➯ 更新privilige:flush privileges;
    ➯ 退出:exit
    ➯ 删除在my.cnf文件中`skip-grant-tables`
    ➯ 重启:service mysqld restart
    -------------------------------------------------------------------------------------------------------------------------------------------
    | 第2个问题按照上面设置之后如果在登陆之后操作之后的时候,遇见如下错误👇
    | `ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement.` 
    | 解决方法:alter user 'root'@'localhost' IDENTIFIED with mysql_native_password AS '*0D3CED9BEC10A777AEC23CCC353A8C08A633045E';
    | 当之后重新设置密码时,遇见如下错误👇
    | `[ERROR 1819 (HY000): Your password does not satisfy the current policy requirements]`
    | 解决方法:输入 set global validate_password_policy=0;
    | 之后在设置密码就OK了,命令见`FAQ 2`设置用户密码,然后更新privilige
    | (正如上文所说,MySQL 5.6之后安全机制增强了,所以导致5.6之后的设置密码方式与之前不一样)
  • 第四步:创建sonar数据库及sonar用户及设置用户权限
➯ 创建数据库:
    CREATE DATABASE sonar CHARACTER SET utf8 COLLATE utf8_general_ci;
➯ 创建SonarQube Server访问数据库的用户:
    CREATE USER 'sonar' IDENTIFIED BY 'sonar';
➯ 配置SonarQube Server访问数据库用户的权限
    GRANT ALL ON sonar.* TO 'sonar'@'%' IDENTIFIED BY 'sonar';
    GRANT ALL ON sonar.* TO 'sonar'@'localhost' IDENTIFIED BY 'sonar';
➯ 更新权限:flush privileges;
 -------------------------
 Tip:
      flush privileges 命令本质上的作用是将当前user和privilige表中的用户信息/权限设
置从mysql库(MySQL数据库的内置库)中提取到内存里。MySQL用户数据和权限有修改后,希望在
"不重启MySQL服务"的情况下直接生效,那么就需要执行这个命令。通常是在修改ROOT帐号的设置
后,怕重启后无法再登录进来,那么直接flush之后就可以看权限设置是否生效,而不必冒太大风险
  • 第五步:更改SonarQube配置文件,打开SonarQube下的conf/sonar.properties,如下图👇

sonar.properties

取消注释,并按照如下图👇所示,填写内容,其中sonar.jdbc.url这一行只要取消注释就可以
sonar.properties

  • 第六步:进入SonarQube目录下的/bin/linux-x86-64运行:nohup bash sonar.sh start &注:高版本中不能用 root 用户启动 SonarQube,需用非 root 用户启动)
    Tip:nohup command &表示将进程放置后台运行,而对于linux-x86-64这个文件夹是根据你当前安装SonarQube的系统决定的,是哪个系统就进那个文件夹
  • 第七步:访问http://127.0.0.1:9000,如果不是本机就输入http://IP:9000接着你会看到如下图所示👇

SonarQube

接着点击Log in,默认账号:admin,密码:admin

Log in

登录之后,按如下操作安装中文插件

install Chinese Pack
Restart
大功告成

SonarQube Scanner 配置

  • 准备工作

  • 第一步:下载之后解压zip包,之后进入该目录的conf文件夹下,打开文件sonar-scanner.properties,如下图所示👇

sonar-scanner.properties

在文件中,将下面一行取消注释即可

# 如果是远程的话,请将localhost修改为远程机器的IP地址
sonar.host.url=http://localhost:9000
sonar-scanner.properties
  • 第二步:到工程根目录下新建文件sonar-project.properties,文件内容如下👇,文件中的参数配置,参考Sonar Analysis Parameters这篇文章
# 指定SonarQube instance必须是唯一的
sonar.projectKey=Jacoco
# 设置SonarQube UI显示的名称 
# PS:有人会问这里的名称是否可以是中文名称,我在网上搜索了好多资料都说是不可以的(至少我看到的资料都是)
#     后来自己尝试了一下,答案是可以写成中文的,但是要换一种方式,比如你想把项目名称命名为“测试”,
#     那么在这里就要写成“\u6d4b\u8bd5”,那么下面这个参数就应该这样写“sonar.projectName= \u6d4b\u8bd5”,
#     说白了就是将中文转成Unicode
sonar.projectName= Jacoco
sonar.projectVersion=1.0
sonar.language=java
# 指定src和classes文件夹位置,当然也可以是全路径,如果是当前工程根目录下用“.”表示也可以,比如“sonar.sources=.”
sonar.sources=src
sonar.java.binaries=target
# 下面的这两个参数作用是相同的,因为有时我们需要指定某个文件夹或者忽略某个文件夹
# sonar.inclusions=src1/**,src3/**
# sonar.exclusions=src2/**,src4/**
# 源码编码,默认是系统编码
sonar.sourceEncoding=UTF-8
# Set jacoco Configuration
# 指定代码覆盖率工具
sonar.core.codeCoveragePlugin=jacoco
# 指定exec二进制文件存放路径
sonar.jacoco.reportPaths=[yourPath/]jacoco.exec
# 以下属性可选择性加,当然也可以不加
sonar.dynamicAnalysis=reuseReports
sonar.jacoco.reportMissing.force.zero=false

Tip:可以将这里的知识结合Jacoco Code Coverage结合这篇的中的Demo工程实践一下,当然如果同时想要分析代码覆盖率的话你就要在下载Demo工程之后,运行mvn test生成exec二进制文件,并将exec文件的路径补全,当然如果找不到这个文件也不会报错,只是在SonarQube平台上看不到代码覆盖率

  • 第三步:第一和第二步完成之后,进入sonar-scanner-xxxconf目录下,你会发现两个文件sonar-scanner&sonar-scanner-debug,配置一下环境变量,如下所示👇
export SONAR_SCANNER_HOME=[yourSonarScannerPath/]
export PATH=$PATH:$SONAR_SCANNER_HOME/bin:PATH

Tip:配置好环境变量之后,source一下使之生效
然后从终端进入工程根目录,运行sonar-scanner你会看到如下日志👇

INFO: Scanner configuration file: /Users/zc/Downloads/sonarqube-6.3.1/extensions/plugins/sonar-scanner-3.0.1.733-macosx/conf/sonar-scanner.properties
INFO: Project root configuration file: /Users/zc/Desktop/jacoco/sonar-project.properties
INFO: SonarQube Scanner 3.0.1.733
INFO: Java 1.8.0_121 Oracle Corporation (64-bit)
INFO: Mac OS X 10.12.4 x86_64
INFO: User cache: /Users/zc/.sonar/cache
INFO: Load global settings
INFO: Load global settings (done) | time=54ms
INFO: User cache: /Users/zc/.sonar/cache
INFO: Load plugins index
INFO: Load plugins index (done) | time=4ms
INFO: Plugin [l10nzh] defines 'l10nen' as base plugin. This metadata can be removed from manifest of l10n plugins since version 5.2.
INFO: SonarQube server 6.3.1
INFO: Default locale: "zh_CN", source code encoding: "UTF-8"
INFO: Process project properties
INFO: Load project repositories
INFO: Load project repositories (done) | time=51ms
INFO: Load quality profiles
INFO: Load quality profiles (done) | time=12ms
INFO: Load active rules
INFO: Load active rules (done) | time=254ms
INFO: Load metrics repository
INFO: Load metrics repository (done) | time=45ms
WARN: SCM provider autodetection failed. No SCM provider claims to support this project. Please use sonar.scm.provider to define SCM of your project.
INFO: Publish mode
INFO: Project key: com.jacoco
INFO: -------------  Scan JacocoTest
INFO: Load server rules
INFO: Load server rules (done) | time=49ms
INFO: Language is forced to java
INFO: Initializer GenericCoverageSensor
INFO: Initializer GenericCoverageSensor (done) | time=0ms
INFO: Base dir: /Users/zc/Desktop/jacoco
INFO: Working dir: /Users/zc/Desktop/jacoco/.scannerwork
INFO: Source paths: src
INFO: Source encoding: UTF-8, default locale: zh_CN
INFO: Index files
INFO: 2 files indexed
INFO: Quality profile for java: Sonar way
INFO: Sensor JavaSquidSensor [aemrules]
INFO: Configured Java source version (sonar.java.source): none
INFO: JavaClasspath initialization
WARN: Bytecode of dependencies was not provided for analysis of source files, you might end up with less precise results. Bytecode can be provided using sonar.java.libraries property
INFO: JavaClasspath initialization (done) | time=8ms
INFO: JavaTestClasspath initialization
INFO: JavaTestClasspath initialization (done) | time=0ms
INFO: Java Main Files AST scan
INFO: 2 source files to be analyzed
INFO: Java Main Files AST scan (done) | time=367ms
INFO: Java Test Files AST scan
INFO: 2/2 source files have been analyzed
INFO: 0 source files to be analyzed
INFO: Java Test Files AST scan (done) | time=0ms
INFO: Sensor JavaSquidSensor [aemrules] (done) | time=780ms
INFO: 0/0 source files have been analyzed
INFO: Sensor SurefireSensor [aemrules]
INFO: parsing /Users/zc/Desktop/jacoco/target/surefire-reports
INFO: Sensor SurefireSensor [aemrules] (done) | time=49ms
INFO: Sensor JaCoCoSensor [aemrules]
WARN: Property 'sonar.jacoco.reportMissing.force.zero' is deprecated and its value will be ignored.
INFO: Analysing /Users/zc/Desktop/jacoco/target/coverage-reports/jacoco-unit.exec
INFO: No information about coverage per test.
INFO: Sensor JaCoCoSensor [aemrules] (done) | time=58ms
INFO: Sensor SonarJavaXmlFileSensor [aemrules]
INFO: Sensor SonarJavaXmlFileSensor [aemrules] (done) | time=0ms
INFO: Sensor Analyzer for "php.ini" files [php]
INFO: Sensor Analyzer for "php.ini" files [php] (done) | time=2ms
INFO: Sensor Zero Coverage Sensor
INFO: Sensor Zero Coverage Sensor (done) | time=11ms
INFO: Sensor Code Colorizer Sensor
INFO: Sensor Code Colorizer Sensor (done) | time=0ms
INFO: Sensor CPD Block Indexer
INFO: org.sonar.scanner.cpd.deprecated.JavaCpdBlockIndexer@6cf047cf is used for java
INFO: Sensor CPD Block Indexer (done) | time=17ms
INFO: No SCM system was detected. You can use the 'sonar.scm.provider' property to explicitly specify it.
INFO: Calculating CPD for 2 files
INFO: CPD calculation finished
INFO: Analysis report generated in 66ms, dir size=30 KB
INFO: Analysis reports compressed in 8ms, zip size=11 KB
INFO: Analysis report uploaded in 19ms
INFO: ANALYSIS SUCCESSFUL, you can browse http://localhost:9000/dashboard/index/com.jacoco
INFO: Note that you will be able to access the updated dashboard once the server has processed the submitted analysis report
INFO: More about the report processing at http://localhost:9000/api/ce/task?id=AVwlSI7NKkvX7ZORxf9W
INFO: Task total time: 2.584 s
INFO: ------------------------------------------------------------------------
INFO: EXECUTION SUCCESS
INFO: ------------------------------------------------------------------------
INFO: Total time: 13.546s
INFO: Final Memory: 50M/306M
INFO: ------------------------------------------------------------------------

接下来我们回到之前搭建好的SonarQube平台,看一下检测的结果,效果展示如下图👇

说明一下:
   上文运用的Sonar Sanner只是实现代码检测方式的其中之一而已,当然还有其它做法,比如直接在
pom.xml文件中引用sonar插件,但是我这里考虑的是与Jenkins做成持续集成,如果我选择在项目中添
加sonar-project.properties文件,这样能更方面与Jenkins结合

到这里基本上就结束了,下面就是将Jenkins与SonarQube集成,详见:Jenkins + SonarQube & SonarQube Scanner

如在阅读或者实践过程中遇到问题,欢迎下方留言

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,214评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,307评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,543评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,221评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,224评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,007评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,313评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,956评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,441评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,925评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,018评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,685评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,234评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,240评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,464评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,467评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,762评论 2 345

推荐阅读更多精彩内容