CentOS
MySQL
SonarQube
SonarQube Scanner
-
針對 Jacoco + Jenkins + SonarQube & SonarQube Scanner 分為四個部分寫的,建議閱讀的順序為:
- Jacoco Code Coverage
- Jenkins + Jacoco 持續集成代碼覆蓋率
- SonarQube & SonarQube Scanner ?
- Jenkins + 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.jdbc.url這一行只要取消注釋就可以
- 第六步:進入
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
接著你會看到如下圖所示??
接著點擊Log in,默認賬號:admin,密碼:admin
登錄之后,按如下操作安裝
中文插件
SonarQube Scanner 配置
-
準備工作
- Download SonarQube Scanner
第一步:下載之后解壓
zip
包,之后進入該目錄的conf
文件夾下,打開文件sonar-scanner.properties
,如下圖所示??
在文件中,將下面一行取消注釋即可
# 如果是遠程的話,請將localhost修改為遠程機器的IP地址
sonar.host.url=http://localhost:9000
- 第二步:到工程根目錄下新建文件
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-xxx
的conf
目錄下,你會發現兩個文件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
如在閱讀或者實踐過程中遇到問題,歡迎下方留言