- 博客分类:
- JAVA
Java 工程在生产环境运行时,一般需要构建成一个jar,同时在运行时需要把依赖的jar添加到classpath中去,如果直接运行添加classpath很不方便,比较方便的是创建一个shell脚本。在公司项目中看到把工程代码和依赖jar包合并到一块,省去设置classpath的麻烦。但这样把项目jar依赖绑定死,被其它项目引入,容易造成jar依赖冲突,如果用maven管理java项目,导致提交到公司仓库jar过于庞大,同时也失去maven对jar依赖管理的作用。
为了方便java项目部署运行,这里为构建部署包定义一个固定格式:
/java 项目
/lib --存放所有依赖jar
/conf --存放配置文件,例如:log4j, spring, properties等配置文件,不放入jar是为
了方便修改这些配置文件
/logs --运行时自动创建的目录,存放日志文件
/bin --存放运行脚本: server.sh 启动和停止项目运行。
如果在构建部署包时,需要我们手动去创建这样的目录,把文件拷贝相应目录,实在是太繁琐了,幸好maven为我们这样“懒惰”coder提供了一个很好的plugin:maven-assembly-plugin,可以去定制这样的部署结构
1:配置maven-assembly-plugin
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-assembly-plugin</artifactId>
- <configuration>
- <descriptors>
- <descriptor>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>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptors>
<descriptor>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>
2:assembly 配置打包格式
定义在assembly.xml文件中,文件中配置信息不作过多解释,可以参考相应文档
- <assembly
- xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
- <id>bin</id>
- <formats>
- <format>tar.gz</format>
- </formats>
- <dependencySets>
- <dependencySet>
- <useProjectArtifact>true</useProjectArtifact>
- <outputDirectory>lib</outputDirectory>
- <scope>runtime</scope>
- </dependencySet>
- </dependencySets>
- <fileSets>
- <fileSet>
- <outputDirectory>/</outputDirectory>
- <includes>
- <include>README.txt</include>
- </includes>
- </fileSet>
- <fileSet>
- <directory>src/main/scripts</directory>
- <outputDirectory>/bin</outputDirectory>
- <lineEnding>unix</lineEnding>
- <fileMode>0755</fileMode>
- <includes>
- <include>*.sh</include>
- </includes>
- </fileSet>
- <fileSet>
- <directory>target/classes</directory>
- <outputDirectory>/conf</outputDirectory>
- <includes>
- <include>*.xml</include>
- </includes>
- </fileSet>
- </fileSets>
- </assembly>
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<id>bin</id>
<formats>
<format>tar.gz</format>
</formats>
<dependencySets>
<dependencySet>
<useProjectArtifact>true</useProjectArtifact>
<outputDirectory>lib</outputDirectory>
<scope>runtime</scope>
</dependencySet>
</dependencySets>
<fileSets>
<fileSet>
<outputDirectory>/</outputDirectory>
<includes>
<include>README.txt</include>
</includes>
</fileSet>
<fileSet>
<directory>src/main/scripts</directory>
<outputDirectory>/bin</outputDirectory>
<lineEnding>unix</lineEnding>
<fileMode>0755</fileMode>
<includes>
<include>*.sh</include>
</includes>
</fileSet>
<fileSet>
<directory>target/classes</directory>
<outputDirectory>/conf</outputDirectory>
<includes>
<include>*.xml</include>
</includes>
</fileSet>
</fileSets>
</assembly>
下面这段配置主要从src/main/scripts目录获取shell脚本复制到bin目录。同时设置文件模式为unix,文件具有可执行权限。
- <directory>src/main/scripts</directory>
- <outputDirectory>/bin</outputDirectory>
- <lineEnding>unix</lineEnding>
- <fileMode>0755</fileMode>
- <includes>
- <include>*.sh</include>
- </includes>
<directory>src/main/scripts</directory>
<outputDirectory>/bin</outputDirectory>
<lineEnding>unix</lineEnding>
<fileMode>0755</fileMode>
<includes>
<include>*.sh</include>
</includes>
3:启动类设计
在学习metamorphosis的时候,对它的启动脚本做了一些了解,发现服务stop方式设计比较优雅,通过JMX连接JVM,去关闭系统内部资源,再kill掉进程。
UeapServerMBean定义stop方法,实现类UeapServer完成系统启动加载和停止功能。ServerStartup是main方法入口,调用 UeapServer启动方式,并注册 UeapServer到JMX中。
4:启动脚本
系统启动脚本分为了两个文件:
env.sh 配置一些环境变量和JVM参数,实际应用中只需要修改 SERVER_NAME、 STARTUP_CLASS和 UEAP_JVM_ARGS变量名称。
server.sh 实际运行脚本,提供启动、停止、运行状态查询、重启功能,实际应用中不需要改动该文件。
env.sh
- #!/bin/bash
- #Config your java home
- #JAVA_HOME=/opt/jdk/
- if [ -z "$JAVA_HOME" ]; then
- export JAVA=`which java`
- else
- export JAVA="$JAVA_HOME/bin/java"
- fi
- UEAP_HOME=$BASE_DIR
- SERVER_NAME="collect master"
- STARTUP_CLASS="com.starit.ueap.collect.master.ServerStartup"
- #Ueap JMX port
- export JMX_PORT=9123
- export CLASSPATH=$BASE_DIR/conf:$(ls $BASE_DIR/lib/*.jar | tr '\n' :)
- #UEAP jvm args
- UEAP_JVM_ARGS="-Xmx512m -Xms256m -server"
- UEAP_JVM_ARGS="$UEAP_JVM_ARGS -cp $CLASSPATH -Dueap.home=$ueap_home -Dcollect.start.worker=false"
- if [ -z "$UEAP_ARGS" ]; then
- export UEAP_ARGS="$UEAP_JVM_ARGS"
- fi
#!/bin/bash
#Config your java home
#JAVA_HOME=/opt/jdk/
if [ -z "$JAVA_HOME" ]; then
export JAVA=`which java`
else
export JAVA="$JAVA_HOME/bin/java"
fi
UEAP_HOME=$BASE_DIR
SERVER_NAME="collect master"
STARTUP_CLASS="com.starit.ueap.collect.master.ServerStartup"
#Ueap JMX port
export JMX_PORT=9123
export CLASSPATH=$BASE_DIR/conf:$(ls $BASE_DIR/lib/*.jar | tr '\n' :)
#UEAP jvm args
UEAP_JVM_ARGS="-Xmx512m -Xms256m -server"
UEAP_JVM_ARGS="$UEAP_JVM_ARGS -cp $CLASSPATH -Dueap.home=$ueap_home -Dcollect.start.worker=false"
if [ -z "$UEAP_ARGS" ]; then
export UEAP_ARGS="$UEAP_JVM_ARGS"
fi
server.sh
- #!/bin/bash
- if [ -z "$BASE_DIR" ] ; then
- PRG="$0"
- # need this for relative symlinks
- while [ -h "$PRG" ] ; do
- ls=`ls -ld "$PRG"`
- link=`expr "$ls" : '.*-> \(.*\)$'`
- if expr "$link" : '/.*' > /dev/null; then
- PRG="$link"
- else
- PRG="`dirname "$PRG"`/$link"
- fi
- done
- BASE_DIR=`dirname "$PRG"`/..
- # make it fully qualified
- BASE_DIR=`cd "$BASE_DIR" && pwd`
- #echo "collect master is at $BASE_DIR"
- fi
- source $BASE_DIR/bin/env.sh
- AS_USER=`whoami`
- LOG_DIR="$BASE_DIR/logs"
- LOG_FILE="$LOG_DIR/server.log"
- PID_DIR="$BASE_DIR/logs"
- PID_FILE="$PID_DIR/.run.pid"
- function running(){
- if [ -f "$PID_FILE" ]; then
- pid=$(cat "$PID_FILE")
- process=`ps aux | grep " $pid " | grep -v grep`;
- if [ "$process" == "" ]; then
- return 1;
- else
- return 0;
- fi
- else
- return 1
- fi
- }
- function start_server() {
- if running; then
- echo "$SERVER_NAME is running."
- exit 1
- fi
- mkdir -p $PID_DIR
- touch $LOG_FILE
- mkdir -p $LOG_DIR
- chown -R $AS_USER $PID_DIR
- chown -R $AS_USER $LOG_DIR
- echo "$JAVA $UEAP_JVM_ARGS -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false \
- -Dcom.sun.management.jmxremote.port=$JMX_PORT $STARTUP_CLASS"
- sleep 1
- nohup $JAVA $UEAP_JVM_ARGS -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false \
- -Dcom.sun.management.jmxremote.port=$JMX_PORT $STARTUP_CLASS 2>&1 >>$LOG_FILE &
- echo $! > $PID_FILE
- chmod 755 $PID_FILE
- sleep 1;
- tail -F $LOG_FILE
- }
- function stop_server() {
- if ! running; then
- echo "$SERVER_NAME is not running."
- exit 1
- fi
- count=0
- pid=$(cat $PID_FILE)
- while running;
- do
- let count=$count+1
- echo "Stopping $SERVER_NAME $count times"
- if [ $count -gt 5 ]; then
- echo "kill -9 $pid"
- kill -9 $pid
- else
- $JAVA $TOOLS_ARGS com.starit.ueap.common.shell.StopServerTool -host 127.0.0.1 -port $JMX_PORT $@
- kill $pid
- fi
- sleep 3;
- done
- echo "Stop $SERVER_NAME successfully."
- rm $PID_FILE
- }
- function status(){
- if running; then
- echo "$SERVER_NAME is running."
- else
- echo "$SERVER_NAME was stopped."
- fi
- }
- function help() {
- echo "Usage: server.sh {start|status|stop|restart|reload}" >&2
- echo " start: start the $SERVER_NAME server"
- echo " stop: stop the $SERVER_NAME server"
- echo " restart: restart the $SERVER_NAME server"
- echo " status: get $SERVER_NAME current status,running or stopped."
- }
- command=$1
- shift 1
- case $command in
- start)
- start_server $@;
- ;;
- stop)
- stop_server $@;
- ;;
- status)
- status $@;
- ;;
- restart)
- $0 stop $@
- $0 start $@
- ;;
- help)
- help;
- ;;
- *)
- help;
- exit 1;
- ;;
- esac
#!/bin/bash
if [ -z "$BASE_DIR" ] ; then
PRG="$0"
# need this for relative symlinks
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG="`dirname "$PRG"`/$link"
fi
done
BASE_DIR=`dirname "$PRG"`/..
# make it fully qualified
BASE_DIR=`cd "$BASE_DIR" && pwd`
#echo "collect master is at $BASE_DIR"
fi
source $BASE_DIR/bin/env.sh
AS_USER=`whoami`
LOG_DIR="$BASE_DIR/logs"
LOG_FILE="$LOG_DIR/server.log"
PID_DIR="$BASE_DIR/logs"
PID_FILE="$PID_DIR/.run.pid"
function running(){
if [ -f "$PID_FILE" ]; then
pid=$(cat "$PID_FILE")
process=`ps aux | grep " $pid " | grep -v grep`;
if [ "$process" == "" ]; then
return 1;
else
return 0;
fi
else
return 1
fi
}
function start_server() {
if running; then
echo "$SERVER_NAME is running."
exit 1
fi
mkdir -p $PID_DIR
touch $LOG_FILE
mkdir -p $LOG_DIR
chown -R $AS_USER $PID_DIR
chown -R $AS_USER $LOG_DIR
echo "$JAVA $UEAP_JVM_ARGS -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false \
-Dcom.sun.management.jmxremote.port=$JMX_PORT $STARTUP_CLASS"
sleep 1
nohup $JAVA $UEAP_JVM_ARGS -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false \
-Dcom.sun.management.jmxremote.port=$JMX_PORT $STARTUP_CLASS 2>&1 >>$LOG_FILE &
echo $! > $PID_FILE
chmod 755 $PID_FILE
sleep 1;
tail -F $LOG_FILE
}
function stop_server() {
if ! running; then
echo "$SERVER_NAME is not running."
exit 1
fi
count=0
pid=$(cat $PID_FILE)
while running;
do
let count=$count+1
echo "Stopping $SERVER_NAME $count times"
if [ $count -gt 5 ]; then
echo "kill -9 $pid"
kill -9 $pid
else
$JAVA $TOOLS_ARGS com.starit.ueap.common.shell.StopServerTool -host 127.0.0.1 -port $JMX_PORT $@
kill $pid
fi
sleep 3;
done
echo "Stop $SERVER_NAME successfully."
rm $PID_FILE
}
function status(){
if running; then
echo "$SERVER_NAME is running."
else
echo "$SERVER_NAME was stopped."
fi
}
function help() {
echo "Usage: server.sh {start|status|stop|restart|reload}" >&2
echo " start: start the $SERVER_NAME server"
echo " stop: stop the $SERVER_NAME server"
echo " restart: restart the $SERVER_NAME server"
echo " status: get $SERVER_NAME current status,running or stopped."
}
command=$1
shift 1
case $command in
start)
start_server $@;
;;
stop)
stop_server $@;
;;
status)
status $@;
;;
restart)
$0 stop $@
$0 start $@
;;
help)
help;
;;
*)
help;
exit 1;
;;
esac
4:执行mvn install或者mvn package 可以再target生成tar.gz后缀文件。提交到linux系统,解压缩即可运行。(不考虑window环境)