SpringBoot项目打包加部署方案
SpringBoot项目打包加部署方案
1、新建项目
项目结构:
2、pom文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.5.6</version><relativePath/></parent><groupId>com.zsx</groupId><artifactId>hello-spring-boot</artifactId><version>0.0.1</version><name>hello-spring-boot</name><description>Demo project for Spring Boot</description><properties><java.version>1.8</java.version><!-- hello-spring-boot-0.0.1 --><scripts_packageName>${project.artifactId}-${project.version}</scripts_packageName><!-- com.zsx.HelloSpringBootApplication --><scripts_bootMain>com.zsx.HelloSpringBootApplication</scripts_bootMain></properties><profiles><profile><id>node</id><properties><!-- 传递给脚本的参数值 --><activeProfile>node</activeProfile><!-- hello-spring-boot-0.0.1 --><package-name>${scripts_packageName}</package-name><!-- com.zsx.HelloSpringBootApplication --><boot-main>${scripts_bootMain}</boot-main></properties><activation><activeByDefault>true</activeByDefault></activation></profile><profile><id>node1</id><properties><activeProfile>node1</activeProfile><!-- hello-spring-boot-0.0.1 --><package-name>${scripts_packageName}</package-name><!-- com.zsx.HelloSpringBootApplication --><boot-main>${scripts_bootMain}</boot-main></properties></profile><profile><id>node2</id><properties><activeProfile>node2</activeProfile><!-- hello-spring-boot-0.0.1 --><package-name>${scripts_packageName}</package-name><!-- com.zsx.HelloSpringBootApplication --><boot-main>${scripts_bootMain}</boot-main></properties></profile><profile><id>node3</id><properties><activeProfile>node3</activeProfile><!-- hello-spring-boot-0.0.1 --><package-name>${scripts_packageName}</package-name><!-- com.zsx.HelloSpringBootApplication --><boot-main>${scripts_bootMain}</boot-main></properties></profile></profiles><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><scope>test</scope></dependency></dependencies><build><resources><resource><!-- activeProfile = node/node1/node2/node3 --><!-- HelloSpringBoot/src/main/profiles/node --><!-- HelloSpringBoot/src/main/profiles/node1 --><!-- HelloSpringBoot/src/main/profiles/node2 --><!-- HelloSpringBoot/src/main/profiles/node3 --><directory>${project.basedir}/src/main/profiles/${activeProfile}</directory></resource><resource><!-- HelloSpringBoot/src/main/resources --><directory>${project.basedir}/src/main/resources</directory><includes><include>static/**</include><include>templates/**</include></includes></resource></resources><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><includes><include><groupId>non-exists</groupId><artifactId>non-exists</artifactId></include></includes></configuration><executions><execution><goals><goal>repackage</goal></goals></execution></executions></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><source>1.8</source><target>1.8</target></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-jar-plugin</artifactId><version>2.6</version><configuration><archive><addMavenDescriptor>false</addMavenDescriptor><manifest><addClasspath>true</addClasspath><classpathPrefix>lib/</classpathPrefix><!-- com.zsx.HelloSpringBootApplication --><mainClass>${scripts_bootMain}</mainClass></manifest></archive><!--打包排除项--><excludes><exclude>**/*.yml</exclude><exclude>**/*.properties</exclude><exclude>**/*.xml</exclude><exclude>**/*.sh</exclude></excludes></configuration><executions><execution><id>make-a-jar</id><phase>compile</phase><goals><goal>jar</goal></goals></execution></executions></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-assembly-plugin</artifactId><version>2.4</version><!-- The configuration of the plugin --><configuration><!-- Specifies the configuration file of the assembly plugin --><descriptors><!-- HelloSpringBoot/src/main/assembly/assembly.xml --><descriptor>${project.basedir}/src/main/assembly/assembly.xml</descriptor></descriptors></configuration><executions><execution><id>make-assembly</id><phase>package</phase><goals><goal>single</goal></goals></execution></executions></plugin></plugins></build>
</project>
3、assembly.xml
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd
http://maven.apache.org/ASSEMBLY/2.0.0 "><!-- activeProfile = node/node1/node2/node3 --><id>${activeProfile}</id><!-- 打包成一个用于发布的zip文件 --><formats><format>zip</format></formats><!-- true: zip中生成一级目录(此处屏蔽,配合脚本需要profiles后缀) --><includeBaseDirectory>false</includeBaseDirectory><dependencySets><dependencySet><!-- 打包进zip文件的lib目录 --><useProjectArtifact>false</useProjectArtifact><!-- hello-spring-boot-0.0.1-node/lib --><!-- hello-spring-boot-0.0.1-node1/lib --><!-- hello-spring-boot-0.0.1-node2/lib --><!-- hello-spring-boot-0.0.1-node3/lib --><outputDirectory>${package-name}-${activeProfile}/lib</outputDirectory><unpack>false</unpack></dependencySet></dependencySets><fileSets><!-- 配置文件打包进zip文件的conf目录 --><fileSet><!-- HelloSpringBoot/src/main/profiles/node --><!-- HelloSpringBoot/src/main/profiles/node1 --><!-- HelloSpringBoot/src/main/profiles/node2 --><!-- HelloSpringBoot/src/main/profiles/node3 --><directory>${project.basedir}/src/main/profiles/${activeProfile}</directory><!-- hello-spring-boot-0.0.1-node/conf --><!-- hello-spring-boot-0.0.1-node1/conf --><!-- hello-spring-boot-0.0.1-node2/conf --><!-- hello-spring-boot-0.0.1-node3/conf --><outputDirectory>${package-name}-${activeProfile}/conf</outputDirectory><includes><include>**/*</include><!--<include>*.xml</include>--><!--<include>*.properties</include>--><!--<include>*.yml</include>--></includes></fileSet><!-- 启动脚本打包进zip文件 --><fileSet><!-- HelloSpringBoot/src/main/scripts --><directory>${project.basedir}/src/main/scripts</directory><outputDirectory></outputDirectory><includes><include>**/*</include></includes><!-- 文件文件权限为777 --><fileMode>777</fileMode><!-- 目录权限为777 --><directoryMode>777</directoryMode><!-- 脚本中参数变量为pom中的值,这步非常关键 --><filtered>true</filtered></fileSet><!-- 项目编译出来的jar打包进zip文件 --><fileSet><!-- HelloSpringBoot/target --><directory>${project.build.directory}</directory><!-- hello-spring-boot-0.0.1-node/ --><!-- hello-spring-boot-0.0.1-node1/ --><!-- hello-spring-boot-0.0.1-node2/ --><!-- hello-spring-boot-0.0.1-node3/ --><outputDirectory>${package-name}-${activeProfile}/</outputDirectory><includes><include>*.jar</include></includes></fileSet></fileSets>
</assembly>
4、profiles/node/application.yml
spring:application:name: hello-spring-boot
server:port: 1020
5、profiles/node1/application.yml
spring:application:name: hello-spring-boot
server:port: 1021
6、profiles/node2/application.yml
spring:application:name: hello-spring-boot
server:port: 1022
7、profiles/node3/application.yml
spring:application:name: hello-spring-boot
server:port: 1023
8、scripts/shenniu_publish.sh
#!/usr/bin/env bash
# 可变参数变量
# 支持 java,javac,netcore发布
languageType="javac"
# 参数值由pom文件传递
# 压缩包名称
baseZipName="${package-name}-${activeProfile}"
# 命令启动包名
packageName="${package-name}"
# 定main入口类
mainClass="${boot-main}"# 固定变量
basePath=$(cd $(dirname $0)/pwd
)# 压缩包路径
baseZipPath="${basePath}/${baseZipName}.zip"
# 解压部署磁盘路径
baseDirPath="${basePath}"
# 进程pid
pid=# 解压
function shenniu_unzip() {echo "解压---------------------------------------------"echo "压缩包路径:${baseZipPath}"if [ ! $(find ${baseZipPath}) ]; thenecho "不存在压缩包:${baseZipPath}"elseecho "解压磁盘路径:${baseDirPath}/${baseZipName}"echo "开始解压..."# 解压命令unzip -od ${baseDirPath}/${baseZipName} ${baseZipPath}# 设置执行权限chmod +x ${baseDirPath}/${baseZipName}/${packageName}echo "解压完成。"fi
}# 检测pid
function getPid() {echo "检测状态---------------------------------------------"pid=$(ps -ef | grep -n ${packageName} | grep -v grep | awk '{print $2}')if [ ${pid} ]; thenecho "运行pid:${pid}"elseecho "未运行"fi
}# 启动程序
function start() {# 启动前,先停止之前的stopif [ ${pid} ]; thenecho "停止程序失败,无法启动"elseecho "启动程序---------------------------------------------"# 选择语言类型read -p "输入程序类型(java,javac,netcore),下一步按回车键(默认:${languageType}):" read_languageTypeif [ ${read_languageType} ]; thenlanguageType=${read_languageType}fiecho "选择程序类型:${languageType}"# 进入运行包目录cd ${baseDirPath}/${baseZipName}# 分类启动if [ "${languageType}" == "javac" ]; thenif [ ${mainClass} ]; thennohup java -cp conf:lib\*.jar:${packageName}.jar ${mainClass} >${baseDirPath}/${packageName}.out 2>&1 &# nohup java -cp conf:lib\*.jar:${packageName}.jar ${mainClass} >/dev/null 2>&1 &fielif [ "${languageType}" == "java" ]; thennohup java -jar ${baseDirPath}/${baseZipName}/${packageName}.jar >/dev/null 2>&1 &# java -jar ${baseDirPath}/${baseZipName}/${packageName}.jarelif [ "${languageType}" == "netcore" ]; then#nohup dotnet run ${baseDirPath}/${baseZipName}/${packageName} >/dev/null 2>&1 &nohup ${baseDirPath}/${baseZipName}/${packageName} >/dev/null 2>&1 &fi# 查询是否有启动进程getPidif [ ${pid} ]; thenecho "已启动"# nohup日志tail -n 50 -f ${baseDirPath}/${packageName}.outelseecho "启动失败"fifi
}# 停止程序
function stop() {getPidif [ ${pid} ]; thenecho "停止程序---------------------------------------------"kill -9 ${pid}getPidif [ ${pid} ]; then# stopecho "停止失败"elseecho "停止成功"fifi
}# 启动时带参数,根据参数执行
if [ ${#} -ge 1 ]; thencase ${1} in"start")start;;"restart")start;;"stop")stop;;"unzip")# 执行解压shenniu_unzip# 执行启动start;;*)echo "${1}无任何操作";;esac
elseecho "command如下命令:unzip:解压并启动start:启动stop:停止进程restart:重启示例命令如:./shenniu_publish start"
fi
9、打包
$ mvn package -Pnode2
# 打包之后的文件名称为hello-spring-boot-0.0.1-node2.zip# 解压
$ unzip -od hello-spring-boot-0.0.1-node2 hello-spring-boot-0.0.1-node2.zip
目录结构:
$ tree hello-spring-boot-0.0.1-node2
hello-spring-boot-0.0.1-node2
├── hello-spring-boot-0.0.1-node2
│ ├── conf
│ │ └── application.yml
│ ├── hello-spring-boot-0.0.1.jar
│ └── lib
│ ├── jackson-annotations-2.12.5.jar
│ ├── jackson-core-2.12.5.jar
│ ├── jackson-databind-2.12.5.jar
│ ├── jackson-datatype-jdk8-2.12.5.jar
│ ├── jackson-datatype-jsr310-2.12.5.jar
│ ├── jackson-module-parameter-names-2.12.5.jar
│ ├── jakarta.annotation-api-1.3.5.jar
│ ├── jul-to-slf4j-1.7.32.jar
│ ├── log4j-api-2.14.1.jar
│ ├── log4j-to-slf4j-2.14.1.jar
│ ├── logback-classic-1.2.6.jar
│ ├── logback-core-1.2.6.jar
│ ├── slf4j-api-1.7.32.jar
│ ├── snakeyaml-1.28.jar
│ ├── spring-aop-5.3.12.jar
│ ├── spring-beans-5.3.12.jar
│ ├── spring-boot-2.5.6.jar
│ ├── spring-boot-autoconfigure-2.5.6.jar
│ ├── spring-boot-starter-2.5.6.jar
│ ├── spring-boot-starter-json-2.5.6.jar
│ ├── spring-boot-starter-logging-2.5.6.jar
│ ├── spring-boot-starter-tomcat-2.5.6.jar
│ ├── spring-boot-starter-web-2.5.6.jar
│ ├── spring-context-5.3.12.jar
│ ├── spring-core-5.3.12.jar
│ ├── spring-expression-5.3.12.jar
│ ├── spring-jcl-5.3.12.jar
│ ├── spring-web-5.3.12.jar
│ ├── spring-webmvc-5.3.12.jar
│ ├── tomcat-embed-core-9.0.54.jar
│ ├── tomcat-embed-el-9.0.54.jar
│ └── tomcat-embed-websocket-9.0.54.jar
└── shenniu_publish.sh
# 启动
$ cd hello-spring-boot-0.0.1-node2/
$ ./shenniu_publish.shcommand如下命令:unzip:解压并启动start:启动stop:停止进程restart:重启示例命令如:./shenniu_publish start