使用同一个jetty启动多个不同的服务

在部署Java Web工程时,往往会在同一台服务器上同时部署多个不同的服务,如果每个服务都拷贝一份Jetty,会显得比较麻烦和冗余,如果将多个工程都放到同一个Jetty中,那么最多只有一个工程能有root context,其余的工程都得加个子context去访问,显得不够友好。通过一些sh脚本,可以实现使用一份Jetty来启动多个不同的服务。

创建一个工程目录,例如oms,在这其中新建一个bin目录,把相关shell脚本放在这里面。新建一个env.sh,内容如下:

#!/usr/bin/env bash

if [ -z "$APP_NAME" ] ; then
  export APP_NAME=oms
  cd ..
  export NODE_PATH=$(pwd)
  export app_conf=$NODE_PATH/conf
  cd -
fi

export JETTY_RUN=$NODE_PATH/bin
export JETTY_PID=$NODE_PATH/.jetty.pid
export JETTY_ARGS=jetty.port=8080
export JETTY_LOGS=$NODE_PATH/logs


JAVA_MEM_OPTS=" -server -XX:+UseParNewGC -XX:+DisableExplicitGC -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:-CMSParallelRemarkEnabled -XX:CMSInitiatingOccupancyFraction=70 -XX:Sof
tRefLRUPolicyMSPerMB=0 -XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly -XX:-HeapDumpOnOutOfMemoryError "

JAVA_OPTS_EXT=" -Djava.awt.headless=true -Djava.net.preferIPv4Stack=true -Dapplication.codeset=UTF-8 -Dfile.encoding=UTF-8  "

JAVA_DEBUG=" -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8088 "


export JAVA_OPTIONS="$JAVA_MEM_OPTS $JAVA_OPTS_EXT "
#export JAVA_OPTIONS="$JAVA_OPTIONS $JAVA_DEBUG "

其中,APP_NAME 为该服务war包的名称。jetty.port为jetty服务要启动的端口,其他的为一些常规的java参数设置

再在该目录下新建一个shell脚本jetty.sh,内容如下:

#!/usr/bin/env bash

DIR=`dirname $0`
source $DIR/env.sh

if [ -z "$JETTY_HOME" ] ; then
    echo "Please set JETTY_HOME"
    exit
fi

if [ ! -e ../conf/webapps ] ; then
    mkdir -p ../conf/webapps
fi

if [ ! -e ../logs ] ; then
    mkdir -p ../logs
fi

if [ ! -e ../conf/webapps/$APP_NAME.xml ] ; then
    conf=../conf/webapps/$APP_NAME.xml
    echo '<?xml version="1.0"  encoding="ISO-8859-1"?>' >> $conf
    echo '<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">' >> $conf
    echo '<Configure class="org.eclipse.jetty.webapp.WebAppContext">' >> $conf
    echo '  <Set name="contextPath">/</Set>' >> $conf
    echo '  <Set name="war">'"$NODE_PATH/war/$APP_NAME.war</Set>" >> $conf
    echo '  <Set name="tempDirectory">'"$NODE_PATH/war/${APP_NAME}_exploded</Set>" >> $conf
    echo '  <Set name="extractWAR">true</Set>' >> $conf
    echo '  <Set name="copyWebDir">false</Set>' >> $conf
    echo '  <Set name="defaultsDescriptor"><SystemProperty name="jetty.home" default="."/>/etc/webdefault.xml</Set>'  >> $conf
    echo '</Configure>' >> $conf
fi

rm -rf $JETTY_HOME/webapps

ln  -s $NODE_PATH/conf/webapps $JETTY_HOME/webapps

$JETTY_HOME/bin/jetty.sh $1

设置好JETTY_HOME,然后执行jetty.sh start,便可以自动创建相关需要的xml,并启动jetty。这里假设war包放在工程目录的war目录下,并且名字为APP_NAME.war。

由于jetty自己的启动脚本中将JAVA_OPTIONS变成了数组,数组变量在shell脚本之间是不能传递的,而jetty restart调用了自身shell来进行重启操作,因此在我们自己写的env.sh中设置的JAVA_OPTIONS在jetty restart时就失效了,参数不能传递过去。为了解决该问题,需要修改jetty自己的启动脚本jetty.sh,vim $JETTY_HOME/bin/jetty.sh,在最上方加上这段代码:

if [ -f $NODE_PATH/bin/env.sh ];then
    source $NODE_PATH/bin/env.sh
fi

在shell脚本里面重新加载env.sh