Files
urbanLifeline/docker/urbanLifeline/serv/service-manager.sh
2026-01-01 11:04:24 +08:00

351 lines
9.1 KiB
Bash

#!/bin/bash
# ================================================
# Urban Lifeline - 服务管理脚本
#
# 用法:
# ./service-manager.sh start-all # 启动所有服务
# ./service-manager.sh start gateway # 启动单个服务
# ./service-manager.sh stop gateway # 停止单个服务
# ./service-manager.sh restart gateway # 重启单个服务
# ./service-manager.sh status # 查看所有服务状态
# ./service-manager.sh logs gateway # 查看服务日志
# ================================================
set -e
# 目录配置
JAR_DIR="/app/jars"
LOG_DIR="/app/logs"
PID_DIR="/app/pids"
# 服务配置: 服务名=端口:内存
declare -A SERVICES=(
["gateway"]="8080:384m"
["system"]="8082:384m"
["auth"]="8081:256m"
["file"]="8084:256m"
["log"]="8083:192m"
["message"]="8085:256m"
["crontab"]="8086:192m"
["ai"]="8090:384m"
["bidding"]="8087:256m"
["platform"]="8089:256m"
["workcase"]="8088:384m"
)
# 启动顺序 (有依赖关系)
# BOOT_ORDER=(gateway system auth file log message crontab ai bidding platform workcase)
BOOT_ORDER=(gateway system auth file ai workcase)
# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
# 获取服务端口
get_port() {
local service=$1
echo "${SERVICES[$service]}" | cut -d: -f1
}
# 获取服务内存配置
get_memory() {
local service=$1
echo "${SERVICES[$service]}" | cut -d: -f2
}
# 检查服务是否运行
is_running() {
local service=$1
local pid_file="${PID_DIR}/${service}.pid"
if [ -f "$pid_file" ]; then
local pid=$(cat "$pid_file")
if kill -0 "$pid" 2>/dev/null; then
return 0
fi
fi
return 1
}
# 等待服务就绪
wait_for_service() {
local service=$1
local port=$(get_port "$service")
local max_wait=60
local count=0
while [ $count -lt $max_wait ]; do
if curl -sf "http://localhost:${port}/actuator/health" > /dev/null 2>&1; then
return 0
fi
sleep 2
count=$((count + 2))
done
return 1
}
# 启动单个服务
start_service() {
local service=$1
local port=$(get_port "$service")
local memory=$(get_memory "$service")
local jar_file="${JAR_DIR}/${service}.jar"
local log_file="${LOG_DIR}/${service}.log"
local pid_file="${PID_DIR}/${service}.pid"
if [ ! -f "$jar_file" ]; then
log_error "JAR 文件不存在: $jar_file"
return 1
fi
if is_running "$service"; then
log_warn "$service 已在运行 (PID: $(cat $pid_file))"
return 0
fi
log_info "启动 $service (端口: $port, 内存: $memory)..."
# JVM 参数
local java_opts="-Xms128m -Xmx${memory} -XX:+UseG1GC -XX:MaxGCPauseMillis=100"
java_opts="$java_opts -Djava.security.egd=file:/dev/./urandom"
java_opts="$java_opts -Dspring.profiles.active=${SPRING_PROFILES_ACTIVE:-prod}"
# Nacos 配置
if [ -n "$NACOS_SERVER_ADDR" ]; then
java_opts="$java_opts -Dspring.cloud.nacos.discovery.server-addr=$NACOS_SERVER_ADDR"
java_opts="$java_opts -Dspring.cloud.nacos.config.server-addr=$NACOS_SERVER_ADDR"
fi
if [ -n "$NACOS_NAMESPACE" ]; then
java_opts="$java_opts -Dspring.cloud.nacos.discovery.namespace=$NACOS_NAMESPACE"
java_opts="$java_opts -Dspring.cloud.nacos.config.namespace=$NACOS_NAMESPACE"
fi
# 启动服务
nohup java $java_opts -jar "$jar_file" > "$log_file" 2>&1 &
local pid=$!
echo $pid > "$pid_file"
log_info "$service 已启动 (PID: $pid)"
}
# 停止单个服务
stop_service() {
local service=$1
local pid_file="${PID_DIR}/${service}.pid"
if ! is_running "$service"; then
log_warn "$service 未在运行"
return 0
fi
local pid=$(cat "$pid_file")
log_info "停止 $service (PID: $pid)..."
# 优雅关闭
kill -15 "$pid" 2>/dev/null || true
# 等待进程退出
local count=0
while [ $count -lt 30 ] && kill -0 "$pid" 2>/dev/null; do
sleep 1
count=$((count + 1))
done
# 强制关闭
if kill -0 "$pid" 2>/dev/null; then
log_warn "强制终止 $service..."
kill -9 "$pid" 2>/dev/null || true
fi
rm -f "$pid_file"
log_info "$service 已停止"
}
# 重启单个服务
restart_service() {
local service=$1
stop_service "$service"
sleep 2
start_service "$service"
}
# 启动所有服务
start_all() {
log_info "=========================================="
log_info " Urban Lifeline - 启动所有服务"
log_info "=========================================="
# 等待 Nacos
if [ -n "$NACOS_SERVER_ADDR" ]; then
log_info "等待 Nacos 就绪..."
local nacos_host=$(echo $NACOS_SERVER_ADDR | cut -d: -f1)
local nacos_port=$(echo $NACOS_SERVER_ADDR | cut -d: -f2)
for i in $(seq 1 30); do
if curl -sf "http://${nacos_host}:${nacos_port}/nacos/" > /dev/null 2>&1; then
log_info "Nacos 已就绪"
break
fi
sleep 2
done
fi
# 按顺序启动服务,等待健康检查通过后再启动下一个
for service in "${BOOT_ORDER[@]}"; do
start_service "$service"
log_info "等待 $service 健康检查..."
if wait_for_service "$service"; then
log_info "$service 已就绪 ✓"
else
log_warn "$service 健康检查超时,继续启动下一个服务"
fi
done
log_info "=========================================="
log_info " 所有服务启动完成"
log_info "=========================================="
show_status
# 保持容器运行并监控
monitor_services
}
# 停止所有服务
stop_all() {
log_info "停止所有服务..."
# 逆序停止
for ((i=${#BOOT_ORDER[@]}-1; i>=0; i--)); do
stop_service "${BOOT_ORDER[$i]}"
done
log_info "所有服务已停止"
}
# 查看服务状态
show_status() {
echo ""
echo "=========================================="
echo " Urban Lifeline 服务状态"
echo "=========================================="
printf "%-12s %-8s %-8s %-10s\n" "服务" "端口" "PID" "状态"
echo "------------------------------------------"
for service in "${BOOT_ORDER[@]}"; do
local port=$(get_port "$service")
local pid_file="${PID_DIR}/${service}.pid"
local pid="-"
local status="${RED}停止${NC}"
if [ -f "$pid_file" ]; then
pid=$(cat "$pid_file")
if kill -0 "$pid" 2>/dev/null; then
status="${GREEN}运行中${NC}"
fi
fi
printf "%-12s %-8s %-8s " "$service" "$port" "$pid"
echo -e "$status"
done
echo "=========================================="
}
# 查看服务日志
show_logs() {
local service=$1
local log_file="${LOG_DIR}/${service}.log"
if [ ! -f "$log_file" ]; then
log_error "日志文件不存在: $log_file"
return 1
fi
tail -f "$log_file"
}
# 监控服务 (保持容器运行)
monitor_services() {
log_info "进入监控模式..."
# 捕获退出信号
trap 'stop_all; exit 0' SIGTERM SIGINT
while true; do
sleep 30
# 检查服务状态,自动重启挂掉的服务
for service in "${BOOT_ORDER[@]}"; do
if ! is_running "$service"; then
log_warn "$service 已停止,尝试重启..."
start_service "$service"
fi
done
done
}
# 主入口
case "${1:-help}" in
start-all)
start_all
;;
stop-all)
stop_all
;;
start)
if [ -z "$2" ]; then
log_error "请指定服务名"
exit 1
fi
start_service "$2"
;;
stop)
if [ -z "$2" ]; then
log_error "请指定服务名"
exit 1
fi
stop_service "$2"
;;
restart)
if [ -z "$2" ]; then
log_error "请指定服务名"
exit 1
fi
restart_service "$2"
;;
status)
show_status
;;
logs)
if [ -z "$2" ]; then
log_error "请指定服务名"
exit 1
fi
show_logs "$2"
;;
*)
echo "Urban Lifeline 服务管理"
echo ""
echo "用法: $0 <命令> [服务名]"
echo ""
echo "命令:"
echo " start-all 启动所有服务"
echo " stop-all 停止所有服务"
echo " start <服务> 启动指定服务"
echo " stop <服务> 停止指定服务"
echo " restart <服务> 重启指定服务"
echo " status 查看服务状态"
echo " logs <服务> 查看服务日志"
echo ""
echo "可用服务: ${!SERVICES[*]}"
;;
esac