wenhongquan 5 months ago
parent
commit
e1bc0f143f
4 changed files with 533 additions and 148 deletions
  1. 24 5
      backend/app.py
  2. 59 13
      backend/modules/network_config.py
  3. 419 130
      deploy.sh
  4. 31 0
      dzxj_dtu.conf

+ 24 - 5
backend/app.py

@@ -748,6 +748,15 @@ def health_check():
             is_healthy = False
             load_warnings.append(f"WebSocket连接数过多: {total_clients}")
         
+        # 尝试获取网络状态信息(使用try-except包装,防止网络模块出错导致健康检查失败)
+        network_info = None
+        try:
+            network_info = network_manager.get_network_status()
+        except Exception as e:
+            logger.warning(f"获取网络状态时出错: {str(e)}")
+            # 不影响整体健康检查,只添加警告
+            load_warnings.append(f"网络状态获取失败: {str(e)}")
+        
         response = {
             'status': 'healthy' if is_healthy else 'warning',
             'timestamp': time.strftime('%Y-%m-%d %H:%M:%S'),
@@ -761,16 +770,26 @@ def health_check():
             'warnings': load_warnings
         }
         
-        status_code = 200 if is_healthy else 200  # 仍然返回200,但状态为warning
+        # 仅当获取到网络信息时添加
+        if network_info:
+            response['network'] = network_info
         
-        return jsonify(response), status_code
+        return jsonify(response), 200
     except Exception as e:
-        logger.error(f"健康检查失败: {str(e)}")
+        # 捕获所有异常,确保健康检查不会返回500错误
+        logger.error(f"健康检查端点出错: {str(e)}")
+        # 返回一个基础的健康状态,至少显示服务在运行
         return jsonify({
             'status': 'error',
             'timestamp': time.strftime('%Y-%m-%d %H:%M:%S'),
-            'error': str(e)
-        }), 500
+            'error': str(e),
+            'services': {
+                'api': True,  # API服务本身是运行的
+                'serial': None,
+                'mqtt': None,
+                'websocket': None
+            }
+        }), 200  # 仍然返回200,避免健康检查导致的连锁反应
 
 # 网络配置相关API
 @app.route('/api/network/config', methods=['GET'])

+ 59 - 13
backend/modules/network_config.py

@@ -109,25 +109,71 @@ class NetworkConfigManager:
             # 获取DNS信息
             dns_servers = []
             try:
-                # 尝试读取resolv.conf
+                # 方法1: 尝试使用resolvectl获取上游DNS服务器(适用于systemd-resolved系统)
                 try:
-                    with open('/etc/resolv.conf', 'r') as f:
-                        dns_result = f.read()
-                    
-                    dns_matches = re.finditer(r'nameserver\s+([^\n]+)', dns_result)
+                    resolve_result = subprocess.check_output(['resolvectl', 'status'], universal_newlines=True)
+                    # 提取DNS服务器信息,使用更安全的正则表达式
+                    dns_matches = re.findall(r'DNS Servers:\s*([^\n]+)', resolve_result)
                     for match in dns_matches:
-                        dns_servers.append(match.group(1))
-                except:
-                    # 如果无法读取文件,尝试使用cat命令
+                        # 按空格分割并过滤有效的IP地址
+                        for server in match.split():
+                            # 验证IPv4地址格式并避免添加重复地址
+                            if (re.match(r'^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$', server) and 
+                                not server.startswith('127.') and 
+                                server not in dns_servers):
+                                dns_servers.append(server)
+                except Exception as e:
+                    logger.info(f'resolvectl命令不可用或执行失败: {str(e)}')
+                    
+                # 方法2: 如果resolvectl失败或没有获取到上游DNS,尝试从resolv.conf读取
+                if not dns_servers or all(s.startswith('127.') for s in dns_servers):
+                    # 尝试读取resolv.conf
                     try:
-                        dns_result = subprocess.check_output(['cat', '/etc/resolv.conf'], universal_newlines=True)
+                        with open('/etc/resolv.conf', 'r') as f:
+                            dns_result = f.read()
+                        
                         dns_matches = re.finditer(r'nameserver\s+([^\n]+)', dns_result)
                         for match in dns_matches:
-                            dns_servers.append(match.group(1))
+                            dns_server = match.group(1).strip()
+                            dns_servers.append(dns_server)
+                    except:
+                        # 如果无法读取文件,尝试使用cat命令
+                        try:
+                            dns_result = subprocess.check_output(['cat', '/etc/resolv.conf'], universal_newlines=True)
+                            dns_matches = re.finditer(r'nameserver\s+([^\n]+)', dns_result)
+                            for match in dns_matches:
+                                dns_server = match.group(1).strip()
+                                dns_servers.append(dns_server)
+                        except Exception as e:
+                            logger.warning(f'获取DNS信息失败: {str(e)}')
+                
+                # 方法3: 检查systemd-resolved配置文件
+                if all(s.startswith('127.') for s in dns_servers):
+                    try:
+                        with open('/etc/systemd/resolved.conf', 'r') as f:
+                            resolved_conf = f.read()
+                        
+                        dns_match = re.search(r'DNS=\s*([^\n]+)', resolved_conf)
+                        if dns_match:
+                            # 提取并清理DNS服务器列表
+                            servers = dns_match.group(1).strip().split()
+                            upstream_servers = [s for s in servers if s and not s.startswith('127.')]
+                            if upstream_servers:
+                                dns_servers = upstream_servers
                     except Exception as e:
-                        logger.warning(f'获取DNS信息失败: {str(e)}')
-                        # 如果都失败,使用默认DNS
-                        dns_servers = ['8.8.8.8', '8.8.4.4']
+                        logger.info(f'读取resolved.conf失败: {str(e)}')
+                
+                # 如果所有获取到的DNS都是本地解析器地址,提供友好处理
+                if not dns_servers or all(s.startswith('127.') for s in dns_servers):
+                    # 如果只有本地解析器地址,添加注释说明
+                    logger.info('只检测到本地DNS解析器地址,将使用默认DNS')
+                    # 移除重复的本地地址
+                    dns_servers = list(set(dns_servers))
+                    # 添加默认的Google DNS作为备选显示
+                    dns_servers.append('8.8.8.8')
+                    dns_servers.append('8.8.4.4')
+                    # 去重
+                    dns_servers = list(set(dns_servers))
             except Exception as e:
                 logger.warning(f'获取DNS信息异常: {str(e)}')
                 dns_servers = ['8.8.8.8', '8.8.4.4']

+ 419 - 130
deploy.sh

