step 1:创建SonarQube的挂载目录

        依次执行下列linux命令创建挂载目录(目录自定义)

        mkdir -p /usr/sonarqube/{extensions,logs,data}

        chmod 777 /usr/sonarqube/{extensions,logs,data}

        chown -R 1000 /usr/sonarqube/{extensions,logs,data}

        *没有权限的话加上sudo

step 2:下载持久化运行需要的数据库

        持久化启动SonarQube需要搭配数据库(Mysqlpostgresql),貌似7.6版本以上就不支持Mysql了,因为本人使用sonar版本为8.9.2,所以本文采用postgresql:11。

        1.创建postgresql的挂载目录:

        mkdir -p /usr/postgres/{postgresql,data}

        chmod 777 /usr/postgres/{postgresql,data}

        2.docker安装postgresql

        docker pull postgres:11

        3.启动容器

#-d 后台运行并返回id;--name 指定运行名称;-p 容器映射宿主机端口
docker run -d --name postgres -p 5432:5432 \
#映射挂载目录
-v /usr/postgres/postgresql:/var/lib/postgresql \
-v /usr/postgres/data:/var/lib/postgresql/data \
-v /etc/localtime:/etc/localtime:ro \
#初始用户、密码、数据库
-e POSTGRES_USER=sonar \
-e POSTGRES_PASSWORD=sonar  \
-e POSTGRES_DB=sonar \
#设置时区
-e TZ=Asia/Shanghai \
#重启策略,docker重启容器会自动启动
--restart always \
#是否让docker 应用容器 获取宿主机root权限(特殊权限)
--privileged=true \
#docker images指定的容器名称
postgres:11

        4.docker ps查看数据库是否启动成功

        端口显示映射且用数据库连接软件尝试连接该数据库。

step 3:修改系统内核参数

        若不修改启动会报错:ERROR: Elasticsearch did not exit normally - check the logs at /opt/sonarqube/logs/sonarqube.log。

vim /etc/sysctl.conf
# 增加以下配置
vm.max_map_count=262144 fs.file-max=65536
# 使配置生效
sysctl -p

step 4:下载SonarQube镜像并启动

docker run -d --name sonarqube8.9.2 -p 9000:9000 \
--link postgres \
-v /usr/sonarqube8.9.2/extensions:/opt/sonarqube/extensions \
-v /usr/sonarqube8.9.2/logs:/opt/sonarqube/logs \
-v /usr/sonarqube8.9.2/data:/opt/sonarqube/data \
-e SONARQUBE_JDBC_URL=jdbc:postgresql://${ip地址}:5432/sonar \
-e SONARQUBE_JDBC_USERNAME=sonar \
-e SONARQUBE_JDBC_PASSWORD=sonar \
--restart always \
--privileged=true \
sonarqube:8.9.2-community

        *没下载sonarqube:8.9.2-community镜像的同学跑该命令不用担心,docker容器会自己检测是否存在该容器,不存在时会先下载再启动。

step 5:查看是否启动成功

    docker logs -f sonarqube8.9.2

        使用docker日志命令查看sonarqube是否启动成功。

        结尾xxx is up出现就表示成功啦。

step 6:访问页面

        默认账号密码都是admin,进入后会要求你改密码。

        想看到和上图一样中文界面的话,可以下载中文插件。

        中文插件地址https://github.com/xuhuisheng/sonar-l10n-zh/tags 

        1.SonarQube:8.9.2社区版下载对应的jar包:sonar-l10n-zh-plugin-8.9.jar。

        2.下载完后放去上面创建对应的挂载目录中的/usr/sonarqube/extensions/plugins若没有plugins文件夹就自己mkdir一个。

        3.放好后重启SonarQube。

step 7:下载SonarQube社区版切换分支插件

        因社区版是免费开源的,所以不提供扫描项目切换分支的功能,但适合真正生产环境的项目会具有多个分支,只能扫描主分支的SonarQube社区版显然很不满足你的需求,而开发者版和企业版支持但是需要大量的欧元。别担心,插件市场提供了一款可以切换分支的插件,sonarqube-community-branch-plugin,Let’s go!

        中文插件地址https://github.com/mc1arke/sonarqube-community-branch-plugin 

        1.进入页面滚轮往下,查看和你SonarQube对应的版本:

         

        2.点击进入超链接挑选下载版本:

        

        SonarQube:8.9.2对应的jar包:sonarqube-community-branch-plugin-1.8.1.jar。

        3.下载完后和setp 6一样放入挂载目录/usr/sonarqube/extensions/plugins

        4.需要同官网描述修改SonarQube的配置文件:sonar.properties。

        

        docker exec -it sonarqbue8.9.2 /bin/bash  进入容器内部找到配置文件。

            

        进入conf文件夹,使用vim命令修改sonar.properties,在文件末尾加入两行:

