【DevOps实践】4. Ubuntu下安装配置代码检测工具SonarQube+MySQL

1. 摘要

SonarQube是一款用于代码质量管理的开源工具,它主要用于管理源代码的质量。 通过插件形式,可以支持众多计算机语言,比如 java, C#, go,C/C++, PL/SQL, Cobol, JavaScrip, Groovy 等。sonar可以通过PMD,CheckStyle,Findbugs等等代码规则检测工具来检测你的代码,帮助你发现代码的漏洞,Bug,异味等信息。
本文讲解该软件在Ubuntu环境的搭建过程。

2. 内容

2.1 前置环境

从Sonar7.8版本开始,要求支持Java11,不再支持MySQL数据库。
本文讲解目前主流环境下(在Java8(JDKv1.8.0)和MySQL)版本中安装Sonar7.7的完整过程。

2.2 配置MySQL数据库

登录MySQL

mysql -u root -p

create database sonar character set utf8 collate utf8_general_ci;
create user 'sonar' identified by 'sonar';
grant all on sonar.* to 'sonar'@'%' identified by 'sonar';
grant all on sonar.* to 'sonar'@'localhost' identified by 'sonar';
flush privileges;

辉哥实际采用宝塔完成数据库的创建和配置,数据库名:sonar 用户名:sonar 同以上命令实现。

2.2 下载安装sonar

2.2.1 下载安装sonar

(1)在国内从官网下载sonar的速度特别慢。下载地址:https://binaries.sonarsource.com/Distribution/sonarqube/sonarqube-7.7.zip
下载后上传到Linux服务器,进行解压缩安装。

