#!/bin/bash ######################################### # AI小红书 Go 后端服务重启脚本 # 用途: Ubuntu/Linux 环境下重启 Go 服务 # 支持: 开发环境(dev) 和 生产环境(prod) ######################################### # 默认配置 DEFAULT_ENV="prod" DEFAULT_PORT=8080 PROD_PORT=8070 LOG_FILE="ai_xhs.log" MAIN_FILE="./go_backend/main.go" # 颜色输出 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # 帮助信息 show_help() { echo -e "${BLUE}用法:${NC}" echo " ./restart.sh [环境]" echo "" echo -e "${BLUE}环境参数:${NC}" echo " dev - 开发环境 (默认, 端口 8080)" echo " prod - 生产环境 (端口 8070)" echo "" echo -e "${BLUE}示例:${NC}" echo " ./restart.sh # 启动开发环境" echo " ./restart.sh dev # 启动开发环境" echo " ./restart.sh prod # 启动生产环境" exit 0 } # 解析参数 ENV="${1:-$DEFAULT_ENV}" if [ "$ENV" = "help" ] || [ "$ENV" = "-h" ] || [ "$ENV" = "--help" ]; then show_help fi # 确定端口 if [ "$ENV" = "prod" ]; then PORT=$PROD_PORT else PORT=$DEFAULT_PORT ENV="dev" fi echo -e "${BLUE}========================================${NC}" echo -e "${BLUE} AI小红书 Go 后端服务重启脚本${NC}" echo -e "${BLUE}========================================${NC}" echo -e "${YELLOW}环境: $ENV${NC}" echo -e "${YELLOW}端口: $PORT${NC}" echo -e "${YELLOW}日志: $LOG_FILE${NC}" echo "" ######################################### # 1. 停止现有服务 ######################################### echo -e "${BLUE}=== [1/4] 停止现有服务 ===${NC}" # 方法1: 查找 go run main.go 进程 GO_PIDS=$(ps aux | grep "go run $MAIN_FILE" | grep -v grep | awk '{print $2}') if [ -n "$GO_PIDS" ]; then echo -e "${YELLOW}找到 Go 服务进程: $GO_PIDS${NC}" for PID in $GO_PIDS; do kill -9 $PID 2>/dev/null && echo " 已终止进程: $PID" done sleep 1 fi # 方法2: 查找编译后的可执行文件进程 COMPILED_PIDS=$(ps aux | grep "/tmp/go-build.*$MAIN_FILE" | grep -v grep | awk '{print $2}') if [ -n "$COMPILED_PIDS" ]; then echo -e "${YELLOW}找到编译后的进程: $COMPILED_PIDS${NC}" for PID in $COMPILED_PIDS; do kill -9 $PID 2>/dev/null && echo " 已终止进程: $PID" done sleep 1 fi # 方法3: 强制清理占用端口的进程 echo -e "${YELLOW}清理端口 $PORT...${NC}" # 使用 lsof 查找占用端口的进程 PORT_PID=$(lsof -ti:$PORT 2>/dev/null) if [ -n "$PORT_PID" ]; then echo " 端口 $PORT 被进程 $PORT_PID 占用" kill -9 $PORT_PID 2>/dev/null && echo " 已终止进程: $PORT_PID" fi # 使用 fuser 强制清理 (需要 sudo) if command -v fuser &> /dev/null; then sudo fuser -k $PORT/tcp 2>/dev/null || true fi # 额外的清理方法 sudo pkill -f ":$PORT" 2>/dev/null || true sudo pkill -f "main.go" 2>/dev/null || true # 等待端口完全释放 sleep 2 # 验证端口是否释放 if lsof -ti:$PORT &> /dev/null; then echo -e "${RED}⚠️ 警告: 端口 $PORT 仍被占用${NC}" lsof -i:$PORT else echo -e "${GREEN}✅ 端口 $PORT 已释放${NC}" fi echo "" ######################################### # 2. 环境检查 ######################################### echo -e "${BLUE}=== [2/4] 环境检查 ===${NC}" # 检查 Go 环境 if ! command -v go &> /dev/null; then echo -e "${RED}❌ 错误: 未检测到 Go 环境,请先安装 Go${NC}" exit 1 fi GO_VERSION=$(go version) echo -e "${GREEN}✅ Go 环境: $GO_VERSION${NC}" # 检查 main.go 是否存在 if [ ! -f "$MAIN_FILE" ]; then echo -e "${RED}❌ 错误: 未找到 $MAIN_FILE 文件${NC}" exit 1 fi echo -e "${GREEN}✅ 主文件: $MAIN_FILE${NC}" # 检查配置文件 CONFIG_FILE="config/config.${ENV}.yaml" if [ ! -f "$CONFIG_FILE" ]; then echo -e "${RED}❌ 错误: 未找到配置文件 $CONFIG_FILE${NC}" exit 1 fi echo -e "${GREEN}✅ 配置文件: $CONFIG_FILE${NC}" echo "" ######################################### # 3. 下载依赖 ######################################### echo -e "${BLUE}=== [3/4] 下载依赖 ===${NC}" if [ -f "go.mod" ]; then go mod tidy echo -e "${GREEN}✅ 依赖下载完成${NC}" else echo -e "${YELLOW}⚠️ 未找到 go.mod 文件,跳过依赖下载${NC}" fi echo "" ######################################### # 4. 启动服务 ######################################### echo -e "${BLUE}=== [4/4] 启动服务 ===${NC}" # 设置环境变量 export APP_ENV=$ENV # 清空旧日志 > $LOG_FILE # 启动服务 (后台运行) echo -e "${YELLOW}启动命令: nohup go run $MAIN_FILE > $LOG_FILE 2>&1 &${NC}" nohup go run $MAIN_FILE > $LOG_FILE 2>&1 & # 记录进程 PID NEW_PID=$! echo -e "${GREEN}✅ 服务已启动,进程 PID: $NEW_PID${NC}" echo "" ######################################### # 5. 验证启动 ######################################### echo -e "${BLUE}=== 启动验证 ===${NC}" echo -e "${YELLOW}等待服务启动 (5秒)...${NC}" sleep 5 # 检查进程是否存在 if ps -p $NEW_PID > /dev/null 2>&1; then echo -e "${GREEN}✅ 服务进程运行正常 (PID: $NEW_PID)${NC}" else echo -e "${RED}❌ 服务进程未找到,可能启动失败${NC}" echo -e "${YELLOW}最近日志:${NC}" tail -n 20 $LOG_FILE exit 1 fi # 检查端口是否监听 if lsof -ti:$PORT &> /dev/null; then echo -e "${GREEN}✅ 端口 $PORT 监听正常${NC}" else echo -e "${RED}❌ 端口 $PORT 未监听,服务可能启动失败${NC}" echo -e "${YELLOW}最近日志:${NC}" tail -n 20 $LOG_FILE exit 1 fi # 检查日志中是否有错误 if grep -i "fatal\|panic\|error" $LOG_FILE > /dev/null 2>&1; then echo -e "${YELLOW}⚠️ 日志中发现错误信息:${NC}" grep -i "fatal\|panic\|error" $LOG_FILE | head -n 5 fi echo "" ######################################### # 6. 完成信息 ######################################### echo -e "${GREEN}========================================${NC}" echo -e "${GREEN} 🎉 服务启动成功!${NC}" echo -e "${GREEN}========================================${NC}" echo "" echo -e "${BLUE}服务信息:${NC}" echo -e " 环境: ${YELLOW}$ENV${NC}" echo -e " 端口: ${YELLOW}$PORT${NC}" echo -e " 进程PID: ${YELLOW}$NEW_PID${NC}" echo -e " 日志文件: ${YELLOW}$LOG_FILE${NC}" echo "" echo -e "${BLUE}快捷命令:${NC}" echo -e " 查看日志: ${YELLOW}tail -f $LOG_FILE${NC}" echo -e " 查看进程: ${YELLOW}ps aux | grep 'go run'${NC}" echo -e " 停止服务: ${YELLOW}kill -9 $NEW_PID${NC}" echo -e " 检查端口: ${YELLOW}lsof -i:$PORT${NC}" echo "" echo -e "${BLUE}访问地址:${NC}" echo -e " 本地: ${GREEN}http://localhost:$PORT${NC}" echo -e " API测试: ${GREEN}http://localhost:$PORT/api/health${NC}" echo "" echo -e "${YELLOW}提示: 使用 Ctrl+C 不会停止后台服务,请使用 kill 命令停止${NC}"