SpringBoot项目打包加部署方案

发布于:2025-07-23 ⋅ 阅读:(12) ⋅ 点赞:(0)

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}) ]; then
    echo "不存在压缩包:${baseZipPath}"
  else
    echo "解压磁盘路径:${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} ]; then
    echo "运行pid:${pid}"
  else
    echo "未运行"
  fi
}

# 启动程序
function start() {
  # 启动前,先停止之前的
  stop
  if [ ${pid} ]; then
    echo "停止程序失败,无法启动"
  else
    echo "启动程序---------------------------------------------"

    # 选择语言类型
    read -p "输入程序类型(java,javac,netcore),下一步按回车键(默认:${languageType}):" read_languageType
    if [ ${read_languageType} ]; then
      languageType=${read_languageType}
    fi
    echo "选择程序类型:${languageType}"

    # 进入运行包目录
    cd ${baseDirPath}/${baseZipName}

    # 分类启动
    if [ "${languageType}" == "javac" ]; then
      if [ ${mainClass} ]; then
        nohup 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 &
      fi
    elif [ "${languageType}" == "java" ]; then
      nohup java -jar ${baseDirPath}/${baseZipName}/${packageName}.jar >/dev/null 2>&1 &
      # java -jar ${baseDirPath}/${baseZipName}/${packageName}.jar
    elif [ "${languageType}" == "netcore" ]; then
      #nohup dotnet run ${baseDirPath}/${baseZipName}/${packageName} >/dev/null 2>&1 &
      nohup ${baseDirPath}/${baseZipName}/${packageName} >/dev/null 2>&1 &
    fi

    # 查询是否有启动进程
    getPid
    if [ ${pid} ]; then
      echo "已启动"
      # nohup日志
      tail -n 50 -f ${baseDirPath}/${packageName}.out
    else
      echo "启动失败"
    fi
  fi
}

# 停止程序
function stop() {
  getPid
  if [ ${pid} ]; then
    echo "停止程序---------------------------------------------"
    kill -9 ${pid}

    getPid
    if [ ${pid} ]; then
      # stop
      echo "停止失败"
    else
      echo "停止成功"
    fi
  fi
}

# 启动时带参数,根据参数执行
if [ ${#} -ge 1 ]; then
  case ${1} in
  "start")
    start
    ;;
  "restart")
    start
    ;;
  "stop")
    stop
    ;;
  "unzip")
    # 执行解压
    shenniu_unzip
    # 执行启动
    start
    ;;
  *)
    echo "${1}无任何操作"
    ;;
  esac
else
  echo "
    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.sh

    command如下命令:
    unzip:解压并启动
    start:启动
    stop:停止进程
    restart:重启

    示例命令如:./shenniu_publish start

网站公告

今日签到

点亮在社区的每一天
去签到