跳到主要内容

1、Maven构建工具实践

Maven构建工具实践

image-20230619122656768

目录

[toc]

1、Maven构建工具配置

maven是java项目的一个构建工具。

构建工具核心的功能就是管理这些依赖。

官网:https://maven.apache.org/index.html

Maven是一个项目的构建依赖管理工具。通常项目的根目录会存在一个pom.xml文件(该文件用于定义项目的依赖包信息和构建配置)

image-20230619202228669

1.spring boot项目生成

初始化一个springboot项目 https://start.spring.io/ (也可以下载一个ide) 如果打不开也可以使用:https://start.aliyun.com/bootstrap.html

一个spring boot项目其实有很多依赖。

生成一个标准的maven项目:

  • 项目类型: Maven Project
  • 语言: Java
  • SpringBoot: 2.7.12 (版本)(随着时间变化版本号会变,默认即可)
  • Metadata
    • Group : 组信息
    • Artifact:包名称
    • Packging: 包格式(Jar、War)
  • Dependencies: 定义项目依赖(最后都会写入Pom.xml)

jar包:可执行的程序。(目前基本是这种) war包:需要放到容器里,例如tomcat里,需要支持jsp环境的那种,才可以解析。

image-20230620065455170

以上配置完成后,点击Generate,生成测试代码。

image-20230619210108004

代码下载完成 后,可以用vscode打开,看下项目代码结构:

image-20230620070244314

2.创建gitlab仓库并上传代码

  • 创建一个devops6-maven-service项目

注意:这里取消勾选初始化仓库配置项。

image-20230619210635722

  • 在本地git端将项目代码上传到刚才创建的项目里:

image-20230619210715469

Push an existing folder

cd existing_folder
git init --initial-branch=main
git remote add origin http://172.29.9.101:8076/devops6/devops6-maven-service.git
git add .
git commit -m "Initial commit"
git push -u origin main

自己推送过程:

git init --initial-branch=main
git remote add origin http://172.29.9.101:8076/devops6/devops6-maven-service.git
git add .
git commit -m "Initial commit"
git push -u origin main

image-20230619211445730

image-20230619211458878

  • 到gitlab查看推送上来的代码:

image-20230619211540297

3.配置maven环境

提前安装好JDK, 然后安装apache-maven-3.9.1。

本次在gitlanci-runner上下载maven:(后面的环境为gitlab runner和jenkins agent都在一台机器上)

1、JDK环境自己之前已经安装好。

image-20230619213016203

如何安装JDK环境,请查看我的另一篇文章!

本地文档路径:实战:Linux下jdk8环境安装(测试成功)-2022.4.16(二进制方式) (jdk11安装方式一样)

image-20230619214431567

网络文档路径:https://blog.csdn.net/weixin_39246554/article/details/124221560

2、安装apache-maven-3.9.1

image-20230619214615558

###1、下载代码
[root@Devops6 ~]#wget https://dlcdn.apache.org/maven/maven-3/3.9.2/binaries/apache-maven-3.9.2-bin.tar.gz --no-check-certificate
[root@Devops6 ~]#ll -h apache-maven-3.9.2-bin.tar.gz
-rw-r--r-- 1 root root 8.9M May 8 17:12 apache-maven-3.9.2-bin.tar.gz
[root@Devops6 ~]#tar zxf apache-maven-3.9.2-bin.tar.gz -C /usr/local/
[root@Devops6 ~]#cd /usr/local/apache-maven-3.9.2/
[root@Devops6 apache-maven-3.9.2]#pwd /usr/local/apache-maven-3.9.2
/usr/local/apache-maven-3.9.2

###2、配置环境
[root@Devops6 ~]#vim /etc/profile
……
export M2_HOME=/usr/local/apache-maven-3.9.2
export PATH=$M2_HOME/bin:$PATH
[root@Devops6 ~]#source /etc/profile

