#!/bin/bash # ============================================ # 中华药典 AI Agent — 服务器环境检查脚本 # 用法: bash server-check.sh # ============================================ set -e RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' pass() { echo -e "${GREEN}✅ $1${NC}"; } warn() { echo -e "${YELLOW}⚠️ $1${NC}"; } fail() { echo -e "${RED}❌ $1${NC}"; } echo "╔══════════════════════════════════════════╗" echo "║ 中华药典 AI Agent 服务器环境检查 ║" echo "╚══════════════════════════════════════════╝" echo "" # ---- 系统信息 ---- echo "━━━━━━━━━━ 系统信息 ━━━━━━━━━━━━" echo "主机名: $(hostname)" echo "内核: $(uname -r)" if [ -f /etc/os-release ]; then . /etc/os-release echo "系统: $NAME $VERSION" fi echo "架构: $(uname -m)" echo "" # ---- CPU ---- echo "━━━━━━━━━━ CPU ━━━━━━━━━━━━" CORES=$(nproc) CPU_MODEL=$(lscpu 2>/dev/null | grep "Model name" | cut -d: -f2 | xargs) echo "型号: $CPU_MODEL" echo "核心数: $CORES" if [ "$CORES" -ge 4 ]; then pass "核心数满足要求 (≥4)" else fail "核心数不足,需要 ≥4,当前 $CORES" fi echo "" # ---- 内存 ---- echo "━━━━━━━━━━ 内存 ━━━━━━━━━━━━" MEM_TOTAL_KB=$(grep MemTotal /proc/meminfo | awk '{print $2}') MEM_TOTAL_GB=$((MEM_TOTAL_KB / 1024 / 1024)) echo "总内存: ${MEM_TOTAL_GB} GB" free -h | head -2 if [ "$MEM_TOTAL_GB" -ge 8 ]; then pass "内存满足要求 (≥8 GB)" elif [ "$MEM_TOTAL_GB" -ge 4 ]; then warn "内存偏小,最低 8 GB,当前 ${MEM_TOTAL_GB} GB" else fail "内存不足,需要 ≥8 GB,当前 ${MEM_TOTAL_GB} GB" fi echo "" # ---- 磁盘 ---- echo "━━━━━━━━━━ 磁盘 ━━━━━━━━━━━━" df -h / | tail -1 DISK_AVAIL_GB=$(df -BG / | tail -1 | awk '{print $4}' | sed 's/G//') echo "可用空间: ${DISK_AVAIL_GB} GB" if [ "$DISK_AVAIL_GB" -ge 20 ]; then pass "磁盘空间满足要求 (≥20 GB)" elif [ "$DISK_AVAIL_GB" -ge 10 ]; then warn "磁盘空间偏小,建议 ≥20 GB,当前 ${DISK_AVAIL_GB} GB" else fail "磁盘空间不足,需要 ≥20 GB,当前 ${DISK_AVAIL_GB} GB" fi echo "" # ---- Docker ---- echo "━━━━━━━━━━ Docker ━━━━━━━━━━━━" if command -v docker &>/dev/null; then DOCKER_VER=$(docker --version 2>/dev/null | awk '{print $3}' | sed 's/,//') echo "版本: $DOCKER_VER" if docker info &>/dev/null 2>&1; then pass "Docker 已安装且运行中 ($DOCKER_VER)" else warn "Docker 已安装但守护进程未运行" fi else fail "Docker 未安装" fi if docker compose version &>/dev/null 2>&1; then COMPOSE_VER=$(docker compose version 2>/dev/null | awk '{print $4}' | sed 's/v//') pass "Docker Compose 已安装 ($COMPOSE_VER)" elif command -v docker-compose &>/dev/null; then COMPOSE_VER=$(docker-compose --version 2>/dev/null | awk '{print $4}' | sed 's/,//') pass "Docker Compose (旧版) 已安装 ($COMPOSE_VER)" else fail "Docker Compose 未安装" fi echo "" # ---- Python ---- echo "━━━━━━━━━━ Python ━━━━━━━━━━━━" if command -v python3 &>/dev/null; then PY_VER=$(python3 --version 2>&1 | awk '{print $2}') PY_MAJOR=$(echo "$PY_VER" | cut -d. -f1) PY_MINOR=$(echo "$PY_VER" | cut -d. -f2) echo "版本: $PY_VER" if [ "$PY_MAJOR" -ge 3 ] && [ "$PY_MINOR" -ge 11 ]; then pass "Python 版本满足要求 (≥3.11)" else warn "Python 版本偏低,建议 ≥3.11,当前 $PY_VER" fi else fail "Python3 未安装" fi if command -v pip3 &>/dev/null; then echo "pip: $(pip3 --version 2>&1 | awk '{print $2}')" else warn "pip3 未安装" fi echo "" # ---- Java / Maven (可选) ---- echo "━━━━━━━━━━ Java (可选) ━━━━━━━━━━━━" if command -v java &>/dev/null; then JAVA_VER=$(java -version 2>&1 | head -1 | awk -F'"' '{print $2}') echo "Java: $JAVA_VER" JAVA_MAJOR=$(echo "$JAVA_VER" | cut -d. -f1) if [ "$JAVA_MAJOR" -ge 21 ]; then pass "Java 版本满足 Spring Boot 3.3 要求 (≥21)" else warn "Java 版本偏低,Spring Boot 需要 ≥21,但 Python 后端不受影响" fi else echo "Java 未安装(不影响,可用 Python 后端)" fi if command -v mvn &>/dev/null; then echo "Maven: $(mvn --version 2>&1 | head -1 | awk '{print $3}')" else echo "Maven 未安装(不影响,可用 Python 后端)" fi echo "" # ---- Nginx ---- echo "━━━━━━━━━━ Nginx ━━━━━━━━━━━━" if command -v nginx &>/dev/null; then NGINX_VER=$(nginx -v 2>&1 | awk -F'/' '{print $2}') pass "Nginx 已安装 ($NGINX_VER)" else warn "Nginx 未安装(生产环境需要)" fi echo "" # ---- 关键端口 ---- echo "━━━━━━━━━━ 端口占用情况 ━━━━━━━━━━━━" check_port() { local port=$1 local name=$2 if ss -tlnp 2>/dev/null | grep -q ":${port} "; then fail "端口 $port ($name) 已被占用" ss -tlnp | grep ":${port} " else pass "端口 $port ($name) 空闲" fi } check_port 80 "Nginx HTTP" check_port 443 "Nginx HTTPS" check_port 5432 "PostgreSQL" check_port 6379 "Redis" check_port 8000 "FastAPI" check_port 9000 "Spring Boot" echo "" # ---- 外网连通性 ---- echo "━━━━━━━━━━ 外网连通 ━━━━━━━━━━━━" if curl -s --connect-timeout 5 https://dashscope.aliyuncs.com > /dev/null 2>&1; then pass "可访问 Qwen API (dashscope.aliyuncs.com)" else fail "无法访问 Qwen API,请检查网络/代理" fi if curl -s --connect-timeout 5 https://registry-1.docker.io > /dev/null 2>&1; then pass "可访问 Docker Hub" else warn "无法访问 Docker Hub(镜像拉取可能需换国内源)" fi echo "" # ---- 防火墙 ---- echo "━━━━━━━━━━ 防火墙 ━━━━━━━━━━━━" if command -v ufw &>/dev/null; then sudo ufw status 2>/dev/null | head -5 || warn "无法获取 ufw 状态" elif command -v firewall-cmd &>/dev/null; then sudo firewall-cmd --list-all 2>/dev/null || warn "无法获取 firewalld 状态" else warn "未检测到防火墙工具" fi echo "" # ---- 总结 ---- echo "╔══════════════════════════════════════════╗" echo "║ 检查完成 ║" echo "╚══════════════════════════════════════════╝" echo "" echo "必备项: Docker | Docker Compose | Python 3.11+ | 端口 5432/6379/8000 空闲 | Qwen API 可达" echo "可选项: Nginx (生产推荐) | Java 21+Maven (只有 Spring Boot 后端需要)" echo "" echo "详情参考: docs/SERVER_DEPLOY.md"