Files
vf_react/gunicorn_app_config.py
2025-12-11 21:28:57 +08:00

140 lines
3.9 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
使用方式:
# 方式1: 推荐 - 使用 geventwebsocket 支持 WebSocket + 高并发
gunicorn -c gunicorn_app_config.py app:app
# 方式2: 如果方式1有问题使用纯 gevent无 WebSocket
gunicorn -c gunicorn_app_config.py -k gevent app:app
# 方式3: 最简单的多进程模式(不支持 WebSocket但最稳定
gunicorn -w 4 -b 0.0.0.0:5001 --timeout 120 app:app
"""
import os
# ==================== 基础配置 ====================
# 绑定地址和端口
bind = '0.0.0.0:5001'
# Worker 进程数
# 注意geventwebsocket 要求单 worker如果用多 worker 需要用 sync 或 gevent
workers = 1
# Worker 类型 - 使用 geventwebsocket 支持 WebSocket
# 如果遇到问题,可以命令行添加 -k gevent 覆盖此设置
worker_class = 'geventwebsocket.gunicorn.workers.GeventWebSocketWorker'
# Worker 连接数gevent 异步模式下可以处理大量并发连接)
worker_connections = 1000
# 每个 worker 处理的最大请求数,超过后重启(防止内存泄漏)
max_requests = 5000
max_requests_jitter = 500
# ==================== 超时配置 ====================
# 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
"""