###3、验证
[root@Devops6 ~]#mvn -v
Apache Maven 3.9.2 (c9616018c7a021c1c39be70fb2843d6f5f9b8a1c)
Maven home: /usr/local/apache-maven-3.9.2
Java version: 11.0.18, vendor: Red Hat, Inc., runtime: /usr/lib/jvm/java-11-openjdk-11.0.18.0.10-1.el7_9.x86_64
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "3.10.0-957.el7.x86_64", arch: "amd64", family: "unix"

4.配置Maven镜像源

==Maven本地仓库 & 远程仓库==

[root@Devops6 conf]#vim /usr/local/apache-maven-3.9.2/conf/settings.xml
  • 本地仓库
${user.home}/.m2/repository

image-20230620062542268

  • 远程仓库

image-20230620062822608

  • ==自己内网一般是会去搭建这样一个代理的==。

内网搭建一个这样的源,使用nexus去搭建的。

image-20230620063011707

image-20230620063048276

  • 阿里云云效 Maven

https://developer.aliyun.com/mvn/guide?spm=a2c6h.13651104.mirror-free-trial.5.10596e1ab2zbI4

image-20230620063623923

image-20230620063745863

  • 修改maven源为国内阿里源

https://developer.aliyun.com/mirror/maven?spm=a2c6h.13651102.0.0.3e221b11J7CO0d

    <mirror>
<id>aliyunmaven</id>
<mirrorOf>*</mirrorOf>
<name>阿里云公共仓库</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>

image-20230620063241219

image-20230620063349700

5.手动测试代码

  • 下载代码
[root@Devops6 ~]#cd /data/devops6/
[root@Devops6 devops6]#ls
gitlab jenkins_agent jenkins_home
[root@Devops6 devops6]#git clone http://172.29.9.101:8076/devops6/devops6-maven-service.git
Cloning into 'devops6-maven-service'...
Username for 'http://172.29.9.101:8076': root
Password for 'http://root@172.29.9.101:8076':
remote: Enumerating objects: 25, done.
remote: Counting objects: 100% (25/25), done.
remote: Compressing objects: 100% (15/15), done.
remote: Total 25 (delta 1), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (25/25), done.
[root@Devops6 devops6]#ls
devops6-maven-service gitlab jenkins_agent jenkins_home
[root@Devops6 devops6]#cd devops6-maven-service/
[root@Devops6 devops6-maven-service]#ls
mvnw mvnw.cmd pom.xml src
[root@Devops6 devops6-maven-service]#
  • 打包
[root@Devops6 devops6-maven-service]#pwd
/data/devops6/devops6-maven-service
[root@Devops6 devops6-maven-service]#ls
mvnw mvnw.cmd pom.xml src
[root@Devops6 devops6-maven-service]#mvn clean package

image-20230620070519530

image-20230620070831955

  • 打包完成后,我们来启动项目
[root@Devops6 devops6-maven-service]#ls
mvnw mvnw.cmd pom.xml src target
[root@Devops6 devops6-maven-service]#cd target/
[root@Devops6 target]#ls
classes demo-0.0.1-SNAPSHOT.jar demo-0.0.1-SNAPSHOT.jar.original generated-sources generated-test-sources maven-archiver maven-status surefire-reports test-classes
[root@Devops6 target]#java -jar demo-0.0.1-SNAPSHOT.jar

image-20230620071003201

可以看到报错了,提示8080端口被占用了,我们来检查下:

image-20230620071124194

可以看到8080端口被jenkins使用了。

  • 通过自定义端口参数来启动项目
[root@Devops6 target]#java  -jar -Dserver.port=8090  demo-0.0.1-SNAPSHOT.jar

image-20230620071329698

通过http://172.29.9.101:8090/访问:

image-20230620071410569

出现这个界面就说明ok了。(这里出现这个界面是因为代码里没有配置相关异常的代码,不影响测试。)

  • 我们接着来看下maven的缓存

image-20230620071644777

我们删除下这个缓存目录:

[root@Devops6 ~]#rm -rf .m2/repository/

在到项目里清下构建目录:

mvn clean

image-20230620072015818

image-20230620072035145

image-20230620072110832

可以看到,target目录也被清理掉了

然后打包,就可以看到要继续下载依赖包了:

mnv clean package

image-20230620072250669

image-20230620072437095

