CentOS
MySQL
SonarQube
SonarQube Scanner
-
針對(duì) Jacoco + Jenkins + SonarQube & SonarQube Scanner 分為四個(gè)部分寫的硫麻,建議閱讀的順序?yàn)椋?/p>
- Jacoco Code Coverage
- Jenkins + Jacoco 持續(xù)集成代碼覆蓋率
- SonarQube & SonarQube Scanner ?
- Jenkins + SonarQube & SonarQube Scanner
SonarQube 簡(jiǎn)介
SonarQube 能夠提供對(duì)代碼的一整套檢查掃描和分析功能岸晦,擁有一套服務(wù)器端程序,然后再通過(guò)客戶端或者別的軟件的插件的形式完成對(duì)各開(kāi)發(fā)環(huán)境和軟件的支持空猜。
對(duì)編程語(yǔ)言的支持非常廣泛蓄诽,包括 C薛训、C++、Java仑氛、Objective C许蓖、Python、JavaScript调衰、PHP膊爪、C#、Swift嚎莉、Erlang米酬、Groovy 等眾多語(yǔ)言
提供了對(duì) HTML、CSS趋箩、JSON赃额、XML加派、CSV、SQL跳芳、JSP/JSF 等類型的文檔的支持提供了以 FindBugs芍锦、PMD、CheckStyle 方式執(zhí)行代碼分析和測(cè)試檢查的功能
登錄認(rèn)證方式支持 LDAP飞盆、Bitbucket娄琉、Azure Active Directory(AAD)、Crowd 等方式
提供了優(yōu)美的 3D 視圖方式下查看代碼分析和測(cè)試結(jié)果報(bào)告
SonarQube 能帶來(lái)什么吓歇?孽水??
? 糟糕的復(fù)雜度分布:文件城看、類女气、方法等,如果復(fù)雜度過(guò)高將難以改變测柠,這會(huì)使得開(kāi)發(fā)人員難以理解它們炼鞠,且如果沒(méi)有自動(dòng)化的單元測(cè)試,對(duì)于程序中的任何組件的改變都將可能導(dǎo)致需要全面的回歸測(cè)試
? 重復(fù):顯然程序中包含大量復(fù)制粘貼的代碼是質(zhì)量低下的轰胁,sonar 可以展示源碼中重復(fù)嚴(yán)重的地方
? 缺乏單元測(cè)試:sonar 可以很方便地統(tǒng)計(jì)并展示單元測(cè)試覆蓋率
? 沒(méi)有代碼標(biāo)準(zhǔn):sonar 可以通過(guò) PMD谒主、CheckStyle、Findbugs 等等代碼規(guī)則檢測(cè)工具規(guī)范代碼編寫
? 沒(méi)有足夠的或者過(guò)多的注釋:沒(méi)有注釋將使代碼可讀性變差软吐,特別是當(dāng)不可避免地出現(xiàn)人員變動(dòng)時(shí)瘩将,程序的可讀性將大幅下降吟税。而過(guò)多的注釋又會(huì)使得開(kāi)發(fā)人員將精力過(guò)多地花費(fèi)在閱讀注釋上凹耙,亦違背初衷
? 潛在的 bug:sonar 可以通過(guò) PMD、CheckStyle肠仪、Findbugs 等等代碼規(guī)則檢測(cè)工具檢測(cè)出潛在的 bug
SonarQube 環(huán)境搭建
Tip:我這里安裝的 SonarQube 6.3.1肖抱,需要 JDK 1.8 以上的版本,MySQL 版本建議 5.6 以上异旧,若 MySQL 版本高于 5.6 可以直接進(jìn)行第四步
- 第一步:升級(jí)數(shù)據(jù)庫(kù)
重要的事情說(shuō)三遍:先備份舊數(shù)據(jù)庫(kù)意述,先備份舊數(shù)據(jù)庫(kù),先備份舊數(shù)據(jù)庫(kù)吮蛹,然后再刪除荤崇,再安裝新的
安裝包下載之后,按照以下步驟操作
驗(yàn)證MD5:md5sum mysql57-community-release-el6-9.noarch.rpm
驗(yàn)證包的MD5潮针,務(wù)必要和官方給出的保持一致术荤,確認(rèn)無(wú)誤才行
接著執(zhí)行:rpm -ivh mysql57-community-release-el6-9.noarch.rpm
-i 是安裝指令install的簡(jiǎn)寫,-v是詳盡模式verbose的簡(jiǎn)寫每篷,-h是打印要安裝的包的Hash碼(與-v組合使用)
開(kāi)始安裝MySQL的發(fā)布包瓣戚,這個(gè)過(guò)程會(huì)瞬間完成端圈。輸出類似于下面這樣的信息:
Preparing... ########################################### [100%]
1:mysql57-community-relea########################################### [100%]
第二步:執(zhí)行
yum install -y mysql-community-client mysql-community-server
(這個(gè)過(guò)程會(huì)需要一些時(shí)間)第三步:安裝完成之后,打開(kāi)
/etc/my.cnf
文件子库,在[mysqld]
節(jié)點(diǎn)下增加如下兩行??舱权,然后重新啟動(dòng)mysqld
服務(wù)
character_set_server=utf8
init_connect='SET NAMES utf8'
FAQ:
1.如果啟動(dòng)' mysqld '服務(wù)時(shí)卡在Installing validate password plugin:這個(gè)步驟過(guò)不去,可以先中止這個(gè)過(guò)程仑嗅,解決方案如下:
? vim /etc/my.cnf
? 在[mysqld]這個(gè)節(jié)下面添加一行內(nèi)容`validate_password=off`
這是臨時(shí)禁止密碼驗(yàn)證插件宴倍,可以在以后需要的時(shí)候再配置即可。
此時(shí)的數(shù)據(jù)庫(kù)已經(jīng)正常工作了无畔,但是我們還不能使用
? vim /var/log/mysqld.log啊楚,找到類似于下面的內(nèi)容:
A temporary password is generated for root@localhost: -?i;XHTuh5eH
這里的' -?i;XHTuh5eH '就是臨時(shí)密碼,
? 重新啟動(dòng)mysqld服務(wù)之后浑彰,輸入:mysql -u root -p恭理,回車,之后輸入臨時(shí)密碼
? 成功登錄到MySQL郭变,此時(shí)再使用命令:alter user 'root'@'localhost' identified by '123';
更新root用戶的默認(rèn)密碼颜价,5.6以后的版本安全機(jī)制增強(qiáng)了,臨時(shí)密碼只允許登錄诉濒,不允許操作數(shù)據(jù)庫(kù)周伦,所以必須更改。
2.忘記登錄密碼未荒,解決方案如下:
? vim /etc/my.cnf
? 在文件中`[mysqld]`下添加skip-grant-tables专挪,如圖所示:
? 登錄mysql:mysql -uroot -p (直接點(diǎn)擊回車,密碼為空)
? 設(shè)置用戶密碼:update mysql.user set authentication_string=PASSWORD('123456') where user='root';
? 更新privilige:flush privileges;
? 退出:exit
? 刪除在my.cnf文件中`skip-grant-tables`
? 重啟:service mysqld restart
-------------------------------------------------------------------------------------------------------------------------------------------
| 第2個(gè)問(wèn)題按照上面設(shè)置之后如果在登陸之后操作之后的時(shí)候片排,遇見(jiàn)如下錯(cuò)誤??
| `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';
| 當(dāng)之后重新設(shè)置密碼時(shí)寨腔,遇見(jiàn)如下錯(cuò)誤??
| `[ERROR 1819 (HY000): Your password does not satisfy the current policy requirements]`
| 解決方法:輸入 set global validate_password_policy=0;
| 之后在設(shè)置密碼就OK了,命令見(jiàn)`FAQ 2`設(shè)置用戶密碼率寡,然后更新privilige
| (正如上文所說(shuō)迫卢,MySQL 5.6之后安全機(jī)制增強(qiáng)了,所以導(dǎo)致5.6之后的設(shè)置密碼方式與之前不一樣)
- 第四步:創(chuàng)建
sonar
數(shù)據(jù)庫(kù)及sonar
用戶及設(shè)置用戶權(quán)限
? 創(chuàng)建數(shù)據(jù)庫(kù):
CREATE DATABASE sonar CHARACTER SET utf8 COLLATE utf8_general_ci;
? 創(chuàng)建SonarQube Server訪問(wèn)數(shù)據(jù)庫(kù)的用戶:
CREATE USER 'sonar' IDENTIFIED BY 'sonar';
? 配置SonarQube Server訪問(wèn)數(shù)據(jù)庫(kù)用戶的權(quán)限
GRANT ALL ON sonar.* TO 'sonar'@'%' IDENTIFIED BY 'sonar';
GRANT ALL ON sonar.* TO 'sonar'@'localhost' IDENTIFIED BY 'sonar';
? 更新權(quán)限:flush privileges;
-------------------------
Tip:
flush privileges 命令本質(zhì)上的作用是將當(dāng)前user和privilige表中的用戶信息/權(quán)限設(shè)
置從mysql庫(kù)(MySQL數(shù)據(jù)庫(kù)的內(nèi)置庫(kù))中提取到內(nèi)存里冶共。MySQL用戶數(shù)據(jù)和權(quán)限有修改后乾蛤,希望在
"不重啟MySQL服務(wù)"的情況下直接生效,那么就需要執(zhí)行這個(gè)命令捅僵。通常是在修改ROOT帳號(hào)的設(shè)置
后家卖,怕重啟后無(wú)法再登錄進(jìn)來(lái),那么直接flush之后就可以看權(quán)限設(shè)置是否生效庙楚,而不必冒太大風(fēng)險(xiǎn)
- 第五步:更改
SonarQube
配置文件上荡,打開(kāi)SonarQube
下的conf/sonar.properties
,如下圖??
取消注釋醋奠,并按照如下圖??所示榛臼,填寫內(nèi)容伊佃,其中sonar.jdbc.url這一行只要取消注釋就可以
- 第六步:進(jìn)入
SonarQube
目錄下的/bin/linux-x86-64
運(yùn)行:nohup bash sonar.sh start &
(注:高版本中不能用root
用戶啟動(dòng)SonarQube
,需用非root
用戶啟動(dòng))
Tip:
nohup command &表示將進(jìn)程放置后臺(tái)運(yùn)行沛善,而對(duì)于linux-x86-64這個(gè)文件夾是根據(jù)你當(dāng)前安裝SonarQube的系統(tǒng)決定的航揉,是哪個(gè)系統(tǒng)就進(jìn)那個(gè)文件夾
- 第七步:訪問(wèn)
http://127.0.0.1:9000
,如果不是本機(jī)就輸入http://IP:9000
接著你會(huì)看到如下圖所示??
接著點(diǎn)擊Log in,默認(rèn)賬號(hào):admin金刁,密碼:admin
登錄之后帅涂,按如下操作安裝
中文插件
SonarQube Scanner 配置
-
準(zhǔn)備工作
- Download SonarQube Scanner
第一步:下載之后解壓
zip
包,之后進(jìn)入該目錄的conf
文件夾下尤蛮,打開(kāi)文件sonar-scanner.properties
媳友,如下圖所示??
在文件中,將下面一行取消注釋即可
# 如果是遠(yuǎn)程的話产捞,請(qǐng)將localhost修改為遠(yuǎn)程機(jī)器的IP地址
sonar.host.url=http://localhost:9000
- 第二步:到工程根目錄下新建文件
sonar-project.properties
醇锚,文件內(nèi)容如下??,文件中的參數(shù)配置坯临,參考Sonar Analysis Parameters這篇文章
# 指定SonarQube instance必須是唯一的
sonar.projectKey=Jacoco
# 設(shè)置SonarQube UI顯示的名稱
# PS:有人會(huì)問(wèn)這里的名稱是否可以是中文名稱焊唬,我在網(wǎng)上搜索了好多資料都說(shuō)是不可以的(至少我看到的資料都是)
# 后來(lái)自己嘗試了一下,答案是可以寫成中文的看靠,但是要換一種方式赶促,比如你想把項(xiàng)目名稱命名為“測(cè)試”,
# 那么在這里就要寫成“\u6d4b\u8bd5”挟炬,那么下面這個(gè)參數(shù)就應(yīng)該這樣寫“sonar.projectName= \u6d4b\u8bd5”鸥滨,
# 說(shuō)白了就是將中文轉(zhuǎn)成Unicode
sonar.projectName= Jacoco
sonar.projectVersion=1.0
sonar.language=java
# 指定src和classes文件夾位置,當(dāng)然也可以是全路徑谤祖,如果是當(dāng)前工程根目錄下用“.”表示也可以婿滓,比如“sonar.sources=.”
sonar.sources=src
sonar.java.binaries=target
# 下面的這兩個(gè)參數(shù)作用是相同的,因?yàn)橛袝r(shí)我們需要指定某個(gè)文件夾或者忽略某個(gè)文件夾
# sonar.inclusions=src1/**,src3/**
# sonar.exclusions=src2/**,src4/**
# 源碼編碼泊脐,默認(rèn)是系統(tǒng)編碼
sonar.sourceEncoding=UTF-8
# Set jacoco Configuration
# 指定代碼覆蓋率工具
sonar.core.codeCoveragePlugin=jacoco
# 指定exec二進(jìn)制文件存放路徑
sonar.jacoco.reportPaths=[yourPath/]jacoco.exec
# 以下屬性可選擇性加空幻,當(dāng)然也可以不加
sonar.dynamicAnalysis=reuseReports
sonar.jacoco.reportMissing.force.zero=false
Tip:可以將這里的知識(shí)結(jié)合
Jacoco Code Coverage結(jié)合這篇的中的
Demo工程實(shí)踐一下烁峭,當(dāng)然如果同時(shí)想要分析代碼覆蓋率的話你就要在下載
Demo工程之后容客,運(yùn)行mvn test生成exec二進(jìn)制文件,并將exec文件的路徑補(bǔ)全约郁,當(dāng)然如果找不到這個(gè)文件也不會(huì)報(bào)錯(cuò)缩挑,只是在SonarQube平臺(tái)上看不到代碼覆蓋率
- 第三步:第一和第二步完成之后,進(jìn)入
sonar-scanner-xxx
的conf
目錄下鬓梅,你會(huì)發(fā)現(xiàn)兩個(gè)文件sonar-scanner
&sonar-scanner-debug
供置,配置一下環(huán)境變量,如下所示??
export SONAR_SCANNER_HOME=[yourSonarScannerPath/]
export PATH=$PATH:$SONAR_SCANNER_HOME/bin:PATH
Tip:配置好環(huán)境變量之后绽快,source一下使之生效
然后從終端進(jìn)入工程根目錄
芥丧,運(yùn)行sonar-scanner
你會(huì)看到如下日志??
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: ------------------------------------------------------------------------
接下來(lái)我們回到之前搭建好的SonarQube
平臺(tái)紧阔,看一下檢測(cè)的結(jié)果,效果展示如下圖??
說(shuō)明一下:
上文運(yùn)用的Sonar Sanner只是實(shí)現(xiàn)代碼檢測(cè)方式的其中之一而已续担,當(dāng)然還有其它做法擅耽,比如直接在
pom.xml文件中引用sonar插件,但是我這里考慮的是與Jenkins做成持續(xù)集成物遇,如果我選擇在項(xiàng)目中添
加sonar-project.properties文件乖仇,這樣能更方面與Jenkins結(jié)合
到這里基本上就結(jié)束了,下面就是將Jenkins與SonarQube集成询兴,詳見(jiàn):
Jenkins + SonarQube & SonarQube Scanner
如在閱讀或者實(shí)踐過(guò)程中遇到問(wèn)題乃沙,歡迎下方留言