From 63b462352298606cb80f9defa427efba77cbeb28 Mon Sep 17 00:00:00 2001 From: zzlgreat Date: Thu, 11 Dec 2025 21:11:43 +0800 Subject: [PATCH] update pay ui --- gunicorn_app_config.py | 135 +++++++++++++++++++++++++++++++++++++++++ start_production.bat | 30 +++++++++ start_production.sh | 64 +++++++++++++++++++ 3 files changed, 229 insertions(+) create mode 100644 gunicorn_app_config.py create mode 100644 start_production.bat create mode 100644 start_production.sh diff --git a/gunicorn_app_config.py b/gunicorn_app_config.py new file mode 100644 index 00000000..cbe925d6 --- /dev/null +++ b/gunicorn_app_config.py @@ -0,0 +1,135 @@ +# -*- coding: utf-8 -*- +""" +Gunicorn 配置文件 - app.py 生产环境配置(支持 Flask-SocketIO) + +使用方式: + # 推荐方式: 使用 geventwebsocket 支持 WebSocket + 高并发 + gunicorn -c gunicorn_app_config.py app:app + + # 或者使用 eventlet(如果 gevent 有问题) + pip install eventlet + gunicorn -c gunicorn_app_config.py -k eventlet app:app +""" + +import os + +# ==================== 基础配置 ==================== + +# 绑定地址和端口 +bind = '0.0.0.0:5001' + +# Worker 进程数(Flask-SocketIO 使用异步 worker,不需要太多) +workers = 1 # geventwebsocket 要求单 worker + +# Worker 类型 - 使用 geventwebsocket 支持 WebSocket +worker_class = 'geventwebsocket.gunicorn.workers.GeventWebSocketWorker' + +# Worker 连接数(gevent 异步模式下可以处理大量并发连接) +worker_connections = 1000 + +# 每个 worker 处理的最大请求数,超过后重启(防止内存泄漏) +max_requests = 10000 +max_requests_jitter = 1000 + +# ==================== 超时配置 ==================== + +# Worker 超时时间(秒),WebSocket 需要长连接,设大一些 +timeout = 300 + +# 优雅关闭超时时间(秒) +graceful_timeout = 30 + +# 保持连接超时时间(秒) +keepalive = 65 + +# ==================== SSL 配置 ==================== + +cert_file = '/etc/letsencrypt/live/valuefrontier.cn/fullchain.pem' +key_file = '/etc/letsencrypt/live/valuefrontier.cn/privkey.pem' + +if os.path.exists(cert_file) and os.path.exists(key_file): + certfile = cert_file + keyfile = key_file + +# ==================== 日志配置 ==================== + +accesslog = '-' +errorlog = '-' +loglevel = 'info' +access_log_format = '%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s" %(D)sμs' + +# ==================== 进程管理 ==================== + +daemon = False +pidfile = '/tmp/gunicorn_app.pid' +proc_name = 'vf_react_app' + +# 不预加载应用,确保 gevent monkey patch 正确 +preload_app = False + +# ==================== Hook 函数 ==================== + +def on_starting(server): + """服务器启动时调用""" + print("=" * 60) + print("🚀 Gunicorn + Flask-SocketIO 服务器正在启动...") + print(f" Workers: {server.app.cfg.workers}") + print(f" Worker Class: {server.app.cfg.worker_class}") + print(f" Bind: {server.app.cfg.bind}") + print(f" Worker Connections: {server.app.cfg.worker_connections}") + print("=" * 60) + + +def when_ready(server): + """服务准备就绪时调用""" + print("✅ Gunicorn 服务准备就绪! WebSocket 支持已启用") + + +def post_worker_init(worker): + """Worker 初始化完成后调用""" + # gevent monkey patching 在这里自动完成 + print(f"✅ Worker {worker.pid} 已初始化 (gevent 异步模式)") + + +def worker_abort(worker): + """Worker 收到 SIGABRT 信号时调用(超时)""" + print(f"⚠️ Worker {worker.pid} 超时被终止,正在重启...") + + +def on_exit(server): + """服务器退出时调用""" + print("🛑 Gunicorn 服务器已关闭") + + +# ==================== systemd 服务配置示例 ==================== +""" +保存为 /etc/systemd/system/vf_react.service: + +[Unit] +Description=VF React Flask Application with SocketIO +After=network.target redis.service mysql.service + +[Service] +User=root +Group=root +WorkingDirectory=/path/to/vf_react +Environment="PATH=/path/to/venv/bin" +ExecStart=/path/to/venv/bin/gunicorn -c gunicorn_app_config.py app:app +ExecReload=/bin/kill -s HUP $MAINPID +Restart=always +RestartSec=5 +TimeoutStopSec=30 + +[Install] +WantedBy=multi-user.target + +启用服务: + sudo systemctl daemon-reload + sudo systemctl enable vf_react + sudo systemctl start vf_react + sudo systemctl status vf_react + +查看日志: + sudo journalctl -u vf_react -f +""" + diff --git a/start_production.bat b/start_production.bat new file mode 100644 index 00000000..0cde100f --- /dev/null +++ b/start_production.bat @@ -0,0 +1,30 @@ +@echo off +REM 生产环境启动脚本 - app.py (Flask + SocketIO) +REM 使用 Gunicorn + geventwebsocket 支持高并发 +REM 注意: Windows 下使用 waitress 替代 Gunicorn + +echo ============================================ +echo 启动 VF React 生产服务器 (Windows) +echo ============================================ + +cd /d "%~dp0" + +REM 检查 waitress(Windows 兼容的 WSGI 服务器) +python -c "import waitress" 2>nul +if errorlevel 1 ( + echo 正在安装 waitress... + pip install waitress +) + +echo. +echo 启动服务器... +echo 端口: 5001 +echo 线程数: 8 +echo. + +REM Windows 下使用 waitress 替代 gunicorn +REM 注意:waitress 不支持 WebSocket,建议在 Linux 服务器上部署生产环境 +python -c "from waitress import serve; from app import app; print('Starting...'); serve(app, host='0.0.0.0', port=5001, threads=8)" + +pause + diff --git a/start_production.sh b/start_production.sh new file mode 100644 index 00000000..06ad0495 --- /dev/null +++ b/start_production.sh @@ -0,0 +1,64 @@ +#!/bin/bash +# 生产环境启动脚本 - app.py (Flask + SocketIO) +# 使用 Gunicorn + geventwebsocket 支持高并发 + +set -e + +# 颜色输出 +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +RED='\033[0;31m' +NC='\033[0m' # No Color + +echo -e "${GREEN}============================================${NC}" +echo -e "${GREEN}🚀 启动 VF React 生产服务器${NC}" +echo -e "${GREEN}============================================${NC}" + +# 切换到脚本所在目录 +cd "$(dirname "$0")" + +# 检查 Python 环境 +if ! command -v python3 &> /dev/null; then + echo -e "${RED}❌ Python3 未安装${NC}" + exit 1 +fi + +# 检查 gunicorn +if ! command -v gunicorn &> /dev/null; then + echo -e "${YELLOW}⚠️ Gunicorn 未安装,正在安装...${NC}" + pip install gunicorn +fi + +# 检查必要的依赖 +echo -e "${GREEN}📦 检查依赖...${NC}" +python3 -c "import gevent; import geventwebsocket" 2>/dev/null || { + echo -e "${RED}❌ 缺少 gevent 或 geventwebsocket${NC}" + echo "运行: pip install gevent gevent-websocket" + exit 1 +} + +# 检查 Redis +echo -e "${GREEN}🔍 检查 Redis 连接...${NC}" +python3 -c "import redis; r=redis.Redis(); r.ping()" 2>/dev/null || { + echo -e "${YELLOW}⚠️ Redis 连接失败,请确保 Redis 正在运行${NC}" +} + +# 停止旧进程(如果存在) +if [ -f /tmp/gunicorn_app.pid ]; then + OLD_PID=$(cat /tmp/gunicorn_app.pid) + if kill -0 $OLD_PID 2>/dev/null; then + echo -e "${YELLOW}🛑 停止旧进程 (PID: $OLD_PID)...${NC}" + kill -TERM $OLD_PID + sleep 2 + fi +fi + +# 启动服务器 +echo -e "${GREEN}🚀 启动 Gunicorn + Flask-SocketIO...${NC}" +echo -e "${GREEN} 配置: gunicorn_app_config.py${NC}" +echo -e "${GREEN} 端口: 5001${NC}" +echo -e "${GREEN} Worker: GeventWebSocketWorker${NC}" + +# 使用 gunicorn 启动(支持 WebSocket 的高并发模式) +exec gunicorn -c gunicorn_app_config.py app:app +