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閱讀 228,030評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,310評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,951評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,796評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,566評論 6 407
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,055評論 1 322
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,142評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,303評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,799評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,683評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,899評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,409評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,135評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,520評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,757評論 1 282
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,528評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,844評論 2 372

推薦閱讀更多精彩內容