Files
vf_react/gunicorn_app_config.py
2025-12-11 21:34:20 +08:00

138 lines
3.8 KiB
Python
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.

# -*- coding: utf-8 -*-
"""
Gunicorn 配置文件 - app.py 生产环境配置(支持 Flask-SocketIO + WebSocket
使用方式:
# 推荐方式: 使用此配置文件启动
gunicorn -c gunicorn_app_config.py app:app
# 如果遇到 502 错误,可以尝试安装 eventlet 后使用:
pip install eventlet
gunicorn -k eventlet -w 1 -b 0.0.0.0:5001 --timeout 300 app:app
"""
import os
# ==================== 基础配置 ====================
# 绑定地址和端口
bind = '0.0.0.0:5001'
# Worker 进程数WebSocket 需要单 worker
workers = 1
# Worker 类型 - 使用 geventwebsocket 支持 WebSocket
# Flask-SocketIO 需要异步 worker 来支持 WebSocket
worker_class = 'geventwebsocket.gunicorn.workers.GeventWebSocketWorker'
# Worker 连接数gevent 异步模式下可以处理大量并发连接)
worker_connections = 2000
# 每个 worker 处理的最大请求数
max_requests = 0 # 禁用自动重启,避免 WebSocket 连接中断
max_requests_jitter = 0
# ==================== 超时配置 ====================
# 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 = 'debug' # 调试时用 debug正常运行用 info
capture_output = True # 捕获 print 输出到日志
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
"""