assembly(装配/组装)
对于SpringBoot项目通常我们会使用mavaen提供的普通的打包方式打成一个jar包, 这对于在本地运行似乎没有什么问题, 但是把这种方式在Linux上运行却会出现很多问题,导致无法运行, 而且打包的结构也并不清晰,所以我们需要一个插件来完成打包的工作, 把你的项目打包成一个包含脚本、配置文件、运行时所有依赖的部署包
“assembly”就是把一组文件、目录、依赖元素组装成一个归档文件的插件
官方配置详解:http://maven.apache.org/plugins/maven-assembly-plugin/assembly.html
这里使用SpringBoot + Dubbo 的Server项目进行演示
一. 原始项目是一个最简单的SpringBoot +Dubbo 生产者端的小示例,只发布了一个helloWord服务, 在此基础上拷贝assebly的几个文件到main目录
assembly.jpg
- bin 目录放打包后项目的启动/停止脚本 , 这几个脚本可以到dubbo-2.5.7.jar-->MATA-INF-->assembly.bin
下去拷,然后根据需要修改一下 主方法类 和配置文件名称 等
- assembly.xml 是maven-assembly-plugin插件对应的配置文件
二, 在maven中添加assembly插件
<build>
<!--我们自己的文件会打成一个demo-server.jar包,此包中不需要配置文件-->
<resources>
<resource>
<directory>src/main/resources</directory>
<excludes>
<exclude>**/*.xml</exclude>
<exclude>**/*.properties</exclude>
</excludes>
</resource>
</resources>
<plugins>
<!--assebly插件-->
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.5.5</version>
<configuration>
<finalName>${project.artifactId}</finalName>
<skipAssembly>false</skipAssembly>
<appendAssemblyId>false</appendAssemblyId>
<!--如果路径长度超过100字符,执行的操作warn" (default), "fail", "truncate", "gnu", or "omit". -->
<tarLongFileMode>gnu</tarLongFileMode>
<outputDirectory>target</outputDirectory>
<!--具体配置文件所在路径-->
<descriptors>
<descriptor>src/main/assembly/assembly.xml</descriptor>
</descriptors>
</configuration>
<!--执行的操作-->
<executions>
<execution>
<id>assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<!--profile设置 , 这个跟Assebly打包没关系,根据需要配置 -->
<profiles>
<profile>
<id>dev</id>
<properties>
<dubbo.application.name>demo-server-dev</dubbo.application.name>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>test</id>
<properties>
<dubbo.application.name>demo-server-test</dubbo.application.name>
</properties>
</profile>
</profiles>
PS:在使用Assembly打包的时候必须要springboot把默认的打包插件删除掉,否则会报找不到启动类
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
二,配置assembly.xml定制打包过程
<?xml version="1.0" encoding="UTF-8"?>
<assembly>
<id>prd</id>
<baseDirectory>${project.artifactId}</baseDirectory>
<includeBaseDirectory>true</includeBaseDirectory>
<formats>
<format>tar.gz</format><!--打包的文件格式:tar.zip war zip等-->
</formats>
<fileSets>
<!-- 将src/main/resources下配置问价打包到conf目录 -->
<fileSet>
<directory>src/main/resources</directory>
<outputDirectory>/conf</outputDirectory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
<filtered>true</filtered><!-- 是否进行属性替换 -->
</fileSet>
<!-- 打包.sh文件到bin 目录 -->
<fileSet>
<directory>src/main/assembly/bin</directory>
<outputDirectory>/bin</outputDirectory>
<includes>
<include>*.*</include>
</includes>
<fileMode>0755</fileMode><!--赋予文件权限-->
</fileSet>
</fileSets>
<!--依赖输出-->
<dependencySets>
<dependencySet>
<unpack>false</unpack><!--不解压-->
<outputDirectory>lib</outputDirectory><!--依赖包输出路径-->
<useProjectArtifact>true</useProjectArtifact><!--当前项目构件是否包含在这个依赖集合里。-->
<scope>runtime</scope><!-- 将scope为runtime的依赖包打包到lib目录下。 -->
</dependencySet>
</dependencySets>
</assembly>
三,根据需要配置startup.sh/stop.sh等便捷启动/停止项目的脚本,这里给出一个示例:
1.startup.sh
#!/bin/bash
cd `dirname $0`
BIN_DIR=`pwd`
cd ..
DEPLOY_DIR=`pwd`
CONF_DIR=$DEPLOY_DIR/conf
MAIN_CLASS=cn.wolfcode.DemoServerApplication
SERVER_NAME=`sed '/spring.dubbo.application.name/!d;s/.*=//' conf/application.properties | tr -d '\r'`
SERVER_PROTOCOL=`sed '/spring.dubbo.protocol.name/!d;s/.*=//' conf/application.properties | tr -d '\r'`
SERVER_PORT=`sed '/spring.dubbo.protocol.port/!d;s/.*=//' conf/application.properties | tr -d '\r'`
LOGS_FILE=`sed '/dubbo.log4j.file/!d;s/.*=//' conf/application.properties | tr -d '\r'`
if [ -z "$SERVER_NAME" ]; then
SERVER_NAME=`hostname`
fi
PIDS=`ps -ef | grep java | grep -v grep | grep "$CONF_DIR" |awk '{print $2}'`
if [ -n "$PIDS" ]; then
echo "ERROR: The $SERVER_NAME already started!"
echo "PID: $PIDS"
exit 1
fi
if [ -n "$SERVER_PORT" ]; then
SERVER_PORT_COUNT=`netstat -tln | grep $SERVER_PORT | wc -l`
if [ $SERVER_PORT_COUNT -gt 0 ]; then
echo "ERROR: The $SERVER_NAME port $SERVER_PORT already used!"
exit 1
fi
fi
LOGS_DIR=""
if [ -n "$LOGS_FILE" ]; then
LOGS_DIR=`dirname $LOGS_FILE`
else
LOGS_DIR=$DEPLOY_DIR/logs
fi
if [ ! -d $LOGS_DIR ]; then
mkdir $LOGS_DIR
fi
STDOUT_FILE=$LOGS_DIR/stdout.log
LIB_DIR=$DEPLOY_DIR/lib
LIB_JARS=`ls $LIB_DIR|grep .jar|awk '{print "'$LIB_DIR'/"$0}'|tr "\n" ":"`
JAVA_OPTS=" -Djava.awt.headless=true -Djava.net.preferIPv4Stack=true "
JAVA_DEBUG_OPTS=""
if [ "$1" = "debug" ]; then
JAVA_DEBUG_OPTS=" -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n "
fi
JAVA_JMX_OPTS=""
if [ "$1" = "jmx" ]; then
JAVA_JMX_OPTS=" -Dcom.sun.management.jmxremote.port=1099 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false "
fi
JAVA_MEM_OPTS=""
BITS=`java -version 2>&1 | grep -i 64-bit`
if [ -n "$BITS" ]; then
JAVA_MEM_OPTS=" -server -Xmx2g -Xms2g -Xmn256m -XX:PermSize=128m -Xss256k -XX:+DisableExplicitGC -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:LargePageSizeInBytes=128m -XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=70 "
else
JAVA_MEM_OPTS=" -server -Xms1g -Xmx1g -XX:PermSize=128m -XX:SurvivorRatio=2 -XX:+UseParallelGC "
fi
echo -e "Starting the $SERVER_NAME ...\c"
nohup java $JAVA_OPTS $JAVA_MEM_OPTS $JAVA_DEBUG_OPTS $JAVA_JMX_OPTS -classpath $CONF_DIR:$LIB_JARS $MAIN_CLASS > $STDOUT_FILE 2>&1 &
echo "OK!"
PIDS=`ps -f | grep java | grep -v grep | grep "$DEPLOY_DIR" | awk '{print $2}'`
echo "PID: $PIDS"
echo "STDOUT: $STDOUT_FILE"
stop.sh
#!/bin/bash
cd `dirname $0`
BIN_DIR=`pwd`
cd ..
DEPLOY_DIR=`pwd`
CONF_DIR=$DEPLOY_DIR/conf
SERVER_NAME=`sed '/spring.dubbo.application.name/!d;s/.*=//' conf/application.properties | tr -d '\r'`
if [ -z "$SERVER_NAME" ]; then
SERVER_NAME=`hostname`
fi
PIDS=`ps -ef | grep java | grep -v grep | grep "$CONF_DIR" |awk '{print $2}'`
if [ -z "$PIDS" ]; then
echo "ERROR: The $SERVER_NAME does not started!"
exit 1
fi
if [ "$1" != "skip" ]; then
$BIN_DIR/dump.sh
fi
echo -e "Stopping the $SERVER_NAME ...\c"
for PID in $PIDS ; do
kill $PID > /dev/null 2>&1
done
COUNT=0
while [ $COUNT -lt 1 ]; do
echo -e ".\c"
sleep 1
COUNT=1
for PID in $PIDS ; do
PID_EXIST=`ps -f -p $PID | grep java`
if [ -n "$PID_EXIST" ]; then
COUNT=0
break
fi
done
done
echo "OK!"
echo "PID: $PIDS"
四,配置完毕,执行package
到Target目录查看是否生成xxx.tar.gz
生成的xxx.tar.gz包结构:
|
|-bin
|-conf
|-lib
五,部署
拷贝xxx.tar.gz到linux
tar -zxvf xxx.tar.gz
cd xxx/bin
./start.sh
tail -f -n 100 ../logs/stout.log 查看日志是否启动成功
网友评论