$ unzip sonarqube-7.7.zip
$ mkdir /opt/sonar
$ mv sonarqube-7.7/* /opt/sonar/

(2)sonar无法使用root启动,需要创建新的sonar用户,密码自行记录。

$ useradd sonar
$ passwd sonar

赋予普通用户sonar具有sonar软件的所有读写执行权限。
chown将指定文件的拥有者改为指定的用户或组,用户可以是用户名或者用户ID;组可以是组名或者组ID;文件是以空格分开的要改变权限的文件列表,支持通配符。-R表示 处理指定目录以及其子目录下的所有文件

$ chown -R sonar. /opt/sonar/

(3)sonar默认侦听接口为9000。启动前采用netstat查看9000接口有无被占用。修改sonar配置文件。
9001默认被自带的elastic search启动占用,也要保证该端口不被其他进程占用。

$ netstat -nltp
$ cd /opt/sonar/
$ vim conf/sonar.properties

编辑的核心内容如下:

sonar.jdbc.username=sonar 
sonar.jdbc.password=***#需要修改访问数据库的密码

sonar.jdbc.url=jdbc:mysql://localhost:3306/sonar?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&useConfigs=maxPerformance&useSSL=false

sonar.web.port=9000 #侦听端口

sonar.web.host=0.0.0.0 # 开放,允许所有IP访问该端口。
#sonarWEB登录用户密码
sonar.login=admin
sonar.password=***#需要修改为访问页面的初始密码,可以修改

(4)启动sonarqube
启动sonarqube:

$ su sonar
$ ./bin/linux-x86-64/sonar.sh start

查看sonarqube,这个表示启动成功。16395是其进程号。

$ ./bin/linux-x86-64/sonar.sh status
SonarQube is running (16395)

kill -9 进程号可杀死。也可以采用stop命令关闭。

$ ./bin/linux-x86-64/sonar.sh stop

2.2.2 常见启动失败问题及排查

如果启动不成功,可能有各种原因。可以查看启动日志,并逐个排查问题解决。

$ tail -f logs/sonar.log

(1)JAVA版本不合适

vim logs/sonar.log
【问题】

WrapperSimpleApp: Encountered an error running main: java.lang.IllegalStateException: SonarQube requires Java 11 to run
java.lang.IllegalStateException: SonarQube requires Java 11 to run
        at com.google.common.base.Preconditions.checkState(Preconditions.java:173)

【分析结论】
需要Java11运行。这个是安装sonarqube-7.9 TLS版本遇到的问题。改为安装sonarqube-7.7版本,以便支持JDK1.8的环境。

(2)以root用户运行

【问题】
vim logs/sonar.log

2021.03.18 15:19:02 INFO  app[][o.s.a.AppFileSystem] Cleaning or creating temp directory /opt/sonar/temp
2021.03.18 15:19:02 INFO  app[][o.s.a.es.EsSettings] Elasticsearch listening on /127.0.0.1:9001
2021.03.18 15:19:02 INFO  app[][o.s.a.p.ProcessLauncherImpl] Launch process[[key='es', ipcIndex=1, logFilenamePrefix=es]] from [/opt/sonar/elasticsearch]: /opt/sonar/elasticsearch/bin/elasticsearch
2021.03.18 15:19:02 INFO  app[][o.s.a.SchedulerImpl] Waiting for Elasticsearch to be up and running
2021.03.18 15:19:03 INFO  app[][o.e.p.PluginsService] no modules loaded
2021.03.18 15:19:03 INFO  app[][o.e.p.PluginsService] loaded plugin [org.elasticsearch.transport.Netty4Plugin]
2021.03.18 15:19:05 WARN  app[][o.s.a.p.AbstractProcessMonitor] Process exited with exit value [es]: 1
2021.03.18 15:19:05 INFO  app[][o.s.a.SchedulerImpl] Process [es] is stopped
2021.03.18 15:19:05 INFO  app[][o.s.a.SchedulerImpl] SonarQube is stopped
<-- Wrapper Stopped

vim es.log

java.lang.RuntimeException: can not run elasticsearch as root
        at org.elasticsearch.bootstrap.Bootstrap.initializeNatives(Bootstrap.java:103) ~[elasticsearch-6.6.2.jar:6.6.2]
        at org.elasticsearch.bootstrap.Bootstrap.setup(Bootstrap.java:170) ~[elasticsearch-6.6.2.jar:6.6.2]
        at org.elasticsearch.bootstrap.Bootstrap.init(Bootstrap.java:333) [elasticsearch-6.6.2.jar:6.6.2]
        at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:159) [elasticsearch-6.6.2.jar:6.6.2]
        at org.elasticsearch.bootstrap.Elasticsearch.execute(Elasticsearch.java:150) [elasticsearch-6.6.2.jar:6.6.2]
        at org.elasticsearch.cli.EnvironmentAwareCommand.execute(EnvironmentAwareCommand.java:86) [elasticsearch-6.6.2.jar:6.6.2]
        at org.elasticsearch.cli.Command.mainWithoutErrorHandling(Command.java:124) [elasticsearch-cli-6.6.2.jar:6.6.2]
        at org.elasticsearch.cli.Command.main(Command.java:90) [elasticsearch-cli-6.6.2.jar:6.6.2]
        at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:116) [elasticsearch-6.6.2.jar:6.6.2]
        at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:93) [elasticsearch-6.6.2.jar:6.6.2]
2021.03.18 15:19:05 WARN  es[][o.e.b.ElasticsearchUncaughtExceptionHandler] uncaught exception in thread [main]
org.elasticsearch.bootstrap.StartupException: java.lang.RuntimeException: can not run elasticsearch as root
        at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:163) ~[elasticsearch-6.6.2.jar:6.6.2]
        at org.elasticsearch.bootstrap.Elasticsearch.execute(Elasticsearch.java:150) ~[elasticsearch-6.6.2.jar:6.6.2]
        at org.elasticsearch.cli.EnvironmentAwareCommand.execute(EnvironmentAwareCommand.java:86) ~[elasticsearc

【分析结论】
sonar.log没有有效信息。但是es.log明确指出不能使用root用户启动的。
切换到sonar用户,重新启动sonar服务了。

(3)端口被占用

vim logs/sonar.log
【问题】

sh-4.4$ ./bin/linux-x86-64/sonar.sh console
Running SonarQube...
wrapper  | --> Wrapper Started as Console
wrapper  | Launching a JVM...
jvm 1    | Wrapper (Version 3.2.3) http://wrapper.tanukisoftware.org
jvm 1    |   Copyright 1999-2006 Tanuki Software, Inc.  All Rights Reserved.
jvm 1    | 
jvm 1    | 2021.03.15 21:42:37 INFO  app[][o.s.a.AppFileSystem] Cleaning or creating temp directory /opt/sonar/temp
jvm 1    | 2021.03.15 21:42:37 INFO  app[][o.s.a.es.EsSettings] Elasticsearch listening on /127.0.0.1:9001
jvm 1    | 2021.03.15 21:42:37 INFO  app[][o.s.a.p.ProcessLauncherImpl] Launch process[[key='es', ipcIndex=1, logFilenamePrefix=es]] from [/opt/sonar/elasticsearch]: /opt/sonar/elasticsearch/bin/elasticsearch
jvm 1    | 2021.03.15 21:42:37 INFO  app[][o.s.a.SchedulerImpl] Waiting for Elasticsearch to be up and running
jvm 1    | 2021.03.15 21:42:37 INFO  app[][o.e.p.PluginsService] no modules loaded
jvm 1    | 2021.03.15 21:42:37 INFO  app[][o.e.p.PluginsService] loaded plugin [org.elasticsearch.transport.Netty4Plugin]
jvm 1    | 2021.03.15 21:42:50 INFO  app[][o.s.a.SchedulerImpl] Process[es] is up
jvm 1    | 2021.03.15 21:42:50 INFO  app[][o.s.a.p.ProcessLauncherImpl] Launch process[[key='web', ipcIndex=2, logFilenamePrefix=web]] from [/opt/sonar]: /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java -Djava.awt.headless=true -Dfile.encoding=UTF-8 -Djava.io.tmpdir=/opt/sonar/temp -Xmx512m -Xms128m -XX:+HeapDumpOnOutOfMemoryError -cp ./lib/common/*:/opt/sonar/lib/jdbc/mysql/mysql-connector-java-5.1.46.jar org.sonar.server.app.WebServer /opt/sonar/temp/sq-process6941314718593124808properties
jvm 1    | 2021.03.15 21:42:51 INFO  app[][o.s.a.SchedulerImpl] Process [web] is stopped
jvm 1    | 2021.03.15 21:42:52 INFO  app[][o.s.a.SchedulerImpl] Process [es] is stopped
jvm 1    | 2021.03.15 21:42:52 INFO  app[][o.s.a.SchedulerImpl] SonarQube is stopped
jvm 1    | 2021.03.15 21:42:52 WARN  app[][o.s.a.p.AbstractProcessMonitor] Process exited with exit value [es]: 143
wrapper  | <-- Wrapper Stopped

然后vim logs/web.log,保存信息如下:

2021.03.15 21:42:51 WARN  web[][o.s.p.ProcessEntryPoint] Fail to start web
java.lang.RuntimeException: org.apache.catalina.LifecycleException: Failed to initialize component [StandardServer[-1]]
        at com.google.common.base.Throwables.propagate(Throwables.java:160)
        at org.sonar.server.app.EmbeddedTomcat.start(EmbeddedTomcat.java:65)
        at org.sonar.server.app.WebServer.start(WebServer.java:51)
        at org.sonar.process.ProcessEntryPoint.launch(ProcessEntryPoint.java:113)
        at org.sonar.process.ProcessEntryPoint.launch(ProcessEntryPoint.java:100)
        at org.sonar.server.app.WebServer.main(WebServer.java:91)
Caused by: org.apache.catalina.LifecycleException: Failed to initialize component [StandardServer[-1]]
        at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:112)
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:140)
        at org.apache.catalina.startup.Tomcat.start(Tomcat.java:427)
        at org.sonar.server.app.EmbeddedTomcat.start(EmbeddedTomcat.java:61)
        ... 4 common frames omitted
Caused by: org.apache.catalina.LifecycleException: Failed to initialize component [StandardService[Tomcat]]
        at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:112)
        at org.apache.catalina.core.StandardServer.initInternal(StandardServer.java:875)
        at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:107)
        ... 7 common frames omitted
Caused by: org.apache.catalina.LifecycleException: Failed to initialize connector [Connector[HTTP/1.1-9001]]
        at org.apache.catalina.core.StandardService.initInternal(StandardService.java:559)
        at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:107)
        ... 9 common frames omitted

【分析结果】
sonar.log的日志表示sonar的web服务启动后又被关闭了。无法确定其原因。
web.log的日志表示之前配置的已经被占用,导致连接失败。" Failed to initialize connector [Connector[HTTP/1.1-9001]]"
9001端口默认被es占用,改为9000即可。

输入curl http://127.0.0.1:9000可以获取反馈页面内容。

(4)

【问题描述】
sonar先启动成功,然后not running了。
vim ./logs/sonar.log

WrapperSimpleApp: Encountered an error running main: java.nio.file.AccessDeniedException: /opt/sonar/temp/conf/es/log4j2.properties
java.nio.file.AccessDeniedException: /opt/sonar/temp/conf/es/log4j2.properties
        at sun.nio.fs.UnixException.translateToIOException(UnixException.java:84)
        at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:102)
        at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:107)
        at sun.nio.fs.UnixFileSystemProvider.implDelete(UnixFileSystemProvider.java:244)
        at sun.nio.fs.AbstractFileSystemProvider.delete(AbstractFileSystemProvider.java:103)
        at java.nio.file.Files.delete(Files.java:1126)
        at org.sonar.process.FileUtils2$DeleteRecursivelyFileVisitor.visitFile(FileUtils2.java:186)
        at org.sonar.process.FileUtils2$DeleteRecursivelyFileVisitor.visitFile(FileUtils2.java:181)
        at java.nio.file.Files.walkFileTree(Files.java:2670)
        at java.nio.file.Files.walkFileTree(Files.java:2742)
        at org.sonar.process.FileUtils2.deleteDirectoryImpl(FileUtils2.java:143)
        at org.sonar.process.FileUtils2.deleteDirectory(FileUtils2.java:112)
        at org.sonar.application.AppFileSystem$CleanTempDirFileVisitor.visitFile(AppFileSystem.java:117)
        at org.sonar.application.AppFileSystem$CleanTempDirFileVisitor.visitFile(AppFileSystem.java:101)
        at java.nio.file.Files.walkFileTree(Files.java:2670)
        at org.sonar.application.AppFileSystem.createOrCleanTempDirectory(AppFileSystem.java:96)
        at org.sonar.application.AppFileSystem.reset(AppFileSystem.java:62)
        at org.sonar.application.App.start(App.java:55)
        at org.sonar.application.App.main(App.java:78)
        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.tanukisoftware.wrapper.WrapperSimpleApp.run(WrapperSimpleApp.java:240)
        at java.lang.Thread.run(Thread.java:748)
<-- Wrapper Stopped

【分析结论】
之前因为root账户运行导致es失败。切换到sonar账户后,还是失败,报错如上。没有/opt/sonar/temp/conf/es权限?
删除sonarqube temp目录重新运行就成功了。

sudo rm -rf temp

2.2.3 配置https域名和反向代理

增加NGINX配置的反代理,以便安全保护。这个步骤不是必选项。

在nginx配置增加sonar的路由,然后把conf/sonar.properties的开放IP“sonar.web.host=0.0.0.0 ”注释掉关闭。
最终域名:
https://sonar.artarva.com/

配置参考文章《【DevOps实践】2. 使用NGINX配置Jenkins的https域名访问》

2.3 登录

https://sonar.artarva.com/就可以访问sonarqube主页了。

3. 参考

(1)Ubuntu 16.04下安装配置SonarQube+MySQL
https://www.linuxidc.com/Linux/2017-05/143860.htm
【说明】主要参考这个。

(2)sonarqube环境搭建采坑详解
https://blog.csdn.net/weixin_40686603/article/details/90208627

(3)SonarQube 7.9.x LT安装
https://blog.csdn.net/u010948569/article/details/111991998
【说明】安装参考这个,需要JAVA11,无奈放弃。
[1] SonarQube安装教程与简单使用(基于Centos7,JDK1.8)

[2] 下载文件列表【最后显示所有版本】
https://www.sonarqube.org/downloads/
https://docs.sonarqube.org/7.7/requirements/requirements/
【说明】7.7为最后一个支持JDK1.8的版本
[3] 有安装sonar scanner的帮助

(4)GO语言监测配置
How to run SonarQube for Go code using Jenkins
https://stackoverflow.com/questions/63832311/how-to-run-sonarqube-for-go-code-using-jenkins

https://docs.sonarqube.org/latest/analysis/languages/go/

(5)Jenkins+SonarQube+Gitlab搭建自动化持续代码扫描质量平台
https://blog.csdn.net/zuozewei/article/details/84539396
【说明】介绍sonar的作用整体。

(6) SonarQube集成golang检测
https://blog.csdn.net/baidu_36943075/article/details/90634160

(7)GO项目配置
https://docs.sonarqube.org/latest/analysis/languages/go/

(8) sonarqube SonarGo 搭建和golang代码检视的使用教程
https://www.jianshu.com/p/95ae320aa46d

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

推荐阅读更多精彩内容