BingLogyBlog-Backend/scripts/healthcheck.sh
laobinghu 37742571ae feat: 完成项目初始化并重构部署流程
主要变更:
- 添加完整的项目结构和模块(admin、articles、comments、users、session、oauth2、email、moderation、analytics、jobs 等)
- 实现系统初始化 API(/init/status 和 /init/run)
- 重写部署流程:迁移到 package.json scripts,删除 Makefile
- 优化部署脚本:deploy.sh、healthcheck.sh、backup.sh、restore.sh、verify-env.sh
- 更新 README.md:简化文档,整合部署指南
- 优化 AGENTS.md:精简到约 150 行,包含完整的代码规范和命令速查
- 配置 Docker Compose 自动化部署(prisma migrate deploy + seed)
- 生成 OAuth2 RSA 密钥对支持
- 添加环境变量验证和数据库备份恢复功能
2026-03-28 16:53:25 +08:00

247 lines
7.0 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
# ============================================
# LinkShare Blog - 增强健康检查脚本
# ============================================
# 用途: 全面检查系统状态,包括初始化状态
# 用法: ./scripts/healthcheck.sh [--admin-token TOKEN]
# 示例: ./scripts/healthcheck.sh
# ./scripts/healthcheck.sh --admin-token xxx
set -e
# API 地址
API_URL=${HEALTH_CHECK_URL:-http://localhost:3001}
ADMIN_TOKEN=${ADMIN_TOKEN:-}
# 颜色定义
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_step() { echo -e "${BLUE}[STEP]${NC} $1"; }
# 检查 API 健康
check_api() {
log_step "检查 API 健康状态..."
local response=$(curl -s -o /dev/null -w "%{http_code}" "$API_URL/health" 2>/dev/null)
if [ "$response" = "200" ]; then
log_info "✓ API 健康检查通过 (HTTP $response)"
return 0
else
log_error "✗ API 健康检查失败 (HTTP $response)"
return 1
fi
}
# 检查数据库连接
check_database() {
log_step "检查数据库连接..."
local health_json=$(curl -s "$API_URL/health" 2>/dev/null || echo "")
if echo "$health_json" | grep -q '"database":"ok"'; then
log_info "✓ 数据库连接正常"
return 0
else
log_error "✗ 数据库连接异常"
return 1
fi
}
# 检查 Redis 连接
check_redis() {
log_step "检查 Redis 连接..."
local health_json=$(curl -s "$API_URL/health" 2>/dev/null || echo "")
if echo "$health_json" | grep -q '"redis":"ok"'; then
log_info "✓ Redis 连接正常"
return 0
else
log_error "✗ Redis 连接异常"
return 1
fi
}
# 检查初始化状态(需要管理员 token
check_initialization() {
log_step "检查系统初始化状态..."
if [ -z "$ADMIN_TOKEN" ]; then
# 尝试从环境变量或 .env 文件获取管理员 token简化版
log_warn "未提供管理员 token跳过初始化状态检查"
log_info "提示: 使用 --admin-token 参数或设置 ADMIN_TOKEN 环境变量"
return 0
fi
local response=$(curl -s -o /dev/null -w "%{http_code}" \
-H "Authorization: Bearer $ADMIN_TOKEN" \
"$API_URL/init/status" 2>/dev/null)
if [ "$response" = "200" ]; then
log_info "✓ 初始化状态检查成功"
# 可选:显示详细状态
# local status_json=$(curl -s -H "Authorization: Bearer $ADMIN_TOKEN" "$API_URL/init/status")
# echo "$status_json" | python3 -m json.tool 2>/dev/null || echo "$status_json"
return 0
else
log_error "✗ 初始化状态检查失败 (HTTP $response)"
return 1
fi
}
# 检查关键 API 端点
check_endpoints() {
log_step "检查关键 API 端点..."
local all_ok=true
# 健康检查端点
if curl -sf "$API_URL/health" >/dev/null 2>/dev/null; then
log_info " ✓ GET /health"
else
log_error " ✗ GET /health 失败"
all_ok=false
fi
# 登录端点(不验证,只检查是否存在)
if curl -sf -X POST "$API_URL/login" \
-H "Content-Type: application/json" \
-d '{"emailOrUsername":"test","password":"test"}"' \
>/dev/null 2>&1; then
# 即使登录失败401端点也是可用的
log_info " ✓ POST /login (可用)"
else
log_error " ✗ POST /login 不可用"
all_ok=false
fi
# 初始化端点(需要管理员 token
if [ -n "$ADMIN_TOKEN" ]; then
if curl -sf -H "Authorization: Bearer $ADMIN_TOKEN" "$API_URL/init/status" \
>/dev/null 2>&1; then
log_info " ✓ GET /init/status (管理员)"
else
log_warn " ⚠ GET /init/status 失败 (可能需要管理员权限)"
fi
fi
return $([ "$all_ok" = true ] && echo 0 || echo 1)
}
# 检查磁盘空间
check_disk() {
log_step "检查磁盘空间..."
local available=$(df -BG /app 2>/dev/null | tail -1 | awk '{print $4}' | sed 's/G//' || echo "0")
if [ "$available" -ge 5 ]; then
log_info "✓ 可用磁盘空间: ${available}GB"
return 0
else
log_warn "⚠ 可用磁盘空间: ${available}GB (建议至少 5GB)"
return 0 # 仅警告,不失败
fi
}
# 检查 Docker 容器状态
check_containers() {
log_step "检查 Docker 容器状态..."
local all_running=true
# 检查 API 容器
if docker ps --format '{{.Names}}' | grep -q 'blog-api'; then
log_info " ✓ API 容器运行中"
else
log_error " ✗ API 容器未运行"
all_running=false
fi
# 检查数据库容器
if docker ps --format '{{.Names}}' | grep -q 'blog-postgres'; then
log_info " ✓ PostgreSQL 容器运行中"
else
log_error " ✗ PostgreSQL 容器未运行"
all_running=false
fi
# 检查 Redis 容器
if docker ps --format '{{.Names}}' | grep -q 'blog-redis'; then
log_info " ✓ Redis 容器运行中"
else
log_error " ✗ Redis 容器未运行"
all_running=false
fi
return $([ "$all_running" = true ] && echo 0 || echo 1)
}
# 主检查流程
main() {
echo "=========================================="
echo "LinkShare Blog 系统健康检查"
echo "检查时间: $(date '+%Y-%m-%d %H:%M:%S')"
echo "API URL: $API_URL"
echo "=========================================="
echo ""
local all_passed=true
# 1. 容器状态检查
if command -v docker &>/dev/null; then
check_containers || all_passed=false
echo ""
fi
# 2. API 健康检查
check_api || all_passed=false
echo ""
# 3. 数据库检查
check_database || all_passed=false
echo ""
# 4. Redis 检查
check_redis || all_passed=false
echo ""
# 5. 初始化状态检查
check_initialization || all_passed=false
echo ""
# 6. 关键端点检查
check_endpoints || all_passed=false
echo ""
# 7. 磁盘空间检查
check_disk
echo ""
# 总结
echo "=========================================="
if [ "$all_passed" = true ]; then
log_info "所有关键检查通过!系统运行正常。"
echo ""
echo "下一步:"
echo " - 访问 API: $API_URL"
echo " - Swagger 文档: $API_URL/api-docs (开发环境)"
echo " - 初始化状态: $API_URL/init/status (需要管理员 Token)"
exit 0
else
log_error "部分检查失败,请排查上述问题。"
echo ""
echo "故障排查:"
echo " - 查看日志: docker-compose logs -f api"
echo " - 重启服务: make restart"
echo " - 重新部署: make deploy"
echo " - 查看文档: DEPLOYMENT.md"
exit 1
fi
}
# 运行主函数
main