介绍
我们使用spring-boot-maven-plugin打包,会生成一个整体的jar包(Fatjar),配置文件和模块jar包都打进去了。如果想手动修改配置或者替换部分jar的话是实现不了的。
而assembly可以加载jar外的配置文件,可以很好的解决上面的问题。另外我们可以编写应用服务脚本(启动,关闭等),配置到相关的自定义文件(通常是bin)下,这样就可以很方便的对springboot项目进行操作。
我们会设置在jar包同等级的目录下创建一个config目录,config目录下在再放一份application.properties,这样做是为了便于从外部修改配置。这是因为springboot读取配置的优先级决定的。优先级如下:
1.jar包同级目录的config目录下的配置
2.当前目录下配置
3.classpath的config目录下配置
4.classpath根目录配置
assembly配置
配置内容如下:
pom.xml配置
我们先来配置下项目的pom.xml,如下所示:
<build>
<finalName>manage-web</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<excludes>
<exclude>*.properties</exclude>
</excludes>
</resource>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>application.properties</include>
<include>application-${profile.env}.properties</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<classesDirectory>target/classes/</classesDirectory>
<archive>
<!--生成的jar包不包含maven描述相关文件-->
<addMavenDescriptor>false</addMavenDescriptor>
<manifest>
<!--项目启动类-->
<mainClass>com.wk.manage.web.WebApplication</mainClass>
<useUniqueVersions>false</useUniqueVersions>
<!--第三方JAR加入类构建的路径maven-dependency-plugin-->
<addClasspath>true</addClasspath>
<!--外部依赖jar包的位置-->
<classpathPrefix>lib/</classpathPrefix>
</manifest>
<manifestEntries>
<Class-Path>.</Class-Path>
</manifestEntries>
</archive>
</configuration>
</plugin>
<!--关键插件,maven提供的assembly插件,需要放在最后-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>make-tar.gz</id>
<!--绑定的maven操作-->
<phase>package</phase>
<!--运行一次-->
<goals>
<goal>single</goal>
</goals>
<configuration>
<!--如果不想在打包的后缀加上assembly.xml中设置的id,可以加上下面的配置-->
<!--<appendAssemblyId>false</appendAssemblyId>-->
<!--指定assembly插件对应的assembly.xml配置文件-->
<descriptors>
<descriptor>src/main/resources/assembly/assembly.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
assembly.xml配置
然后我们需要在pom文件中指定的assembly插件对应的assembly.xml配置文件进行配置:
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
<!--必填,会追加到打包文件名称的末尾-->
<id>1.0</id>
<!--打包类型,可以设置多种类型,打包的时候不同的类型都会打包打出来-->
<formats>
<format>tar.gz</format>
<!--<format>zip</format>-->
</formats>
<!--第三方依赖设置-->
<dependencySets>
<dependencySet>
<!--使用项目中的artifact,第三方包打包进tar.gz文件的lib目录下-->
<useProjectArtifact>true</useProjectArtifact>
<outputDirectory>lib</outputDirectory>
</dependencySet>
</dependencySets>
<!--文件相关设置-->
<fileSets>
<!--src/main/assembly/bin文件下的所有脚本文件输出到打包后的bin目录下-->
<fileSet>
<directory>src/main/resources/assembly/bin</directory>
<outputDirectory>bin</outputDirectory>
<!--
权限设置:
0755->即用户具有读/写/执行权限,组用户和其它用户具有读写权限;
0644->即用户具有读写权限,组用户和其它用户具有只读权限;
-->
<fileMode>0755</fileMode>
<lineEnding>unix</lineEnding>
<filtered>true</filtered>
</fileSet>
<!-- src/main/resources/config目录下配置文件打包到config目录下 -->
<fileSet>
<directory>src/main/resources</directory>
<includes>
<include>application.properties</include>
<include>application-${profile.env}.properties</include>
</includes>
<filtered>true</filtered>
<outputDirectory>${file.separator}config</outputDirectory>
</fileSet>
<!-- 将target目录下的启动jar打包到目录下-->
<fileSet>
<directory>target</directory>
<outputDirectory>/</outputDirectory>
<includes>
<include>*.jar</include>
</includes>
</fileSet>
</fileSets>
</assembly>
服务脚本配置
接下来配置下启动、关闭、重启以及查询状态的脚本,由assembly.xml可以看出放置的位置为src/main/resources/assembly/bin(可自定义):
#!/bin/sh
## service name(TODO-需要替换为自己服务名称)
APP_NAME=manage-web
## 启动等待最长时间
MAX_START_WAIT_SEC=60
## 当前等待时间
WAIT_SEC=1
## 服务所在路径(TODO-需要替换为自己的路径)
SERVICE_DIR=/Users/wukong/Desktop/tool/$APP_NAME
APP_DIR=$HOME
JAVA_JDK=jdk1.8.0_144
SERVICE_NAME=$APP_NAME
JAR_NAME=$SERVICE_NAME.jar
PID=$SERVICE_NAME.pid
PID_BAK=$PID.bak
## heap dump路径(TODO-需要替换为自己的路径)
HEAP_DUMP_PATH=/Users/wukong/Desktop/tool/logs/$APP_NAME/
cd $SERVICE_DIR
#使用说明,用来提示输入参数
usage() {
echo "Usage: sh 脚本名.sh [start|stop|restart|status]"
exit 1
}
#启动方法
start(){
nohup java -Djava.security.egd=file:/dev/./urandom -server -Xms1024m -Xmx1024m -Xmn512m -Xss256k -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=256m -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -XX:CMSFullGCsBeforeCompaction=5 -XX:+UseCMSCompactAtFullCollection -Xloggc:gc.log -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=$HEAP_DUMP_PATH -jar $JAR_NAME >/dev/null 2>&1 &
echo $! > $SERVICE_DIR/$PID
echo "================================================== start $SERVICE_NAME begin... please wait $MAX_START_WAIT_SEC sec"
while((WAIT_SEC < MAX_START_WAIT_SEC))
do
P_ID=`ps -ef | grep -w "$JAR_NAME" | grep -w "java" | grep -v "grep" | awk '{print $2}'`
P_ID_COUNT=`ps -ef | grep -w "$JAR_NAME" | grep -w "java" | grep -v "grep" | wc -l`
if [ $P_ID_COUNT = 0 ];then
echo "================================================== start $SERVICE_NAME begin... wait time :$WAIT_SEC / $MAX_START_WAIT_SEC | P_ID_COUNT=$P_ID_COUNT"
sleep 1
else
echo "================================================== start $SERVICE_NAME succeeded. pid=$P_ID, costTime:$WAIT_SEC"
let "WAIT_SEC = MAX_START_WAIT_SEC"
fi
let "WAIT_SEC += 1"
done
}
#停止方法
stop(){
is_exist
if [ $? -eq "0" ]; then
echo "=== stop $SERVICE_NAME begin... please wait $MAX_START_WAIT_SEC sec"
kill -15 `cat $SERVICE_DIR/$PID`
mv $SERVICE_DIR/$PID $SERVICE_DIR/$PID_BAK
rm -rf $SERVICE_DIR/$PID
while((WAIT_SEC < MAX_START_WAIT_SEC))
do
P_ID=`ps -ef | grep -w "$JAR_NAME" | grep -w "java" | grep -v "grep" | awk '{print $2}'`
P_ID_COUNT=`ps -ef | grep -w "$JAR_NAME" | grep -w "java" | grep -v "grep" | wc -l`
if [ $P_ID_COUNT != 0 ]; then
echo "=== stop $SERVICE_NAME begin by (kill -15)... wait time :$WAIT_SEC / $MAX_START_WAIT_SEC | P_ID_COUNT=$P_ID_COUNT"
sleep 1
else
echo "=== stop $SERVICE_NAME succeeded by (kill -15). costTime:$WAIT_SEC"
let "WAIT_SEC = MAX_START_WAIT_SEC"
fi
let "WAIT_SEC += 1"
done
P_ID=`ps -ef | grep -w "$JAR_NAME" | grep -w "java" | grep -v "grep" | awk '{print $2}'`
P_ID_COUNT=`ps -ef | grep -w "$JAR_NAME" | grep -w "java" | grep -v "grep" | wc -l`
if [ $P_ID_COUNT != 0 ];then
echo "=== stop $SERVICE_NAME begin by (kill -15) failed. begin kill -9 $SERVICE_NAME process, pid is:$P_ID"
kill -9 $P_ID
echo "${APP_NAME} is not running"
fi
else
echo "${APP_NAME} is not running"
fi
}
#检查程序是否在运行
is_exist(){
pid=`ps -ef | grep -w "$JAR_NAME" | grep -w "java" | grep -v "grep" | awk '{print $2}'`
#如果不存在返回1,存在返回0
if [ -z "${pid}" ]; then
return 1
else
return 0
fi
}
#输出运行状态
status(){
is_exist
if [ $? -eq "0" ]; then
echo "${APP_NAME} is running. Pid is ${pid}"
else
echo "${APP_NAME} is NOT running."
fi
}
#重启
restart(){
stop
start
}
#根据输入参数,选择执行对应方法,不输入则执行使用说明
case "$1" in
"start")
start
;;
"stop")
stop
;;
"status")
status
;;
"restart")
restart
;;
*)
usage
;;
esac
项目打包
以上配置好以后,在idea中执行clean package对项目进行打包。打包名称为manage-web-1.0.tar.gz(1.0为assembly.xml中设置的id)。我们对包进行解压看下里面的目录结构。
我们可以看到和assembly.xml配置的结构是一致的。我们启动项目只要执行bin目录下的脚本即可。如果想覆盖图中manage-web.jar中的application.properties相关配置,可以在config中的配置进行设置。