#!/bin/bash # ======================================== # Go 服务管理脚本 # 用途:启动、停止、重启、查看状态 # ======================================== set -e # 颜色定义 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # 配置 SERVICE_DIR="/www/wwwroot/api.yunzer.cn" LOG_FILE="$SERVICE_DIR/go.log" PID_FILE="$SERVICE_DIR/go.pid" MAIN_FILE="$SERVICE_DIR/main.go" # 检查服务目录 if [ ! -d "$SERVICE_DIR" ]; then echo -e "${RED}错误:服务目录不存在: $SERVICE_DIR${NC}" exit 1 fi # 检查 main.go if [ ! -f "$MAIN_FILE" ]; then echo -e "${RED}错误:找不到 main.go: $MAIN_FILE${NC}" exit 1 fi # 获取进程 ID get_pid() { if [ -f "$PID_FILE" ]; then cat "$PID_FILE" else # 通过进程名查找 pgrep -f "go run main.go" | head -n 1 fi } # 检查服务是否运行 is_running() { local pid=$(get_pid) if [ -n "$pid" ] && kill -0 "$pid" 2>/dev/null; then return 0 else return 1 fi } # 启动服务 start() { echo -e "${BLUE}========================================${NC}" echo -e "${BLUE}启动 Go 服务${NC}" echo -e "${BLUE}========================================${NC}" echo "" if is_running; then local pid=$(get_pid) echo -e "${YELLOW}服务已在运行中 (PID: $pid)${NC}" return 0 fi echo -e "${YELLOW}切换到服务目录...${NC}" cd "$SERVICE_DIR" echo -e "${YELLOW}启动服务...${NC}" nohup go run main.go > "$LOG_FILE" 2>&1 & local pid=$! echo $pid > "$PID_FILE" # 等待服务启动 sleep 2 if is_running; then echo -e "${GREEN}✓ 服务启动成功 (PID: $pid)${NC}" echo -e "${GREEN}✓ 日志文件: $LOG_FILE${NC}" echo "" echo -e "${YELLOW}查看日志:${NC}" echo -e " tail -f $LOG_FILE" echo "" echo -e "${YELLOW}查看最近日志:${NC}" tail -n 20 "$LOG_FILE" else echo -e "${RED}✗ 服务启动失败${NC}" if [ -f "$LOG_FILE" ]; then echo -e "${YELLOW}最近的错误日志:${NC}" tail -n 20 "$LOG_FILE" fi exit 1 fi } # 停止服务 stop() { echo -e "${BLUE}========================================${NC}" echo -e "${BLUE}停止 Go 服务${NC}" echo -e "${BLUE}========================================${NC}" echo "" if ! is_running; then echo -e "${YELLOW}服务未运行${NC}" rm -f "$PID_FILE" return 0 fi local pid=$(get_pid) echo -e "${YELLOW}停止服务 (PID: $pid)...${NC}" # 尝试优雅停止 kill "$pid" 2>/dev/null || true # 等待最多 10 秒 local count=0 while is_running && [ $count -lt 10 ]; do sleep 1 count=$((count + 1)) echo -n "." done echo "" # 如果还在运行,强制停止 if is_running; then echo -e "${YELLOW}强制停止服务...${NC}" kill -9 "$pid" 2>/dev/null || true sleep 1 fi # 清理所有相关进程 pkill -f "go run main.go" 2>/dev/null || true rm -f "$PID_FILE" if is_running; then echo -e "${RED}✗ 服务停止失败${NC}" exit 1 else echo -e "${GREEN}✓ 服务已停止${NC}" fi } # 重启服务 restart() { echo -e "${BLUE}========================================${NC}" echo -e "${BLUE}重启 Go 服务${NC}" echo -e "${BLUE}========================================${NC}" echo "" stop echo "" sleep 2 start } # 查看状态 status() { echo -e "${BLUE}========================================${NC}" echo -e "${BLUE}Go 服务状态${NC}" echo -e "${BLUE}========================================${NC}" echo "" if is_running; then local pid=$(get_pid) echo -e "${GREEN}✓ 服务运行中${NC}" echo -e " PID: $pid" echo -e " 目录: $SERVICE_DIR" echo -e " 日志: $LOG_FILE" echo "" # 显示进程信息 echo -e "${YELLOW}进程信息:${NC}" ps aux | grep "$pid" | grep -v grep echo "" # 显示端口监听 echo -e "${YELLOW}端口监听:${NC}" netstat -tlnp 2>/dev/null | grep "$pid" || lsof -i -P -n | grep "$pid" || echo " 无法获取端口信息" echo "" # 显示最近日志 if [ -f "$LOG_FILE" ]; then echo -e "${YELLOW}最近日志(最后 10 行):${NC}" tail -n 10 "$LOG_FILE" fi else echo -e "${RED}✗ 服务未运行${NC}" # 检查是否有残留进程 local pids=$(pgrep -f "go run main.go" || true) if [ -n "$pids" ]; then echo -e "${YELLOW}发现残留进程:${NC}" ps aux | grep "go run main.go" | grep -v grep echo "" echo -e "${YELLOW}清理残留进程:${NC}" echo " bash $0 stop" fi # 显示最近日志 if [ -f "$LOG_FILE" ]; then echo "" echo -e "${YELLOW}最近日志(最后 20 行):${NC}" tail -n 20 "$LOG_FILE" fi fi } # 查看日志 logs() { if [ ! -f "$LOG_FILE" ]; then echo -e "${RED}日志文件不存在: $LOG_FILE${NC}" exit 1 fi if [ "$1" = "-f" ] || [ "$1" = "--follow" ]; then echo -e "${YELLOW}实时查看日志(Ctrl+C 退出):${NC}" tail -f "$LOG_FILE" else local lines=${1:-50} echo -e "${YELLOW}最近 $lines 行日志:${NC}" tail -n "$lines" "$LOG_FILE" fi } # 显示帮助 help() { echo -e "${BLUE}========================================${NC}" echo -e "${BLUE}Go 服务管理脚本${NC}" echo -e "${BLUE}========================================${NC}" echo "" echo "用法: $0 {start|stop|restart|status|logs}" echo "" echo "命令:" echo " start - 启动服务" echo " stop - 停止服务" echo " restart - 重启服务" echo " status - 查看服务状态" echo " logs - 查看日志(默认最后 50 行)" echo " logs -f - 实时查看日志" echo " logs 100 - 查看最后 100 行日志" echo "" echo "示例:" echo " $0 start # 启动服务" echo " $0 restart # 重启服务" echo " $0 status # 查看状态" echo " $0 logs -f # 实时查看日志" echo " $0 logs 100 # 查看最后 100 行" echo "" } # 主函数 main() { case "${1:-}" in start) start ;; stop) stop ;; restart) restart ;; status) status ;; logs) logs "${2:-}" ;; help|--help|-h) help ;; *) echo -e "${RED}错误:未知命令 '$1'${NC}" echo "" help exit 1 ;; esac } # 运行主函数 main "$@"