286 lines
7.3 KiB
Bash
286 lines
7.3 KiB
Bash
#!/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 "$@"
|