您当前的位置: 首页 >  spring

wu@55555

暂无认证

  • 2浏览

    0关注

    201博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

springboot项目如何打包成.sh脚本形式运行|assemly插件打包自定义脚本参数

wu@55555 发布时间:2022-09-03 02:37:25 ,浏览量:2

0. 引言

springboot作为目前主流的java开发框架,因为便捷和易上手的特性,深受开发者欢迎。springboot默认以jar包形式,通过java -jar指令运行

但这样的启动方式实际上不是很友好,我们常常看到各类组建通过bin目录下的start.sh脚本进行启动,我们可以在.sh脚本中书写自定义各类启动参数。这样的方式更加友好,那么我们的springboot项目可不可以打包成这样的形式启动呢?

当然可以,今天我们就来看如何实现

1. assembly-plugin插件

assembly是一个maven插件,专门用于maven项目打包。它的作用就是可以将项目打包成一个可以通过脚本文件启动的项目包

其打包后的项目文件结构如下:

bin 项目启动/停止/重启等脚本文件目录 conf 配置文件目录 lib 依赖包目录

assembly插件需要配置一个.xml配置文件来指定打包设置。该文件常见的标签配置如下:

  • id: 标识符,添加到打包文件名称的后缀符 如果设置为${project.version}则会将项目版本号添加到打包文件名中
  • formats:打包格式,支持zip、tar、tar.gz (or tgz)、tar.bz2 (or tbz2)、jar、dir、war等格式,可以同时指定多种打包形式,通过format标签指定

	tar.gz
   jar

  • includeBaseDirectory 是否包含打包层目录,当设置false时,所有文件直接打包到根目录下;为true时,打包到${artifactId}目录下
  • dependencySets 设置项目依赖包打包的目录
  • fileSets 设置要包含的文件集,可以定义多个fileSet,单个fileSet标签中又包含如下子标签 directory:要打包的文件夹 outputDirectory:打包出来的文件夹,比如为bin,则表示将directory文件夹下的文本打包到bin目录下 includes: 指定要包含(include)或排除(exclude)的打包文件 fileMode:指定文件权限,权限的指定参考linux系统文件权限,比较常用的0755,0644。我们在文末单独讲解 directoryMode:指定目录权限

    src/main/assembly/bin
    bin
    
       start.sh
       stop.sh
    
    0755

2. 实操

1、首先我们先创建一个springboot项目assembly-plugin-demo,并且引入spring web依赖,模拟一个web项目


            org.springframework.boot
            spring-boot-starter-web

2、创建一个HelloController,并书写一个简单的接口,用于模拟接口

/**
 * @author benjamin_5
 * @Description
 * @date 2022/8/27
 */
@RestController
public class HelloController {

    @GetMapping("/hello")
    public String hello(){
        return "hello~~";
    }

}

3、在项目src/main下创建bin目录,并声明启动/停止/重启脚本

启动脚本 start.sh

#!/usr/bin/env bash

#source $(dirname $0)/../../env.sh
# 进入当前文件目录
cd `dirname $0`
# 返回上一级
cd ..

# jar包名称
#SERVER_JAR="$SERVER_NAME-$PROJECT_VERSION.jar"
SERVER_JAR="assembly_plugin_demo-0.0.1-SNAPSHOT.jar"
BASE_DIR=`pwd`

# 获取java路径
if [ "$JAVA_HOME" != "" ]; then
 JAVA="$JAVA_HOME/bin/java"
else
 JAVA=java
fi

# 指定日志输出路径
LOGS_DIR=""
if [ -n "$LOGS_FILE" ]; then
    LOGS_DIR=`dirname $LOGS_FILE`
else
    LOGS_DIR=$BASE_DIR/logs
fi
if [ ! -d $LOGS_DIR ]; then
    mkdir $LOGS_DIR
fi
STDOUT_FILE=$LOGS_DIR/stdout.log

# 设置jvm参数
JAVA_OPTS="-server -Xms1G -Xmx2G -Xmn256m -Xss1m \
-XX:SurvivorRatio=4 -XX:+UseConcMarkSweepGC -XX:+UseCMSCompactAtFullCollection \
-XX:CMSInitiatingOccupancyFraction=60 -XX:+PrintGCDateStamps \
-XX:+PrintGCDetails -Xloggc:$LOGS_DIR/gc.log"

# 如果项目已经启动则之前停止项目
echo -n "Starting server ..."
 PID=$(ps -ef | grep $SERVER_JAR | grep -v grep |awk '{print $2}')
if [ -z "$PID" ]; then
 echo Application is already stopped
else
 echo kill $PID
 kill -9 $PID
fi

# 以指定参数启动项目
nohup $JAVA $JAVA_OPTS $JAVA_DEBUG_OPT -jar lib/$SERVER_JAR > $STDOUT_FILE 2>&1 &

if [ $? -eq 0 ];then
 # echo -n $! > "$PIDFILE"
 if [ $? -eq 0 ]
 then
 sleep 1
 echo STARTED
 else
 echo FAILED TO WRITE PID
 exit 1
 fi
else
 echo SERVER DID NOT START
 exit 1
fi

