#!/bin/bash SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" API_PORT=${API_PORT:-8080} ADMIN_PORT=${ADMIN_PORT:-5174} GATEWAY_PORT=${GATEWAY_PORT:-9000} TIMEOUT=${STARTUP_TIMEOUT:-180} SKIP_GATEWAY=${SKIP_GATEWAY:-false} LOG_DIR="/tmp/service-logs" mkdir -p "$LOG_DIR" RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' log_info() { echo -e "${BLUE}[INFO]${NC} $1"; } log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; } log_warning() { echo -e "${YELLOW}[WARNING]${NC} $1"; } log_error() { echo -e "${RED}[ERROR]${NC} $1"; } echo "==========================================" echo " 启动所有服务进行 E2E 测试" echo "==========================================" echo "" echo "配置信息:" echo " API 端口: $API_PORT" echo " Admin 端口: $ADMIN_PORT" echo " Gateway 端口: $GATEWAY_PORT" echo " 启动超时: ${TIMEOUT}秒" echo " 跳过 Gateway: $SKIP_GATEWAY" echo "" check_port_available() { local port=$1 local service=$2 if lsof -i :$port > /dev/null 2>&1; then log_warning "端口 $port 已被占用" local pid=$(lsof -t -i :$port) if [ -n "$pid" ]; then log_info "占用进程 PID: $pid ($(ps -p $pid -o comm= 2>/dev/null || echo '未知'))" read -p "是否终止占用进程? (y/n): " -n 1 -r echo if [[ $REPLY =~ ^[Yy]$ ]]; then kill -9 $pid 2>/dev/null log_success "已终止进程 $pid" sleep 2 return 0 else log_error "无法启动 $service,端口被占用" return 1 fi fi fi return 0 } check_service() { local name=$1 local url=$2 local max_wait=$3 log_info "等待 $name 服务就绪..." local waited=0 while [ $waited -lt $max_wait ]; do local http_code=$(curl -s -o /dev/null -w "%{http_code}" "$url" 2>/dev/null || echo "000") if [ "$http_code" != "000" ] && [ "$http_code" != "502" ] && [ "$http_code" != "503" ]; then log_success "$name 服务已就绪 (HTTP $http_code)" return 0 fi sleep 2 waited=$((waited + 2)) printf "\r 等待中... %d秒 (HTTP: %s) " $waited "$http_code" done echo "" log_error "$name 服务启动超时" return 1 } check_dependencies() { log_info "检查依赖..." local missing_deps=() if ! command -v java &> /dev/null; then missing_deps+=("java") fi if ! command -v mvn &> /dev/null; then missing_deps+=("mvn") fi if ! command -v node &> /dev/null; then missing_deps+=("node") fi if ! command -v npm &> /dev/null; then missing_deps+=("npm") fi if [ ${#missing_deps[@]} -gt 0 ]; then log_error "缺少依赖: ${missing_deps[*]}" log_info "请安装缺少的依赖后重试" return 1 fi log_success "所有依赖已安装" log_info "Java: $(java -version 2>&1 | head -1)" log_info "Maven: $(mvn -version 2>&1 | head -1)" log_info "Node: $(node --version)" log_info "NPM: $(npm --version)" return 0 } start_api() { echo "" echo "----------------------------------------" echo "启动 API 服务..." echo "----------------------------------------" if [ -f "/tmp/api-service.pid" ]; then local pid=$(cat /tmp/api-service.pid) if ps -p "$pid" > /dev/null 2>&1; then log_warning "API 服务已在运行中 (PID: $pid)" return 0 fi fi if ! check_port_available $API_PORT "API"; then return 1 fi cd "$PROJECT_ROOT/everything-is-suitable-api/everything-is-suitable-app" if [ ! -f "pom.xml" ]; then log_error "未找到 API 项目目录" return 1 fi log_info "编译 API 项目..." mvn compile -q -DskipTests 2>/dev/null log_info "启动 API 服务..." nohup mvn spring-boot:run \ -Dspring-boot.run.arguments="--server.port=$API_PORT" \ > "$LOG_DIR/api-service.log" 2>&1 & echo $! > /tmp/api-service.pid local pid=$(cat /tmp/api-service.pid) log_info "API 服务启动中 (PID: $pid)" if check_service "API" "http://localhost:$API_PORT/actuator/health" 120; then log_success "API 服务地址: http://localhost:$API_PORT" return 0 fi log_error "API 服务启动失败" log_info "查看日志: tail -100 $LOG_DIR/api-service.log" return 1 } start_gateway() { if [ "$SKIP_GATEWAY" = "true" ]; then log_info "跳过 Gateway 服务" return 0 fi echo "" echo "----------------------------------------" echo "启动 Gateway 服务..." echo "----------------------------------------" if [ -f "/tmp/gateway-service.pid" ]; then local pid=$(cat /tmp/gateway-service.pid) if ps -p "$pid" > /dev/null 2>&1; then log_warning "Gateway 服务已在运行中 (PID: $pid)" return 0 fi fi if ! check_port_available $GATEWAY_PORT "Gateway"; then return 1 fi cd "$PROJECT_ROOT/everything-is-suitable-api/everything-is-suitable-gateway" if [ ! -f "pom.xml" ]; then log_warning "未找到 Gateway 项目目录,跳过" return 0 fi log_info "编译 Gateway 项目..." mvn compile -q -DskipTests 2>/dev/null log_info "启动 Gateway 服务..." nohup mvn spring-boot:run \ -Dspring-boot.run.arguments="--server.port=$GATEWAY_PORT" \ > "$LOG_DIR/gateway-service.log" 2>&1 & echo $! > /tmp/gateway-service.pid local pid=$(cat /tmp/gateway-service.pid) log_info "Gateway 服务启动中 (PID: $pid)" if check_service "Gateway" "http://localhost:$GATEWAY_PORT/actuator/health" 60; then log_success "Gateway 服务地址: http://localhost:$GATEWAY_PORT" return 0 fi log_warning "Gateway 服务启动失败,继续其他服务" return 0 } start_admin() { echo "" echo "----------------------------------------" echo "启动 Admin 前端服务..." echo "----------------------------------------" if [ -f "/tmp/admin-service.pid" ]; then local pid=$(cat /tmp/admin-service.pid) if ps -p "$pid" > /dev/null 2>&1; then log_warning "Admin 服务已在运行中 (PID: $pid)" return 0 fi fi if ! check_port_available $ADMIN_PORT "Admin"; then return 1 fi cd "$PROJECT_ROOT/everything-is-suitable-admin" if [ ! -f "package.json" ]; then log_error "未找到 Admin 项目目录" return 1 fi if [ ! -d "node_modules" ]; then log_info "安装 Admin 依赖..." npm install --silent fi log_info "启动 Admin 服务..." nohup npm run dev -- --port "$ADMIN_PORT" > "$LOG_DIR/admin-service.log" 2>&1 & echo $! > /tmp/admin-service.pid local pid=$(cat /tmp/admin-service.pid) log_info "Admin 服务启动中 (PID: $pid)" if check_service "Admin" "http://localhost:$ADMIN_PORT" 60; then log_success "Admin 服务地址: http://localhost:$ADMIN_PORT" return 0 fi log_error "Admin 服务启动失败" log_info "查看日志: tail -100 $LOG_DIR/admin-service.log" return 1 } show_status() { echo "" echo "==========================================" echo " 服务状态" echo "==========================================" local services=("api-service" "admin-service" "gateway-service") local ports=($API_PORT $ADMIN_PORT $GATEWAY_PORT) local names=("API" "Admin" "Gateway") for i in "${!services[@]}"; do local service="${services[$i]}" local port="${ports[$i]}" local name="${names[$i]}" if [ -f "/tmp/$service.pid" ]; then local pid=$(cat /tmp/$service.pid) if ps -p "$pid" > /dev/null 2>&1; then echo -e " $name: ${GREEN}运行中${NC} (PID: $pid, Port: $port)" else echo -e " $name: ${RED}已停止${NC}" fi else echo -e " $name: ${YELLOW}未启动${NC}" fi done echo "" } if ! check_dependencies; then exit 1 fi echo "" log_info "开始启动服务..." if ! start_api; then echo "" log_error "API 服务启动失败" exit 1 fi start_gateway if ! start_admin; then echo "" log_error "Admin 服务启动失败" log_info "停止已启动的服务..." "$SCRIPT_DIR/stop-services.sh" exit 1 fi echo "" echo "==========================================" echo " ✅ 所有服务启动成功!" echo "==========================================" show_status echo "日志目录: $LOG_DIR" echo "" echo "停止服务: ./scripts/stop-services.sh" echo "查看状态: ./scripts/start-all-services.sh status" echo ""