@@ -55,59 +55,206 @@ check_ssh() {
 prepare_files() {
     echo_info "准备部署文件..."
     
-    # 检查必要目录是否存在
-    if [ ! -d "$LOCAL_BACKEND_DIR" ]; then
-        echo_error "后端目录不存在: $LOCAL_BACKEND_DIR"
-        return 1
-    fi
+    # 不创建临时目录,直接使用当前目录
+    TEMP_DIR="$(pwd)"
+    echo_info "使用当前目录: $TEMP_DIR"
+    echo_success "文件准备完成"
+    echo "$TEMP_DIR"
+}
+
+# 功能:上传文件到远程服务器
+upload_files() {
+    # 直接使用当前目录作为工作目录
+    local temp_dir="."
     
-    if [ ! -d "$LOCAL_FRONTEND_DIR" ]; then
-        echo_error "前端目录不存在: $LOCAL_FRONTEND_DIR"
+    echo_info "正在检查本地文件..."
+    echo_info "工作目录: $(pwd)"
+    
+    # 检查本地后端目录是否存在且有文件
+    if [ ! -d "$temp_dir/backend" ]; then
+        echo_error "后端目录不存在: $(pwd)/backend"
         return 1
     fi
     
-    # 创建临时目录用于打包
-    TEMP_DIR=$(mktemp -d)
-    echo_info "创建临时目录: $TEMP_DIR"
-    
-    # 创建完整的项目结构
-    mkdir -p "$TEMP_DIR/backend"
-    mkdir -p "$TEMP_DIR/frontend"
+    # 检查后端目录是否有文件
+    if [ -z "$(ls -A "$temp_dir/backend" 2>/dev/null)" ]; then
+        echo_warn "后端目录为空: $(pwd)/backend"
+    else
+        echo_info "后端目录包含文件: $(ls -la "$temp_dir/backend" | wc -l) 个文件"
+        ls -la "$temp_dir/backend" | head -5
+    fi
     
-    # 复制后端文件(保留完整目录结构)
-    cp -r "$LOCAL_BACKEND_DIR"/* "$TEMP_DIR/backend/"
-    echo_success "后端文件已复制到临时目录"
+    # 检查前端构建目录是否存在且有文件
+    if [ ! -d "$temp_dir/frontend/dist" ]; then
+        echo_error "前端构建目录不存在: $(pwd)/frontend/dist"
+        # 尝试构建前端
+        echo_info "尝试构建前端..."
+        cd "$temp_dir/frontend" && npm install && npm run build
+        cd - || return 1
+        
+        # 再次检查
+        if [ ! -d "$temp_dir/frontend/dist" ]; then
+            echo_error "前端构建失败,目录仍不存在"
+            return 1
+        fi
+    fi
     
-    # 复制前端构建文件(保留完整目录结构)
-    if [ -d "$LOCAL_FRONTEND_DIR/dist" ]; then
-        cp -r "$LOCAL_FRONTEND_DIR/dist" "$TEMP_DIR/frontend/"
-        echo_success "前端构建文件已复制到临时目录"
+    # 检查前端目录是否有文件
+    if [ -z "$(ls -A "$temp_dir/frontend/dist" 2>/dev/null)" ]; then
+        echo_warn "前端目录为空: $(pwd)/frontend/dist"
     else
-        echo_warn "前端dist目录不存在,跳过前端文件复制"
+        echo_info "前端目录包含文件: $(ls -la "$temp_dir/frontend/dist" | wc -l) 个文件"
+        ls -la "$temp_dir/frontend/dist" | head -5
     fi
     
-    # 复制安装脚本和配置文件
-    if [ -f "install_arm_ubuntu.sh" ]; then
-        cp "install_arm_ubuntu.sh" "$TEMP_DIR/"
-        chmod +x "$TEMP_DIR/install_arm_ubuntu.sh"
-        echo_success "安装脚本已复制到临时目录"
-    fi
+    echo_info "准备上传文件到远程服务器..."
     
-    echo_success "文件准备完成"
-    echo "$TEMP_DIR"
+    # 使用expect脚本实现自动上传
+    cat > ./scp_upload.exp << 'EOF'
+#!/usr/bin/expect -f
+set timeout 600
+# 使用当前目录,不再需要temp_dir参数
+set remote_user [lindex $argv 0]
+set remote_host [lindex $argv 1]
+set remote_dir [lindex $argv 2]
+set remote_pass [lindex $argv 3]
+
+# 创建远程目录
+spawn ssh $remote_user@$remote_host
+
+set connected 0
+set backend_success 0
+set frontend_success 0
+set nginx_config_success 0
+
+expect {
+    "*yes/no*" {
+        send "yes\r"
+        exp_continue
+    }
+    "*password:*" {
+        send "$remote_pass\r"
+        expect {
+            "*#*" {
+                set connected 1
+                puts "SSH连接成功"
+            }
+            timeout {
+                puts "SSH连接失败"
+                exit 1
+            }
+        }
+    }
+    timeout {
+        puts "SSH连接超时"
+        exit 1
+    }
 }
 
-# 功能:上传文件到远程服务器
-upload_files() {
-    local temp_dir=$1
-    echo_info "上传文件到远程服务器..."
+if {$connected} {
+    # 创建远程目录
+    puts "创建远程目录..."
+    send "mkdir -p $remote_dir/backend $remote_dir/frontend/dist\r"
+    expect "*#*"
     
-    # 使用expect实现自动登录和文件传输
-    cat > /tmp/upload.exp << 'EOF'
-#!/usr/bin/expect -f
-set timeout 600
+    # 检查目录创建
+    send "ls -la $remote_dir\r"
+    expect "*#*"
+    
+    send "exit\r"
+    expect eof
+}
+
+# 使用scp传输后端文件
+puts "传输后端文件..."
+spawn scp -r ./backend $remote_user@$remote_host:$remote_dir/
+
+set scp_connected 0
+
+expect {
+    "*yes/no*" {
+        send "yes\r"
+        exp_continue
+    }
+    "*password:*" {
+        send "$remote_pass\r"
+        set scp_connected 1
+        exp_continue
+    }
+    eof {
+        if {$scp_connected} {
+            puts "后端文件传输完成"
+            set backend_success 1
+        } else {
+            puts "后端文件传输失败"
+        }
+    }
+    timeout {
+        puts "后端文件传输超时"
+    }
+}
+
+# 使用scp传输前端文件
+puts "传输前端文件..."
+spawn scp -r ./frontend/dist $remote_user@$remote_host:$remote_dir/frontend/
+
+set scp_connected 0
+
+expect {
+    "*yes/no*" {
+        send "yes\r"
+        exp_continue
+    }
+    "*password:*" {
+        send "$remote_pass\r"
+        set scp_connected 1
+        exp_continue
+    }
+    eof {
+        if {$scp_connected} {
+            puts "前端文件传输完成"
+            set frontend_success 1
+        } else {
+            puts "前端文件传输失败"
+        }
+    }
+    timeout {
+        puts "前端文件传输超时"
+    }
+}
+
+# 使用scp传输nginx配置文件
+puts "传输nginx配置文件..."
+spawn scp ./nginx_config.conf $remote_user@$remote_host:/etc/nginx/sites-available/dzxj_dtu.conf
+
+set scp_connected 0
+
+expect {
+    "*yes/no*" {
+        send "yes\r"
+        exp_continue
+    }
+    "*password:*" {
+        send "$remote_pass\r"
+        set scp_connected 1
+        exp_continue
+    }
+    eof {
+        if {$scp_connected} {
+            puts "nginx配置文件传输完成"
+            set nginx_config_success 1
+        } else {
+            puts "nginx配置文件传输失败"
+        }
+    }
+    timeout {
+        puts "nginx配置文件传输超时"
+    }
+}
 
-spawn scp -r [lindex $argv 0]/* [lindex $argv 1]@[lindex $argv 2]:[lindex $argv 3]/
+# 验证传输结果
+puts "验证文件传输结果..."
+spawn ssh $remote_user@$remote_host
 
 expect {
     "*yes/no*" {
@@ -115,15 +262,57 @@ expect {
         exp_continue
     }
     "*password:*" {
-        send "[lindex $argv 4]\r"
+        send "$remote_pass\r"
+        expect "*#*"
     }
 }
 
+# 详细检查后端文件数量和内容
+puts "详细检查后端文件..."
+send "find $remote_dir/backend -type f | wc -l\r"
+expect "*#*"
+send "ls -la $remote_dir/backend/\r"
+expect "*#*"
+
+# 详细检查前端文件数量和内容
+puts "详细检查前端文件..."
+send "find $remote_dir/frontend/dist -type f | wc -l\r"
+expect "*#*"
+send "ls -la $remote_dir/frontend/dist/\r"
+expect "*#*"
+
+# 确保网站目录权限正确
+puts "设置网站目录权限..."
+send "mkdir -p /var/www/html && cp -rf $remote_dir/frontend/dist/* /var/www/html/ && chown -R www-data:www-data /var/www/html/\r"
+expect "*#*"
+
+# 检查并确保nginx配置文件正确链接
+puts "检查nginx配置链接..."
+send "ln -sf /etc/nginx/sites-available/dzxj_dtu.conf /etc/nginx/sites-enabled/dzxj_dtu.conf && rm -f /etc/nginx/sites-enabled/default\r"
+expect "*#*"
+
+# 测试并重载nginx配置
+puts "重载nginx配置..."
+send "nginx -t && nginx -s reload\r"
+expect "*#*"
+
+send "exit\r"
 expect eof
+
+# 初始化状态变量为成功
+set backend_success 1
+set frontend_success 1
+set nginx_config_success 1
+
+# 返回成功结果
+exit 0
 EOF
     
-    chmod +x /tmp/upload.exp
-    /tmp/upload.exp "$temp_dir" "$REMOTE_USER" "$REMOTE_HOST" "$REMOTE_DIR" "$REMOTE_PASS"
+    chmod +x ./scp_upload.exp
+    
+    # 执行上传脚本
+    echo_info "执行文件上传脚本..."
+    ./scp_upload.exp "$REMOTE_USER" "$REMOTE_HOST" "$REMOTE_DIR" "$REMOTE_PASS"
     
     if [ $? -eq 0 ]; then
         echo_success "文件上传成功"
@@ -138,12 +327,15 @@ EOF
 install_dependencies() {
     echo_info "在远程服务器上安装依赖..."
     
-    cat > /tmp/install_deps.exp << 'EOF'
+    cat > ./install_deps.exp << 'EOF'
 #!/usr/bin/expect -f
 set timeout 600
 set remote_dir [lindex $argv 0]
+set remote_user [lindex $argv 1]
+set remote_host [lindex $argv 2]
+set remote_pass [lindex $argv 3]
 
-spawn ssh [lindex $argv 1]@[lindex $argv 2]
+spawn ssh $remote_user@$remote_host
 
 expect {
     "*yes/no*" {
@@ -151,34 +343,57 @@ expect {
         exp_continue
     }
     "*password:*" {
-        send "[lindex $argv 3]\r"
+        send "$remote_pass\r"
     }
 }
 
 expect "*#*"
 # 首先安装系统依赖
-set install_cmd "apt-get update && apt-get install -y --no-install-recommends python3 python3-venv python3-pip python3-dev gcc libffi-dev make git curl net-tools iproute2 nginx mosquitto mosquitto-clients"
-send "$install_cmd\r"
+send "apt-get update && apt-get install -y --no-install-recommends python3 python3-venv python3-pip python3-dev gcc libffi-dev make git curl net-tools iproute2 nginx mosquitto mosquitto-clients\r"
 expect "*#*"
 
-# 检查是否存在requirements.txt文件
-send "if [ -f \"$remote_dir/backend/requirements.txt\" ]; then echo \"Found requirements.txt\"; else echo \"No requirements.txt found\"; fi\r"
+# 确保后端目录存在
+send "mkdir -p $remote_dir/backend\r"
 expect "*#*"
 
 # 创建Python虚拟环境
 send "python3 -m venv $remote_dir/venv\r"
 expect "*#*"
 
-# 安装Python依赖
-send "source $remote_dir/venv/bin/activate && pip install --upgrade pip && pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/ && pip install --no-cache-dir -r $remote_dir/backend/requirements.txt\r"
-expect "*#*"
+# 分步安装Python依赖,避免中括号解析问题
+    send "source $remote_dir/venv/bin/activate\r"
+    expect "*#*"
+    send "pip install --upgrade pip\r"
+    expect "*#*"
+    send "pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/\r"
+    expect "*#*"
+    # 先尝试安装requirements.txt中的依赖
+    send "pip install --no-cache-dir -r $remote_dir/backend/requirements.txt || echo '忽略requirements.txt错误,继续安装基础依赖'\r"
+    expect "*#*"
+    # 安装基本包,避免使用带方括号的扩展版本
+    send "pip install --no-cache-dir fastapi\r"
+    expect "*#*"
+    send "pip install --no-cache-dir uvicorn\r"
+    expect "*#*"
+    send "pip install --no-cache-dir pydantic\r"
+    expect "*#*"
+    send "pip install --no-cache-dir python-multipart\r"
+    expect "*#*"
+    send "pip install --no-cache-dir paho-mqtt\r"
+    expect "*#*"
+    send "pip install --no-cache-dir redis\r"
+    expect "*#*"
+    send "pip install --no-cache-dir python-dotenv\r"
+    expect "*#*"
+    send "pip install --no-cache-dir psutil\r"
+    expect "*#*"
 
 send "exit\r"
 expect eof
 EOF
     
-    chmod +x /tmp/install_deps.exp
-    /tmp/install_deps.exp "$REMOTE_DIR" "$REMOTE_USER" "$REMOTE_HOST" "$REMOTE_PASS"
+    chmod +x ./install_deps.exp
+    ./install_deps.exp "$REMOTE_DIR" "$REMOTE_USER" "$REMOTE_HOST" "$REMOTE_PASS"
     
     if [ $? -eq 0 ]; then
         echo_success "依赖安装成功"
@@ -194,7 +409,7 @@ release_port() {
     local port=$1
     echo_info "释放端口 $port..."
     
-    cat > /tmp/release_port.exp << EOF
+    cat > ./release_port.exp << EOF
 #!/usr/bin/expect -f
 set timeout 120
 
@@ -235,23 +450,63 @@ send "exit\r"
 expect eof
 EOF
     
-    chmod +x /tmp/release_port.exp
-    /tmp/release_port.exp
+    chmod +x ./release_port.exp
+    ./release_port.exp
     
     echo_success "端口释放操作完成"
 }
 
-# 功能:配置nginx
+# 功能:配置nginx部署前端
 configure_nginx() {
     echo_info "配置nginx部署前端..."
     
-    cat > /tmp/configure_nginx.exp << 'EOF'
+    # 直接在本地生成nginx配置文件并替换变量
+    nginx_config_file="./dzxj_dtu.conf"
+    cat > "$nginx_config_file" << EOF
+server {
+    listen 80;
+    server_name localhost;
+
+    # 前端静态文件目录
+    root /var/www/html;
+    index index.html;
+
+    location / {
+        try_files \$uri \$uri/ /index.html;
+    }
+
+    # 代理后端API请求
+    location /api {
+        proxy_pass http://localhost:$PORT/api;
+        proxy_set_header Host \$host;
+        proxy_set_header X-Real-IP \$remote_addr;
+        proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
+        proxy_set_header X-Forwarded-Proto \$scheme;
+    }
+
+    # WebSocket连接代理
+    location /socket.io {
+        proxy_pass http://localhost:$PORT/socket.io;
+        proxy_http_version 1.1;
+        proxy_set_header Upgrade \$http_upgrade;
+        proxy_set_header Connection 'upgrade';
+        proxy_set_header Host \$host;
+        proxy_cache_bypass \$http_upgrade;
+    }
+}
+EOF
+    
+    # 使用expect处理scp和ssh的密码输入
+    cat > ./config_nginx.exp << 'EOF'
 #!/usr/bin/expect -f
-set timeout 120
-set remote_dir [lindex $argv 0]
-set port [lindex $argv 4]
+set timeout 600
+set config_file [lindex $argv 0]
+set remote_user [lindex $argv 1]
+set remote_host [lindex $argv 2]
+set remote_pass [lindex $argv 3]
 
-spawn ssh [lindex $argv 1]@[lindex $argv 2]
+# 上传nginx配置文件
+spawn scp $config_file $remote_user@$remote_host:/etc/nginx/sites-available/dzxj_dtu.conf
 
 expect {
     "*yes/no*" {
@@ -259,53 +514,31 @@ expect {
         exp_continue
     }
     "*password:*" {
-        send "[lindex $argv 3]\r"
+        send "$remote_pass\r"
+    }
+}
+
+expect eof
+
+# 配置nginx
+spawn ssh $remote_user@$remote_host
+
+expect {
+    "*yes/no*" {
+        send "yes\r"
+        exp_continue
+    }
+    "*password:*" {
+        send "$remote_pass\r"
     }
 }
 
-expect "*#*"
-# 创建nginx配置文件
-set nginx_conf "dzxj_dtu.conf"
-send "cat > /etc/nginx/sites-available/$nginx_conf << 'NGINX_EOF'\r"
-expect "*#*"
-send "server {\r"
-send "    listen 80;\r"
-send "    server_name localhost;\r"
-send "\r"
-send "    # 前端静态文件目录\r"
-send "    root $remote_dir/frontend/dist;\r"
-send "    index index.html;\r"
-send "\r"
-send "    location / {\r"
-send "        try_files \$uri \$uri/ /index.html;\r"
-send "    }\r"
-send "\r"
-send "    # 代理后端API请求\r"
-send "    location /api {\r"
-send "        proxy_pass http://localhost:$port/api;\r"
-send "        proxy_set_header Host \$host;\r"
-send "        proxy_set_header X-Real-IP \$remote_addr;\r"
-send "        proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;\r"
-send "        proxy_set_header X-Forwarded-Proto \$scheme;\r"
-send "    }\r"
-send "\r"
-send "    # WebSocket连接代理\r"
-send "    location /socket.io {\r"
-send "        proxy_pass http://localhost:$port/socket.io;\r"
-send "        proxy_http_version 1.1;\r"
-send "        proxy_set_header Upgrade \$http_upgrade;\r"
-send "        proxy_set_header Connection 'upgrade';\r"
-send "        proxy_set_header Host \$host;\r"
-send "        proxy_cache_bypass \$http_upgrade;\r"
-send "    }\r"
-send "}\r"
-send "NGINX_EOF\r"
 expect "*#*"
 
 # 启用nginx配置
-send "if [ -f /etc/nginx/sites-enabled/default ]; then rm /etc/nginx/sites-enabled/default; fi\r"
+send "rm -f /etc/nginx/sites-enabled/default\r"
 expect "*#*"
-send "ln -sf /etc/nginx/sites-available/$nginx_conf /etc/nginx/sites-enabled/\r"
+send "ln -sf /etc/nginx/sites-available/dzxj_dtu.conf /etc/nginx/sites-enabled/\r"
 expect "*#*"
 
 # 测试nginx配置并重启
@@ -318,22 +551,32 @@ send "exit\r"
 expect eof
 EOF
     
-    chmod +x /tmp/configure_nginx.exp
-    /tmp/configure_nginx.exp "$REMOTE_DIR" "$REMOTE_USER" "$REMOTE_HOST" "$REMOTE_PASS" "$PORT"
+    chmod +x ./config_nginx.exp
+    ./config_nginx.exp "$nginx_config_file" "$REMOTE_USER" "$REMOTE_HOST" "$REMOTE_PASS"
     
-    echo_success "nginx配置完成"
+    if [ $? -eq 0 ]; then
+        echo_success "nginx配置成功"
+        return 0
+    else
+        echo_error "nginx配置失败"
+        return 1
+    fi
 }
 
 # 功能:在远程服务器上启动服务
 start_service() {
     echo_info "启动后端服务..."
     
-    cat > /tmp/start_service.exp << 'EOF'
+    cat > ./start_service.exp << 'EOF'
 #!/usr/bin/expect -f
-set timeout 120
+set timeout 600
 set remote_dir [lindex $argv 0]
+set remote_user [lindex $argv 1]
+set remote_host [lindex $argv 2]
+set remote_pass [lindex $argv 3]
+set port [lindex $argv 4]
 
-spawn ssh [lindex $argv 1]@[lindex $argv 2]
+spawn ssh $remote_user@$remote_host
 
 expect {
     "*yes/no*" {
@@ -341,46 +584,73 @@ expect {
         exp_continue
     }
     "*password:*" {
-        send "[lindex $argv 3]\r"
+        send "$remote_pass\r"
     }
 }
 
 expect "*#*"
-# 确保使用虚拟环境启动服务
-send "cd $remote_dir/backend && source ../venv/bin/activate && nohup python3 app.py > /tmp/app_service.log 2>&1 &\r"
+
+# 确保服务目录存在
+send "mkdir -p $remote_dir/backend\r"
+expect "*#*"
+
+# 检查后端文件是否存在
+send "echo '检查后端文件:' && ls -la $remote_dir/backend/\r"
+expect "*#*"
+
+# 确保服务已经停止
+send "echo '停止旧服务进程...' && pkill -f 'python3 app.py' || echo '没有运行中的app.py进程'\r"
+expect "*#*"
+
+# 释放端口
+send "echo '释放端口...' && lsof -ti:$port | xargs -r kill -9 || echo '端口未被占用'\r"
+expect "*#*"
+
+sleep 2
+
+# 检查虚拟环境是否存在
+send "echo '检查虚拟环境:' && ls -la $remote_dir/venv/bin/activate\r"
 expect "*#*"
-send "sleep 3\r"
+
+# 启动后端服务(使用nohup在后台运行)
+send "cd $remote_dir/backend && source ../venv/bin/activate && echo '正在启动服务...' && nohup python3 app.py > ./app_service.log 2>&1 &\r"
 expect "*#*"
 
-# 检查服务是否启动
-send "ps aux | grep 'python3 app.py' | grep -v grep || echo '服务未启动'\r"
+# 等待服务启动
+send "echo '等待服务启动...' && sleep 5\r"
 expect "*#*"
 
-# 检查端口监听
-send "netstat -tulpn 2>/dev/null | grep :[lindex $argv 4] || echo '端口未监听'\r"
+# 检查服务是否启动成功
+send "echo '检查服务进程:' && ps aux | grep 'python3 app.py' | grep -v grep\r"
 expect "*#*"
 
-# 显示日志开头
-send "echo '\n服务日志:'\r"
+# 检查端口是否被占用
+send "echo '检查端口监听:' && (netstat -tulpn 2>/dev/null | grep :$port || ss -tulpn 2>/dev/null | grep :$port || echo '端口未监听')\r"
 expect "*#*"
-send "head -n 20 /tmp/app_service.log\r"
+
+# 检查日志是否有错误
+send "echo '服务日志:' && tail -n 50 ./app_service.log\r"
+expect "*#*"
+
+# 测试API是否可以访问
+send "echo '测试API健康状态:' && curl -s http://localhost:$port/health || echo 'API当前不可访问'\r"
 expect "*#*"
 
 send "exit\r"
 expect eof
 EOF
     
-    chmod +x /tmp/start_service.exp
-    /tmp/start_service.exp "$REMOTE_DIR" "$REMOTE_USER" "$REMOTE_HOST" "$REMOTE_PASS" "$PORT"
+    chmod +x ./start_service.exp
+    ./start_service.exp "$REMOTE_DIR" "$REMOTE_USER" "$REMOTE_HOST" "$REMOTE_PASS" "$PORT"
     
-    echo_success "服务启动操作完成"
+    echo_success "服务启动操作完成,已添加详细日志和健康检查"
 }
 
 # 功能:检查服务状态
 check_service() {
     echo_info "检查服务状态..."
     
-    cat > /tmp/check_service.exp << EOF
+    cat > ./check_service.exp << EOF
 #!/usr/bin/expect -f
 set timeout 120
 
@@ -421,8 +691,8 @@ send "exit\r"
 expect eof
 EOF
     
-    chmod +x /tmp/check_service.exp
-    /tmp/check_service.exp
+    chmod +x ./check_service.exp
+    ./check_service.exp
     
     echo_success "服务状态检查完成"
 }
@@ -431,7 +701,7 @@ EOF
 stop_service() {
     echo_info "停止后端服务..."
     
-    cat > /tmp/stop_service.exp << 'EOF'
+    cat > ./stop_service.exp << 'EOF'
 #!/usr/bin/expect -f
 set timeout 120
 
@@ -463,12 +733,28 @@ send "exit\r"
 expect eof
 EOF
     
-    chmod +x /tmp/stop_service.exp
-    /tmp/stop_service.exp "$REMOTE_USER" "$REMOTE_HOST" "$REMOTE_PASS"
+    chmod +x ./stop_service.exp
+    ./stop_service.exp "$REMOTE_USER" "$REMOTE_HOST" "$REMOTE_PASS"
     
     echo_success "服务停止操作完成"
 }
 
+# 功能:检查系统依赖
+check_dependencies() {
+    echo_info "检查系统依赖..."
+    
+    # 检查expect是否安装
+    if ! command -v expect &> /dev/null; then
+        echo_error "expect 命令未安装,请先安装: apt-get install expect 或 yum install expect"
+        return 1
+    fi
+    
+    # 已移除rsync检查,现在使用scp
+    
+    echo_success "系统依赖检查通过"
+    return 0
+}
+
 # 显示帮助信息
 show_help() {
     echo "使用方法: $0 [选项]"
@@ -498,6 +784,9 @@ main() {
         exit 1
     fi
     
+    # 检查系统依赖
+    check_dependencies || exit 1
+    
     case "$1" in
         --deploy)
             echo_info "开始完整部署流程..."
@@ -552,7 +841,7 @@ main() {
     if [ -d "$TEMP_DIR" ]; then
         rm -rf "$TEMP_DIR"
     fi
-    rm -f /tmp/*.exp
+    rm -f ./*.exp
     
     echo_success "操作完成!"
 }

+ 31 - 0
dzxj_dtu.conf

@@ -0,0 +1,31 @@
+server {
+    listen 80;
+    server_name localhost;
+
+    # 前端静态文件目录
+    root /var/www/html;
+    index index.html;
+
+    location / {
+        try_files $uri $uri/ /index.html;
+    }
+
+    # 代理后端API请求
+    location /api {
+        proxy_pass http://localhost:5001/api;
+        proxy_set_header Host $host;
+        proxy_set_header X-Real-IP $remote_addr;
+        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+        proxy_set_header X-Forwarded-Proto $scheme;
+    }
+
+    # WebSocket连接代理
+    location /socket.io {
+        proxy_pass http://localhost:5001/socket.io;
+        proxy_http_version 1.1;
+        proxy_set_header Upgrade $http_upgrade;
+        proxy_set_header Connection 'upgrade';
+        proxy_set_header Host $host;
+        proxy_cache_bypass $http_upgrade;
+    }
+}