PID_NOW=`ps -ef | grep java | grep -v grep | grep "$SERVER_JAR" | awk '{print $2}'`
# 打印参数
echo "进程ID: $PID_NOW"
echo "输出日志:$STDOUT_FILE"

停止脚本 stop.sh

#!/usr/bin/env bash

# jar包名称
SERVER_JAR="assembly_plugin_demo-0.0.1-SNAPSHOT.jar"

# 停止项目
echo -n "Stopping server ..."
    PID=$(ps -ef | grep $SERVER_JAR | grep -v grep |awk '{print $2}')
if [ -z "$PID" ]; then
  echo Application is already stopped
else
  echo kill $PID
  kill -9 $PID
fi
exit 0

4、然后我们在项目的src/main目录下创建一个assembly目录,并且创建一个assembly插件的配置文件assembly.xml

我们需要在assembly.xml配置文件中申明bin,conf,lib三个路径


	assembly
	
		tar.gz
	
	true
	
		
			src/main/assembly/bin
			bin
			0755
		
		
			src/main/resources
			conf
			0644
		
	
	
	
		
			lib
		
	

在这里插入图片描述

5、其次我们在pom.xml中引入assembly-plugin插件


    maven-assembly-plugin
    
    src/main/assembly/assembly.xml
    
    
        
             make-assembly
             package
             
                 single
             
         
    

6、重新加载pom文件,下载assembly插件

7、执行打包指令

在这里插入图片描述

出现BUILD SUCCESS说明打包成功

在这里插入图片描述

8、打包文件输出在target目录下,如果有指定输出目录,则在输出目录中查找

在这里插入图片描述

9、我们将打包出来的’.tar.gz’压缩包文件解压,可以看到其结构就是我们上述指定的bin、conf、lib目录

在这里插入图片描述

10、进入bin目录,执行start.sh指令启动项目

./start.sh

在这里插入图片描述

11、我们已经将输出内容指定到logs目录下的stdout.log,我们可以通过该日志查看启动明细

如果启动失败,也可以通过该日志文件查看报错明细。同时也指定了gc日志gc.log,可以通过该文件查看gc详情

在这里插入图片描述 12、从上述日志看启动成功了,我们通过访问之前定义的接口来测试

可以看到正常输出了接口数据,证明我们打包并启动成功了

在这里插入图片描述

如上,我们的springboot就成功打包成了bin目录启动形式。

2.1 优化【未完善】

上述打包程序并不是最佳的,因为我们的项目的jar包名称是在start.sh脚本中写死的,如果版本升级,或者复用到其他模块中时,就需要修改脚本了,非常的不方便

所以我们做出优化,希望能够自动获取这个jar包名称

可以看到我们的jar包名称是:assembly_plugin_demo-0.0.1-SNAPSHOT.jar

这个名称由两部分组成:服务名,版本号

于是我们就要想办法获取这两个属性

1、首先服务名直接在application.properties配置文件中通过spring.application.name属性获取。

2、配置文件是会一起打包到conf文件夹下的,但我们怎么在shell脚本中获取配置文件中的指定配置项呢?

答案是可以通过sed指令,如下所示

PROJECT_VERSION=`sed '/^project.version=/!d;s/.*=//' conf/application.properties`

3、其次就是版本号,我们知道版本号是定义在pom.xml文件中的,打包后是没有pom文件的,那么我们的思路就是在application.properties配置文件中获取到版本号

这里就要考验大家的springboot知识积累了,如何在配置文件中获取到pom属性呢?

4、首先我们要在pom.xml文件中,添加resource标签,设置filtering=true,让配置文件可以读取pom属性


	
            
                src/main/resources
                true
            
	

5、设置完成后记得重新加载pom文件!!!

6、然后在application,properties配置文件中通过@xxx@获取pom属性"project.version"

application.version=@project.version@

7、在start.sh脚本中再声明版本号和jar包名变量

PROJECT_VERSION=`sed '/^application.version=/!d;s/.*=//' conf/application.properties`
SERVER_JAR="$SERVER_NAME-$PROJECT_VERSION.jar"

8、重新打包即可,stop.sh脚本中处理类似

9、这里存在一个问题尚未解决,上述说的@xxx@的方式读取pom属性,在idea中打包,可以看到本身的打包插件已经加载了pom中的属性,如下图

在这里插入图片描述

但是assembly插件打包的conf目录中的配置文件中却没能加载pom的值,初步怀疑是加载顺序的问题,仍在研究中,这里也抛出问题点,大家一起讨论解决。有思路的同学,可以留言讨论

在这里插入图片描述

演示代码见文末

3. 补充内容 fileMode/directoryMode权限

assembly中的权限表示与linux系统一致,通过4位数值表示权限

其中第一位0表示采用十进制,第二位表示用户权限,第三位组用户权限,第四位表示其他用户权限,而十进制表示的权限等级如下:

十进制linux权限说明0—无任何权限1–x执行权限2–w可写权限3-wx可写、执行权限4r–只读权限5r-x可读、可执行权限6rw-读写权限7rwx全部权限

则0755表示用户具有读/写/执行权限,组用户和其它用户具有读写权限;0644表示用户具有读写权限,组用户和其他用户具有只读权限

4. 演示源码

git地址

关注
打赏
1664985904
查看更多评论
立即登录/注册

微信扫码登录

0.0432s