6.maven常用命令

  • mvn clean 清理构建目录

  • mvn clean package 打包

  • mvn clean install 打包部署

  • mvn clean test 单元测试

  • mvn clean package -f ../pom.xml -f指定pom位置\

  • mvn clean package -DskipTests / -Dmaven.test.skip=true 跳过单测

  • mvn deploy 发布包到制品库

mvn打包是必须要用到pom.xml文件的哦。

2、Jenkins与Maven集成

image-20230621065334471

tstmp_20230621065349

1.创建GitLab仓库

见上部分2.创建gitlab仓库并上传代码内容。

2.创建Jenkins作业

  • Jenkins上创建devops6-maven-servicepipeline类型作业,点击保存。

image-20230620080343274

  • 如何做一个静态构建?

添加2个选项参数:

image-20230620080552250

image-20230620080702740

保存后刷新:

image-20230621062046016

  • 开始写pipeline代码

我们先简单写一段代码,测试流水线可用性。

pipeline {
agent {label "build"}
stages{
stage("CheckOut"){
steps{
script{
println("CheckOut")
}
}

}

stage("Build"){
steps{
script{
println("Build")
}
}

}

}
}

image-20230621063010946

image-20230621062928614

以上测试ok。

3.编写Jenkins Pipeline

  • 写下载代码逻辑

如何获取下载代码此部分代码呢?我们使用片段生成器来生成下载部分代码。

image-20230621063253802

image-20230621063313647

checkout([$class: 'GitSCM', branches: [[name: 'main']], extensions: [], userRemoteConfigs: [[credentialsId: 'gitlab-root', url: 'srcUrl']]])
pipeline {
agent {label "build"}
stages{
stage("CheckOut"){
steps{
script{
println("CheckOut")

checkout([$class: 'GitSCM',
branches: [[name: "${env.branchName}"]],
extensions: [],
userRemoteConfigs: [[credentialsId: 'gitlab-root', url: "${env.srcUrl}"]]])

sh "ls -l" //验证
}
}
}

stage("Build"){
steps{
script{
println("Build")

sh "${env.buildShell}"
}
}

}

}
}

image-20230621063754348

image-20230621063818973

以上下载部分代码测试ok。

  • 开始写build部分代码
pipeline {
agent {label "build"}
stages{
stage("CheckOut"){
steps{
script{
println("CheckOut")

checkout([$class: 'GitSCM',
branches: [[name: "${env.branchName}"]],
extensions: [],
userRemoteConfigs: [[credentialsId: 'gitlab-root', url: "${env.srcUrl}"]]])

sh "ls -l" //验证
}
}
}

stage("Build"){
steps{
script{
println("Build")

sh "mvn clean package"
}
}

}

}
}

image-20230621064225132

image-20230621064206186

image-20230621064250571

这里会发现,build阶段报错了,提示mvn命令找不到。

那我们给使用mvn命令的绝对路径来再次测试下:

[root@Devops6 ~]#which mvn
/usr/local/apache-maven-3.9.2/bin/mvn
pipeline {
agent {label "build"}
stages{
stage("CheckOut"){
steps{
script{
println("CheckOut")

checkout([$class: 'GitSCM',
branches: [[name: "${env.branchName}"]],
extensions: [],
userRemoteConfigs: [[credentialsId: 'gitlab-root', url: "${env.srcUrl}"]]])

sh "ls -l" //验证
}
}
}

stage("Build"){
steps{
script{
println("Build")

sh "/usr/local/apache-maven-3.9.2/bin/mvn clean package"
}
}

}

}
}

image-20230621064452186

再次运行:

image-20230621064536597

image-20230621064551096

这次就测试ok了。我们有缓存了,所以它构建非常快。

  • 但是,现在有个问题:

==企业里,能直接这么用吗?--构建命令写死。---显示是不合理的。==

因此,我们这里使用变量来优化下代码。

在此流水线新增一个字符类型变量:

image-20230621064834754

再改下pipeline代码:

pipeline {
agent {label "build"}
stages{
stage("CheckOut"){
steps{
script{
println("CheckOut")

checkout([$class: 'GitSCM',
branches: [[name: "${env.branchName}"]],
extensions: [],
userRemoteConfigs: [[credentialsId: 'gitlab-root', url: "${env.srcUrl}"]]])

sh "ls -l" //验证
}
}
}

stage("Build"){
steps{
script{
println("Build")

sh "${env.buildShell}"
}
}

}

}
}

image-20230621065105119

再次运行测试:

image-20230621065145744

测试ok。

FAQ

技巧:如何判断某个项目是否是maven项目呢?

如果项目代码里包含这个pom.xml文件的话,那么很大可能这项目就是一个maven项目。

devops6 实验环境、软件

gitlab/gitlab-ce:15.0.3-ce.0
jenkins/jenkins:2.346.3-2-lts-jdk11
apache-maven-3.9.2
openjdk 11.0.18

实验软件

链接:https://pan.baidu.com/s/1adCJwX8-XtMBbmneNUf2og?pwd=0820 提取码:0820 --来自百度网盘超级会员V7的分享

2023.6.21-实战:Maven构建工具实践-(测试成功)

image-20230621070554358

==可以找老师开头spingboot如何写一个接口,到构建,并部署的课程。==

带有SNAPSHOT格式的后续打包会报错的

  • 这个带有SNAPSHOT格式的后续打包会报错的。。。

image-20230619205949720

image-20230620065253145

  • 那我们这次就选择这个2.7.12来进行测试。

image-20230620065455170

Maven vs Gradle

后端: 目前Java用的最多的就是Maven了; Gradle的性能比Maven是要强一些;(有时候,安卓打包也会用到这个Gradle) 现在基本很少用Ant了,新项目用的是Gradle; 前端: nodeJs工具:react,vue

maven的缓存目录

在调流水线的时候,遇到很多Maven构建失败的问题。大家都去找Jenkins的问题,但最后发现是Maven这个工具出现了一些问题(使用时可能参数调错了)。Maven在构建代码的时候,经常会出现构建失败,编译不通过现象。Maven跑测试的时候也可能会报错。这个和你的项目也可能有关系,比如你项目的类找不到了,那可能也会报错了。也就是说,后续在排错时,不仅要考虑工具问题,也要考虑代码本身层面的因素。

也可以使用阿里云这种方式生成spring boot项目

  • 打开链接: 如果打不开也可以使用:https://start.aliyun.com/bootstrap.html

  • 按如下进行配置: 选择一个spring web组件,再添加一个spring mvc示例:

  • 配置完成后,下载代码:

🤷‍♀️ 项目pom.xml和maven里settings.xml之间的关系

注意:这里容易混淆的一点是:

1.项目的根目录会存在一个pom.xml文件:(该文件用于定义项目的依赖包信息和构建配置);

2.maven软件包里的settings.xml:是管理maven的;(后期会该改个配置文件)

  • 项目pom.xml

image-20230619210317024

  • maven里settings.xml

image-20230620061734776

注意:其它构建工具和Maven基本一致!!!

Ant(扩展)

官网:https://ant.apache.org/bindownload.cgi Ant现在用的比较少了,也是一个项目构建依赖管理工具,使用xml的文件保存配置(build.xml)

安装配置:

wget 
tar

export
export

source

ant -version

常用命令:

ant
ant -f ../build.xml

Jenkins集成:

stage("build"){
steps{
script {
sh "ant -f build.xml"
}
}
}

案例:gitlabCI & Maven集成

  • 创建.gitlabci-yml文件,编写流水线代码:
stages:
- build
- test

variables:
GIT_CHECKOUT: "false"
RUNNER_TAG: "maven"

pipelineInit:
stage: .pre
tags:
- "${RUNNER_TAG}"
variables:
GIT_CHECKOUT: "true"
script:
- ls -l

cibuild:
tags:
- "${RUNNER_TAG}"
stage: build
script:
- /usr/local/apache-maven-3.8.5/bin/mvn clean package

citest1:
tags:
- "${RUNNER_TAG}"
stage: test
script:
- /usr/local/apache-maven-3.8.5/bin/mvn test

  • 确认下runner上有maven标签:

  • 因为前面jenkins的slave节点和gitlabci-runner不是同一个节点,因此这里还需要把maven环境的源修改为阿里源,然后构建: 修改方法见jenkins构建部分:

可以看到,能够成功构建了。

  • 这边再跑一次流水线,观察下构建速度:

这次构建就没有下载包了,速度很快,这是因为使用了maven缓存: 注意:gitlabCI-runner的用户是gitlab-runner,因此缓存位置要清楚。

🍀 配置maven全局缓存:

  • 此时有必要配置下maven的全局缓存了: 1.占用磁盘空间 2.你的编译构建时间加长了 我们先创建下全局缓存配置,再把gitlab-runner用户的缓存移动到全局缓存,再观察小构建速度:
[root@gitlab-runner ~]#mkdir -p /data/maven_build_cache
[root@gitlab-runner ~]#mv /home/gitlab-runner/.m2/repository/* /data/maven_build_cache/


[root@gitlab-runner ~]#vim /usr/local/apache-maven-3.8.5/conf/settings.xml
……
<localRepository>/data/maven_build_cache</localRepository>

可以看到,配置的全局缓存起作用了: 测试完成。😘

案例:Go项目构建工具

🍀 Go配置环境 见我的另外2篇文章: 1.本地路径: 实战:windows上基于vscode的golang环境搭建(博客分享-测试成功)-kk-2022.4.28 实战:centos上安装Go软件(博客分享-成功测试)-kk-2022.5.18

2.csdn路径: https://blog.csdn.net/weixin_39246554/article/details/124495828 https://blog.csdn.net/weixin_39246554/article/details/124507926

💘 实践:Go项目构建流水线(测试成功)-2022.5.19

🍂 jenkins集成

  • gitlab上创建一个devops4-golang-service的项目,然后把本地demo.go代码推送到仓库: demo.go代码:
package main

import (
"fmt"
)

func main() {
fmt.Println("hello world!")
}

推送过程:

hg@LAPTOP-G8TUFE0T MINGW64 ~/Desktop/golang/demo
$ pwd
/c/Users/hg/Desktop/golang/demo

hg@LAPTOP-G8TUFE0T MINGW64 ~/Desktop/golang/demo
$ ls
demo.go

hg@LAPTOP-G8TUFE0T MINGW64 ~/Desktop/golang/demo
$ git init
Initialized empty Git repository in C:/Users/hg/Desktop/golang/demo/.git/

hg@LAPTOP-G8TUFE0T MINGW64 ~/Desktop/golang/demo (master)
$ git add .

hg@LAPTOP-G8TUFE0T MINGW64 ~/Desktop/golang/demo (master)
$ git commit -am"init commit"
[master (root-commit) 900a326] init commit
1 file changed, 9 insertions(+)
create mode 100644 demo.go

hg@LAPTOP-G8TUFE0T MINGW64 ~/Desktop/golang/demo (master)
$ git remote add origin http://172.29.9.101/devops4/devops4-golang-service.git

hg@LAPTOP-G8TUFE0T MINGW64 ~/Desktop/golang/demo (master)
$ git push origin master
Username for 'http://172.29.9.101': root
Counting objects: 3, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 273 bytes | 136.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To http://172.29.9.101/devops4/devops4-golang-service.git
* [new branch] master -> master

hg@LAPTOP-G8TUFE0T MINGW64 ~/Desktop/golang/demo (master)

在gitlab上查看:

  • jenkins上新建一个叫做devops4-golang-service的流水线:

  • 编写jenkinsfile流水线: 完整代码:

pipeline {
agent {
label "build"
}

parameters {
string defaultValue: 'http://172.29.9.101/devops4/devops4-golang-service.git', name: 'srcUrl', trim: true
string defaultValue: 'master', name: 'branchName', trim: true
}

stages {
stage('CheckOut') {
steps {
script {
checkout([$class: 'GitSCM',
branches: [[name: "${params.branchName}"]],
extensions: [],
userRemoteConfigs: [[credentialsId: '54df701e-d369-4f69-85c6-7209d45c283b',
url: "${params.srcUrl}"]]])
}
}
}

stage('Build') {
steps {
script {
sh "/usr/local/go/bin/go build demo.go"
}
}
}

}
}
  • 构建效果: 在工作目录也可以看到产生的的demo二进制文件:

🍀 gitlabCI & Go集成 在gitlab上新建一个.gitlab-ci.yml文件,并编写代码,提交测试: 完整代码:

stages:
- build
- test

variables:
GIT_CHECKOUT: "false"
RUNNER_TAG: "go"

pipelineInit:
stage: .pre
tags:
- "${RUNNER_TAG}"
variables:
GIT_CHECKOUT: "true"
script:
- ls -l

cibuild:
tags:
- "${RUNNER_TAG}"
stage: build
script:
- /usr/local/go/bin/go build demo.go

提交后观看效果: 测试结束。😘

案例:打包maven依赖包-2024.8.20(测试成功)

maven下载依赖包很耗时,我能不能先第一次下载下来,然后再吧下载好的一来压缩打包起来,放到其他机器上使用呢?

是的,你可以将 Maven 下载的依赖包(通常存放在本地 .m2 目录下)打包起来,然后在其他机器上解压使用,以避免重复下载这些依赖包。这在网络环境不佳或者需要在多台机器上配置相同环境时非常有用。以下是具体步骤:

步骤一:在第一台机器上下载依赖包

  1. 执行 Maven 构建命令 在需要下载依赖的项目目录下执行 Maven 命令,如:

    mvn clean install

    这会下载所有需要的依赖包到本地 .m2 目录。

步骤二:打包 .m2 目录

  1. 找到 .m2 目录 通常在 Unix 系统下为 ~/.m2,在 Windows 系统下为 %USERPROFILE%\.m2

  2. 打包 .m2 目录 使用 tarzip 等工具将 .m2 目录打包:

    tar -czvf maven-repo.tar.gz ~/.m2/repository

    或者用 zip

    zip -r maven-repo.zip ~/.m2/repository

步骤三:在其他机器上解压 .m2 目录

  1. 传输打包文件 将打包好的文件传输到其他机器上,使用 scprsync 或 USB 设备等。

  2. 解压打包文件 在其他机器上解压 .m2 目录:

    tar -xzvf maven-repo.tar.gz -C ~/

    或者用 unzip

    unzip maven-repo.zip -d ~/

步骤四:验证依赖包是否可用

  1. 执行 Maven 构建命令 在其他机器上验证是否可以直接使用这些依赖包:

    mvn clean install

    这时候,Maven 应该会直接从本地 .m2 目录中获取依赖包,而不是从远程仓库下载。

==本次输出==

cd ~
tar -xzvf maven-repo.tar.gz
mv root/.m2 ~

自动化方法:使用 Nexus 或 Artifactory

如果你需要在多个项目和团队中重复使用依赖包,建议使用 Maven 私有仓库,如 Nexus 或 Artifactory,这样可以更有效地管理和共享依赖包。

总结

通过将 .m2 目录打包并在其他机器上解压,你可以避免在多台机器上重复下载 Maven 依赖包,从而节省时间和带宽。这种方法特别适用于网络环境不佳的情况或者你需要快速配置多个开发环境。

关于我

我的博客主旨:

  • 排版美观,语言精炼;
  • 文档即手册,步骤明细,拒绝埋坑,提供源码;
  • 本人实战文档都是亲测成功的,各位小伙伴在实际操作过程中如有什么疑问,可随时联系本人帮您解决问题,让我们一起进步!

🍀 微信二维码 x2675263825 (舍得), qq:2675263825。

image-20230107215114763

🍀 微信公众号 《云原生架构师实战》

image-20230107215126971

🍀 语雀

https://www.yuque.com/xyy-onlyone

image-20230515221819681

🍀 csdn https://blog.csdn.net/weixin_39246554?spm=1010.2135.3001.5421

image-20230107215149885

🍀 知乎 https://www.zhihu.com/people/foryouone

image-20230107215203185

最后

好了,关于本次就到这里了,感谢大家阅读,最后祝大家生活快乐,每天都过的有意义哦,我们下期见!