sonar.web.javaAdditionalOpts=-javaagent:./extensions/plugins/sonarqube-community-branch-plugin-${version}.jar=web

sonar.ce.javaAdditionalOpts=-javaagent:./extensions/plugins/sonarqube-community-branch-plugin-${version}.jar=ce

        ${version}:你所下载的jar包的版本,本文因SonarQube版本为8.9.2所以是填入1.8.1。

        保存退出。

        ***若你的容器里没用vim命令,先尝试apt-get update + apt-get install vim两句命令,若还是不行可以看看有没有yum -y install vim命令,若都没有可以尝试先将容器内部文件拷出来,修改完再拷回去,参考命令如下:

docker cp sonarqube:/opt/sonarqube/conf/sonar.properties /opt/sonar.properties

docker cp /opt/sonar.properties sonarqube:/opt/sonarqube/conf/sonar.properties

        4.重启SonarQube。

        5.登录页面后若弹出检测到插件风险,点击忽略就好。

         

        显示这样的页面,master分支有个蓝底白色加号的按钮就说明你成功了。

        6.先扫描master分支后,再切换如sonar.branch.name=xxx分支扫描后就能看到。

step 8:登录Jenkins下载SonarQube插件并配置

        1.进入Jenkins的系统管理->插件管理->可选插件,搜索框输入sonar,安装重启。

        

        2.安装成功后在已安装里就可以看到该插件。

         

         3.Jenkins的系统管理->系统配置,添加SonarQube服务。

        

        Name:可以随便填,取个名。

        Server URL:装SonarQube的服务器和端口,默认http://localhost:9000。

        Server authentication token:连接凭证,具体获取步骤如下:

                第一步:SCM设置打上√并保存。

   

                第二步:点击权限里的用户获取一个token令牌。

                

                

                第三步:复制生成出来的token,记得哪里保存存储一下。

          

                第四步:在刚刚Jenkins中点击小钥匙添加。

  

                第五步:类型切换成Secret text,粘贴token,点击添加。

                

                第六步:选上刚刚添加的令牌凭证,点击应用保存。

step 9:Jenkins配置全局工具(sonar-scanner扫描仪)

        进入Jenkins的系统管理->全局工具配置,下滑找到图片里的地方,点击新增SonarQube Scanner,我们选择自动安装并选择最新的版本(极为方便)。

*Jenkins最新的版本里,该位置的版本没有选择列表只有一个输入框,也不知道为啥,所以重新安装了老的版本才能显示版本列表,Jenkins 2.303.3。

step 10:Jenkins:具体项目配置参数

        1.进入Jenkins的具体工程的配置空间

        2.添加SonarQube的构建步骤。

        3.填写相应的参数(新一些的版本好像不需要在Task to run中填写scan,空着就好)。

         

Analysis properties:

#自己指定一个项目的key,也可以采用maven中读取的项目名称。

sonar.projectKey=hanson

#自己指定一个项目的名称,也可以采用maven中读取的项目名称。

sonar.projectName=hanson

#自己指定一个项目的名称,也可以采用maven中读取的项目版本。

sonar.projectVersion=1.0.0

#分支插件需要填写的参数,项目第一次记得先扫master,再扫其他的分支,一个个来。

sonar.branch.name=master

#对应语言。

sonar.language=java

#扫描的资源路径,可以在jenkins的挂载目录或内部容器目录看到workspace的一个文件夹,扫描出来maven打包出来的文件一般放在这里,你可以进去指定你内部的文件,$WORKSPACE已经包含了workspace和你工程名字的目录。例如你项目叫test有两个包,叫x1、x2,maven package出两个包的路径就是./workspace/test/x1、./workspace/test/x2,如果你只要扫描x1包那就是sonar.sources=$WORKSPACE/x1/src;如果两个包,sonar.sources=$WORKSPACE/x1/src$WORKSPACE/x2/src

sonar.sources=$WORKSPACE/hanson-oa/src

#扫描的进制文件,基本就是targer,必填格式和sources同理。

sonar.java.binaries=$WORKSPACE/hanson-oa/target

