spring boot jar 分离自动部署脚本

背景

远程部署时spring boot 包,比较大。可以采用依赖库和业务包分离的方式。提供一个脚本进行自动部署

maven 配置分离jar包

xml 复制代码
 <build>
        <finalName>${project.artifactId}</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring-boot.version}</version>
                <configuration>
                    <!-- 导入系统路径包 -->
                    <includeSystemScope>true</includeSystemScope>
                    <includes>
                        <include>
                            <groupId>nothing</groupId>
                            <artifactId>nothing</artifactId>
                        </include>
                    </includes>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <configuration>
                    <archive>
                        <!-- 生成的jar中不要包含pom.xml和pom.properties这两个文件 -->
                        <addMavenDescriptor>false</addMavenDescriptor>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <classpathPrefix>lib/</classpathPrefix>
                            <!--这里需要修改为你的项目的主启动类-->
                            <mainClass>com.ruoyi.RuoYiApplication</mainClass>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>
            <!--设置将 lib 拷贝到应用 Jar 外面-->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <executions>
                    <execution>
                        <id>copy-lib</id>
                        <phase>package</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>target/lib</outputDirectory>
                            <excludeTransitive>false</excludeTransitive>
                            <stripVersion>false</stripVersion>
                            <includeScope>runtime</includeScope>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

部署脚本

bash 复制代码
#!/bin/bash

AppName="smart_engineering_admin.jar"
RemoteUser="root"
RemoteHost="xxx.xxx.xxx.xxx"
JVM_OPTS=" -Dloader.path=smart_engineering/lib -Dserver.port=8080 -Dname=$AppName  -Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8 -Duser.timezone=Asia/Shanghai -Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDateStamps  -XX:+PrintGCDetails -XX:NewRatio=1 -XX:SurvivorRatio=30 -XX:+UseParallelGC -XX:+UseParallelOldGC"

start() {
    echo "Starting $AppName on $RemoteHost"

    # 定义一个内嵌的函数来远程查询 PID
    query() {
        ssh "${RemoteUser}@${RemoteHost}" "ps -ef | grep java | grep '$AppName' | grep -v grep | awk '{print \$2}'"
    }

    # 获取远程进程 ID
    PID=$(query)

    if [ -n "$PID" ]; then
        echo "$AppName is already running on $RemoteHost (pid: $PID)..."
    else
        echo "Starting $AppName on $RemoteHost..."
        ssh "${RemoteUser}@${RemoteHost}" "nohup java $JVM_OPTS -jar smart_engineering/$AppName > /dev/null 2>&1 &"
        echo "$AppName started successfully on $RemoteHost."
        ssh "${RemoteUser}@${RemoteHost}" "tail -f logs/sys-console.log"
    fi
}

sync() {
    rsync -avc --delete ruoyi-admin/target/lib/ root@140.143.209.33:smart_engineering/lib
    scp ruoyi-admin/target/smart_engineering_admin.jar root@140.143.209.33:smart_engineering/
}

stop() {
    echo "Stopping $AppName on $RemoteHost"

    # 定义一个内嵌的函数来远程查询 PID
    query() {
        ssh "${RemoteUser}@${RemoteHost}" "ps -ef | grep java | grep '$AppName' | grep -v grep | awk '{print \$2}'"
    }

    # 获取进程 ID
    PID=$(query)

    if [ -n "$PID" ]; then
        echo "$AppName (pid:$PID) is running. Sending TERM signal..."
        ssh "${RemoteUser}@${RemoteHost}" "kill -TERM $PID"

        # 等待进程退出
        while [ -n "$PID" ]; do
            sleep 1
            PID=$(query)
        done
        echo "$AppName has exited."
    else
        echo "$AppName is already stopped."
    fi
}



sync
stop
sleep 2
start
  • 优点
    • 依赖包不变化不会同步,减少上传的文件
    • 每次都同步业务包,保证准确性
    • 提升发布速度

要求

  • windows 的wsl下可用
  • 需要和服务器配置ssh互信

进一步封装

复制代码
#!/bin/bash
 ./mvnw -T 1C clean package -P prod
 ./push_run.sh
相关推荐
子兮曰27 分钟前
Bun 重写为 Rust:11天、64个Claude、16.5万美元,一次改变行业认知的激进实验
前端·后端·bun
Listen·Rain29 分钟前
提示词和提示词模板
java·人工智能·spring boot
子兮曰32 分钟前
Node.js v26.5.0 深度解读:import Text、流式 ReadableStreamTee、以及隐藏的安全加固浪潮
前端·后端·node.js
子兮曰35 分钟前
TypeScript 7.0 RC 深度解读:Go 重写完成,10 倍提速,编译器的「奇点时刻」
前端·后端·typescript
kosan41 分钟前
.NET/C# 实战:我如何把登录验证码从“裸奔”改到“铜墙铁壁”
后端
王中阳Go1 小时前
AI编程实践:规则 + 技能 + 子代理 + 钩子,拆解Trae AI 开发规范的完整落地范式
后端·agent·ai编程
码事漫谈2 小时前
放下代码洁癖,享受挖坑人生
后端
_张有志_2 小时前
手撕 STL:一棵红黑树,凭什么同时撑起 set 和 map?
后端
妙码生花2 小时前
从 PHP 到 AI + Golang,程序员自救转型手记(二十七):管理员登录验证码开关
前端·后端·ai编程
她的男孩2 小时前
当 Spring Boot 遇上 Flowable 7:Forge 框架企业级工作流引擎架构全解析
人工智能·后端·程序员