具体操作
- 使用nginx作为负载均衡,配置upstream(注意修改项目名)
upstream 项目名 {server localhost:7008 max_fails=3 fail_timeout=30s;server localhost:7009 max_fails=3 fail_timeout=30s;}
- 启动命令(注意修改jar位置及端口号),后修改为
start.sh
并开放权限
#!/bin/shRESOURCE_NAME=你的jar具体位置
#默认端口号
DEFAULT_PORT=7008
#另一端口号
ALTERNATE_PORT=7009
STARTUP_TIMEOUT=60 # 等待新服务启动的超时时间(秒)
CHECK_INTERVAL=2 # 检查间隔时间(秒)check_port() {netstat -tuln | grep ":$1 " > /dev/nullreturn $?
}start_app() {PORT=$1nohup java -Xms256m -Xmx512m -jar $RESOURCE_NAME --spring.profiles.active=prod --server.port=$PORT > nohup_$PORT.out 2>&1 &echo $! > tpid_$PORTecho "应用程序启动成功,使用端口 $PORT"
}wait_for_startup() {PORT=$1TIMEOUT=$2INTERVAL=$3START_TIME=$(date +%s)while [ $(($(date +%s) - $START_TIME)) -lt $TIMEOUT ]; docheck_port $PORTif [ $? -eq 0 ]; thenecho "端口 $PORT 的应用程序已启动"return 0fiecho "等待端口 $PORT 的应用程序启动..."sleep $INTERVALdoneecho "等待超时,端口 $PORT 的应用程序未启动"return 1
}stop_app() {PORT=$1tpid=$(ps -ef | grep $RESOURCE_NAME | grep $PORT | grep -v grep | grep -v kill | awk '{print $2}')if [ -n "$tpid" ]; thenecho "停止进程,端口 $PORT, PID: $tpid..."kill -15 $tpidsleep 5tpid=$(ps -ef | grep $RESOURCE_NAME | grep $PORT | grep -v grep | grep -v kill | awk '{print $2}')if [ -n "$tpid" ]; thenecho "强制终止进程,PID: $tpid..."kill -9 $tpidelseecho "进程停止成功!"fielseecho "未找到端口 $PORT 的进程停止。"fi
}# 检查默认端口是否被占用
check_port $DEFAULT_PORT
if [ $? -eq 0 ]; thenecho "端口 $DEFAULT_PORT 已被占用,使用端口 $ALTERNATE_PORT 启动应用程序"start_app $ALTERNATE_PORTif wait_for_startup $ALTERNATE_PORT $STARTUP_TIMEOUT $CHECK_INTERVAL; thenecho "停止使用端口 $DEFAULT_PORT 的应用程序"stop_app $DEFAULT_PORTelseecho "备用端口的应用程序启动失败,保持原服务运行"fi
elseecho "端口 $DEFAULT_PORT 未被占用,使用该端口启动应用程序"start_app $DEFAULT_PORTif wait_for_startup $DEFAULT_PORT $STARTUP_TIMEOUT $CHECK_INTERVAL; thenecho "停止使用端口 $ALTERNATE_PORT 的应用程序"stop_app $ALTERNATE_PORTelseecho "默认端口的应用程序启动失败,保持备用服务运行"fi
fiecho "服务切换完成!"
说明:
启动应用程序:start_app 函数启动应用程序,并指定使用的端口。
等待应用程序完全启动:
wait_for_startup 函数会在指定的超时时间内轮询检查指定端口是否已经开始监听(应用程序是否已完全启动)。
这个函数会每 CHECK_INTERVAL 秒检查一次端口,直到超过 STARTUP_TIMEOUT 秒。
停止旧的应用程序:只有在新的应用程序完全启动后,才会停止旧的应用程序。
超时处理:如果在指定时间内新服务未能启动,将会输出相应的信息,并保留原服务继续运行。
使用说明:
STARTUP_TIMEOUT:等待新服务启动的最大时间(秒)。
CHECK_INTERVAL:检查新服务是否启动的间隔时间(秒)。