***若项目需要添加Jacoco覆盖率插件,且sonarqube里的覆盖率需要显示出来(没配置好就会显示为0)

  • 1、需要在自己项目的pom文件里配置jacoco的build,多包多模块就放在最外层的pom里面,单包可以直接放在那个包的pom。
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.22.2</version>
                <configuration>
                    <!--跳过单元测试就true,不跳过需要执行则false-->
                    <skipTests>false</skipTests>
                    <!--若你的yml配置文件放在云端例如nacos,启动需要填写配置参数的,需要在argLine里面填写上,且需要加上${jacocoArgLine},jacocoArgLine获取在下面jacoco的插件中,目的是surefire和jacoco在启动的时候,防止启动参数互相覆盖,否则jacoco很容易出现Skipping JaCoCo execution due to missing execution data file.-->
                    <argLine>-Dspring.application.name=helloworld -Dspring.profiles.active=test
                        -Dspring.cloud.nacos.config.server-addr=172.xx.x.xx:8848 ${jacocoArgLine}
                    </argLine>
                    <excludes>
                        <exclude>com/xxx/xxx/BaseTest.java</exclude>
                    </excludes>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.jacoco</groupId>
                <artifactId>jacoco-maven-plugin</artifactId>
                <version>0.8.7</version>
                <configuration>   
                    <!--若需要指定路径、名字生成.exec文件请添加下面两行,默认*/target/jacoco.exec-->
                    <!--指定生成.exec文件的存放位置-->
                    <destFile>target/coverage-reports/jacoco-unit.exec</destFile>   
                    <!--Jacoco是根据.exec文件生成最终的报告,所以需指定.exec的存放路径-->                    
                    <dataFile>target/coverage-reports/jacoco-unit.exec</dataFile>
                    <excludes>
                        <!--排除文件-->
                        <exclude>com/xxx/xxx/BaseTest.java</exclude>
                    </excludes>
                </configuration>
                <executions>
                    <execution>
                        <id>jacoco-initialize</id>
                        <goals>
                            <goal>prepare-agent</goal>
                        </goals>
                        <!--与上文argLine中的参数呼应-->
                        <configuration>
                            <propertyName>jacocoArgLine</propertyName>
                        </configuration>
                    </execution>
                    <execution>
                        <id>jacoco-site</id>
                        <phase>test</phase>
                        <goals>
                            <goal>report</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

maven的<dependencies>中可以不需要加jacoco,若你发错你的@Test(org.Junit的)怎么都扫描不到,且skipTests为false,去掉import org.junit.Test换成import org.junit.jupiter.api.Test试一下,最新的5代Junit,本地直接跑会发现控制台多了个Junit Jupiter和Junit Vintage(报错),不需要管,本地4代junit冲突了,放在jenkins拉取代码mvn时会重新拉取依赖到仓库不会报错。

可以本地直接运行一下mvn install,或者mvn compile test,看看是否在target中出现*.exec文件,surefire-reports文件夹,site文件夹,若都出现,且site中有jacoco的index.html网页报告说明你成功了(切记,项目路径要是英文,若是中文会报错)。

  • 2、jenkins下载jacoco插件

  • 3、配置你创建的任务

在上面提供的sonar参数中在添加下列几行,若是8.9上下版本或更高的sonar,请直接看我的,别去百度,亲测,百度踩坑无数差点奔溃(2天),不如直接去sonarqube官网看参数,以后大家能去官网就去官网,虽然都是英文,但是可以翻译:

#为jacoco执行的二进制.exec文件指定存在路径,若上面中你去掉了指定的那两行,采用默认路径,即可不加

#sonar.jacoco.reportPath=$WORKSPACE/hanson-oa/target/coverage-reports/jacoco-unit.exec

#指定jacoco生成的单元测试覆盖率xml文件路径,默认都在*/target/site/jacoco/jacoco.xml

sonar.coverage.jacoco.xmlReportPaths=$WORKSPACE/hanson-oa/target/site/jacoco/jacoco.xml

#surefire插件生成的单元测试运行报告文件存放的地址,默认时*/target/surefire-reports。

sonar.junit.reportPaths=$WORKSPACE/hanson-oa/target/surefire-reports

  • 4、在构建后操作中添加两个操作(jacoco和surefire报告)

    Record JaCoCo coverage report:

    Publish Junit test result report:

若SUCCESS的话,任务左边就会出现:

          注意 :sonarqube或者jenkins中的通配符,**代表任意目录,*代表任意字符(任意文件),?单个字符,**/controller/*,就是整个项目中任一controller文件夹下的任意文件,若是你有个文件时com/hanson/controller/test/xxx.java,中间带着一层test文件夹是扫描不到的。

           对于sonarqube集成jacoco或者jenkins集成jacoco,有建议或有问题需要帮助的可以评论区再会哦~~。

step 11:构建项目查看扫描结果

        1.构建项目。

        

        2.若项目构建成功,就可以看到旁边有个SonarQube的小图标,点击进入 

        3.查看扫描报告。

         

        4.若安装了分支插件,出来修改sonar.branch.name=分支名称,再进行构建,就可以看到两个分支了。

        

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