启动脚本
#!/bin/bash
cd `dirname $0`
BIN_DIR=`pwd`
cd ..
DEPLOY_DIR=`pwd`
CONF_DIR=$DEPLOY_DIR/conf
# =======================================================================================
# 检测操作系统类型
# =======================================================================================
OS=`uname -s | tr [:upper:] [:lower:] | tr -d [:blank:]`
case "$OS" in
'sunos')
# OS="solaris"
;;
'hp-ux' | 'hp-ux64') # 未经过验证
# OS="linux"
;;
'darwin') # Mac OSX
OS="unix"
;;
'unix_sv')
OS="unix"
;;
esac
# 该脚本目前只支持linux、Mac OSX
if [ "$OS" != "linux" ] && [ "$OS" != "unix" ]; then
echo "Unsupported OS: $OS"
exit 1
fi
# =======================================================================================
# 检测服务是否已经启动,或者端口号是否已经被占用
# Mac OSX支持: ps -e -o 'pid=,command=',但linux必须写成: ps -e -o 'pid=' -o 'command='
# =======================================================================================
PIDS=`ps -e -o 'pid=' -o 'command='|grep java|grep "$CONF_DIR"|awk '{print $1}'`
if [ -n "$PIDS" ]; then
# 服务已经启动
echo "ERROR: The $SERVER_NAME already started!"
echo "PID: $PIDS"
exit 1
fi
if [ -n "$SERVER_PORT" ]; then
# 端口号是否被占用
# netstat的输出格式:
# linux:10.9.10.178:10050
# Mac OSX: 192.168.169.5.56508
if [ "$OS" == "unix" ]; then
SERVER_PORT_COUNT=`netstat -ant -p tcp|tail -n +3|awk '{print $4}'|grep '[.:]$SERVER_PORT' -c`
else
SERVER_PORT_COUNT=`netstat -ant|tail -n +3|awk '{print $4}'|grep '[.:]$SERVER_PORT' -c`
fi
if [ $SERVER_PORT_COUNT -gt 0 ]; then
echo "ERROR: The $SERVER_NAME port $SERVER_PORT already used!"
exit 1
fi
fi
# =======================================================================================
# 启动服务
# =======================================================================================
# dubbo服务配置参数
#从dubbo.properties 中获得server_name
SERVER_NAME=`sed '/^#/d;/dubbo.application.name/!d;s/.*=//' conf/dubbo.properties | tr -d '\r'`
if [ -z "$SERVER_NAME" ]; then
SERVER_NAME=`hostname`
fi
#从dubbo.properties 中获得SERVER_PORT
SERVER_PORT=`sed '/^#/d;/prop.dubbo.protocol.port/!d;s/.*=//' conf/dubbo.properties | tr -d '\r'`
#从dubbo.properties 中获得SERVER_HOST
SERVER_HOST=`sed '/^#/d;/dubbo.protocol.host/!d;s/.*=//' conf/dubbo.properties | tr -d '\r'`
if [ -z "$SERVER_HOST" ]; then
SERVER_HOST=127.0.0.1
fi
# 日志:log4j.xml文件路径、日志路径、stdout日志文件名
LOG4J_XML=`sed '/^#/d;/prop.log.log4j-xml/!d;s/.*=//' conf/dubbo.properties | tr -d '\r'`
LOG_DIR=`sed '/^#/d;/prop.log.dir/!d;s/.*=//' conf/dubbo.properties | tr -d '\r'`
if [ -n "$LOG_DIR" ]; then
LOG_DIR=`dirname $LOG_DIR/stdout.log`
else
LOG_DIR=$DEPLOY_DIR/logs
fi
if [ ! -d $LOG_DIR ]; then
# 日志目录不存在,创建这个目录
mkdir -p $LOG_DIR
fi
# 获得日志输出文件
LOG_STDOUT=`sed '/^#/d;/prop.log.stdout-file/!d;s/.*=//' conf/dubbo.properties | tr -d '\r'`
if [ -z "$LOG_STDOUT" ]; then
LOG_STDOUT=$LOG_DIR/stdout.log
else
LOG_STDOUT=$LOG_DIR/$LOG_STDOUT
fi
# classpath设置
LIB_DIR=$DEPLOY_DIR/lib
LIB_JARS=`ls $LIB_DIR|grep .jar|awk '{print "'$LIB_DIR'/"$0}'|tr "\n" ":"`
#加载外部配置文件和jar包 linux 用:隔开 windows 使用;隔开
CLASS_PATH=$CONF_DIR:$LIB_JARS
# JAVA_OPTS=" -Djava.awt.headless=true -Djava.net.preferIPv4Stack=true -Dlog4j.configuration=$LOG4J_XML "
JAVA_OPTS=" -Xmx4g -Xms4g -Xmn2g -XX:SurvivorRatio=8 -XX:PermSize=128m -XX:MaxPermSize=256m -Xss256k -XX:+UseParallelGC -Dlog4j.configuration=$LOG4J_XML "
JAVA_MEM_OPTS=`sed '/^#/d;/prop.jvm.mem-opts/!d;s/.*=//' conf/dubbo.properties | tr -d '\r'`
echo "Starting the $SERVER_NAME, $SERVER_HOST:$SERVER_PORT"
# TODO: 未导入环境变量,远程启动会有问题
nohup java $JAVA_MEM_OPTS $JAVA_OPTS -classpath $CLASS_PATH com.alibaba.dubbo.container.Main > $LOG_STDOUT 2>&1 &
# =======================================================================================
# 检测服务状态,服务启动状态OK之后再退出
# =======================================================================================
echo -e " Waiting for service status OK ...\c"
COUNT=0
while [ $COUNT -lt 1 ]; do
echo -e ".\c"
sleep 1
# 能够连通服务端口号,则服务启动完成
COUNT=`echo status | nc -4 -i 1 $SERVER_HOST $SERVER_PORT | grep -c OK`
done
echo "OK!"
# 下面ps命令参数兼容linux、Mac OSX(Free BSD)
PIDS=`ps -e -o 'pid=' -o 'command='|grep java|grep "$CONF_DIR"|awk '{print $1}'`
echo " PID: $PIDS"
echo " STDOUT: $LOG_STDOUT"
if [ `hostname|grep 'hst.ehaieridc.net'` ];then
host=`hostname |awk -F. '{print $1}'`
curl -s "http://10.9.10.178/cgi-bin/zbop.cgi?action=en&host=${host}&item=stock-coreapi"
fi
dubbo通过SPI扩展container来启动
spring=com.alibaba.dubbo.container.spring.SpringContainer
jetty=com.alibaba.dubbo.container.jetty.JettyContainer
log4j=com.alibaba.dubbo.container.log4j.Log4jContainer
logback=com.alibaba.dubbo.container.logback.LogbackContainer
public class Main {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
com.alibaba.dubbo.container.Main.main(args);
}
}
public class Main {
public static final String CONTAINER_KEY = "dubbo.container";
public static final String SHUTDOWN_HOOK_KEY = "dubbo.shutdown.hook";
private static final Logger logger = LoggerFactory.getLogger(Main.class);
private static final ExtensionLoader loader = ExtensionLoader.getExtensionLoader(Container.class);
private static volatile boolean running = true;
public static void main(String[] args) {
try {
if (args == null || args.length == 0) {
//如果main方法不传递参数使用默认容器 spring
String config = ConfigUtils.getProperty(CONTAINER_KEY, loader.getDefaultExtensionName());
args = Constants.COMMA_SPLIT_PATTERN.split(config);
}
final List containers = new ArrayList();
for (int i = 0; i < args.length; i ++) {
//创建spring 容器放入到containers集合中
containers.add(loader.getExtension(args[i]));
}
logger.info("Use container type(" + Arrays.toString(args) + ") to run dubbo serivce.");
if ("true".equals(System.getProperty(SHUTDOWN_HOOK_KEY))) {
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
for (Container container : containers) {
try {
container.stop();
logger.info("Dubbo " + container.getClass().getSimpleName() + " stopped!");
} catch (Throwable t) {
logger.error(t.getMessage(), t);
}
synchronized (Main.class) {
running = false;
Main.class.notify();
}
}
}
});
}
for (Container container : containers) {
//启动spring容器
container.start();
logger.info("Dubbo " + container.getClass().getSimpleName() + " started!");
}
System.out.println(new SimpleDateFormat("[yyyy-MM-dd HH:mm:ss]").format(new Date()) + " Dubbo service server started!");
} catch (RuntimeException e) {
e.printStackTrace();
logger.error(e.getMessage(), e);
System.exit(1);
}
synchronized (Main.class) {
while (running) {
try {
Main.class.wait();
} catch (Throwable e) {
}
}
}
}
}
public class SpringContainer implements Container {
private static final Logger logger = LoggerFactory.getLogger(SpringContainer.class);
public static final String SPRING_CONFIG = "dubbo.spring.config";
public static final String DEFAULT_SPRING_CONFIG = "classpath*:META-INF/spring/*.xml";
static ClassPathXmlApplicationContext context;
public static ClassPathXmlApplicationContext getContext() {
return context;
}
public void start() {
//读取springconfig 文件的配置
String configPath = ConfigUtils.getProperty(SPRING_CONFIG);
if (configPath == null || configPath.length() == 0) {
//没有就是用默认的配置
configPath = DEFAULT_SPRING_CONFIG;
}
context = new ClassPathXmlApplicationContext(configPath.split("[,\\s]+"));
context.start();
}
public void stop() {
try {
if (context != null) {
context.stop();
context.close();
context = null;
}
} catch (Throwable e) {
logger.error(e.getMessage(), e);
}
}
}
public static String getProperty(String key) {
return getProperty(key, null);
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public static String getProperty(String key, String defaultValue) {
//获取系统参数dubbo.spring.config
String value = System.getProperty(key);
if (value != null && value.length() > 0) {
return value;
}
//如果为空获得不到从properties 的配置文件中获取
Properties properties = getProperties();
return replaceProperty(properties.getProperty(key, defaultValue), (Map)properties);
}
dubbo.properties
dubbo.container=spring
dubbo.spring.config=classpath:service-deploy.xml
dubbo.application.name=stock-service-provider
# dubbo.protocol.host=10.130.21.88