Files
vf_react/gunicorn_eventlet_config.py

238 lines
7.0 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 配置文件 - Eventlet 高并发配置48核128GB 专用)
服务器配置: 48核心 128GB 内存
目标并发: 5,000-10,000 实际并发(理论 320,000 连接)
使用方式:
# 设置环境变量后启动
export REDIS_HOST=127.0.0.1
gunicorn -c gunicorn_eventlet_config.py app:app
# 或者一行命令
REDIS_HOST=127.0.0.1 gunicorn -c gunicorn_eventlet_config.py app:app
架构说明:
- 32 个 Eventlet Worker每个占用 1 核心,预留 16 核给系统/Redis/MySQL
- 每个 Worker 处理 10000+ 并发连接(协程异步 I/O
- 数据库连接池: 32 workers × 150 = 4800 连接(实际瓶颈)
- Redis 消息队列同步跨 Worker 的 WebSocket 消息
- 理论并发能力: 32 × 10000 = 320,000 连接
- 实际并发能力: 5,000-10,000受数据库连接限制
"""
import os
# ==================== 环境变量设置 ====================
# 解决 eventlet greendns 无法解析 localhost 的问题
os.environ.setdefault('REDIS_HOST', '127.0.0.1')
# ==================== 基础配置 ====================
# 绑定地址和端口
bind = '0.0.0.0:5001'
# Worker 进程数
# 48 核心机器: 32 Workers目标 5000-10000 并发)
# 每个 Eventlet Worker 是单线程但支持协程并发
workers = 32
# Worker 类型 - eventlet 异步模式
worker_class = 'eventlet'
# 每个 worker 的最大并发连接数
# 16 Workers × 10000 = 160,000 并发连接能力
worker_connections = 10000
# 每个 worker 处理的最大请求数(防止内存泄漏)
# 128GB 内存充足,可以设置较大值
max_requests = 100000
max_requests_jitter = 10000
# ==================== 超时配置 ====================
# Worker 超时时间(秒)
# WebSocket 长连接需要较长超时
timeout = 600
# 优雅关闭超时时间(秒)
# 16 个 Worker 需要更长的优雅关闭时间
graceful_timeout = 120
# 保持连接超时时间(秒)
keepalive = 120
# ==================== 内存优化 ====================
# 128GB 内存,可以适当增加缓冲区
# 限制请求行大小(防止恶意请求)
limit_request_line = 8190
# 限制请求头数量
limit_request_fields = 200
# 限制请求头大小
limit_request_field_size = 8190
# ==================== 日志配置 ====================
accesslog = '-'
errorlog = '-'
loglevel = 'info'
capture_output = True
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_eventlet.pid'
proc_name = 'vf_react_eventlet'
# 不预加载应用
preload_app = False
# ==================== Hook 函数 ====================
def on_starting(server):
"""服务器启动时调用"""
workers = server.app.cfg.workers
connections = server.app.cfg.worker_connections
total = workers * connections
db_pool = workers * 150 # pool_size=50 + max_overflow=100
print("=" * 70)
print("🚀 Gunicorn + Eventlet 高并发服务器正在启动...")
print("=" * 70)
print(f" 服务器配置: 48核心 128GB 内存")
print(f" Workers: {workers} 个 Eventlet 协程进程")
print(f" 每 Worker 连接数: {connections:,}")
print(f" 理论并发能力: {total:,} 连接")
print(f" 数据库连接池: {db_pool:,} 连接(实际瓶颈)")
print(f" 目标实际并发: 5,000-10,000")
print("-" * 70)
print(f" Bind: {server.app.cfg.bind}")
print(f" Max Requests: {server.app.cfg.max_requests:,}")
print(f" Timeout: {server.app.cfg.timeout}s")
print("-" * 70)
print(" 多进程架构:")
print(" - Redis db=0: 微信登录状态(跨 Worker 共享)")
print(" - Redis db=1: Flask Session跨 Worker 共享)")
print(" - Redis db=2: SocketIO 消息队列(跨 Worker 同步)")
print("=" * 70)
def when_ready(server):
"""服务准备就绪时调用"""
workers = server.app.cfg.workers
connections = server.app.cfg.worker_connections
total = workers * connections
db_pool = workers * 150
print("=" * 70)
print(f"✅ Gunicorn + Eventlet 服务准备就绪!")
print(f" {workers} 个 Worker 已启动")
print(f" 理论并发能力: {total:,} 连接")
print(f" 数据库连接池: {db_pool:,} 连接")
print(f" 目标实际并发: 5,000-10,000")
print(f" WebSocket + HTTP API 混合高并发已启用")
print("=" * 70)
def post_worker_init(worker):
"""Worker 初始化完成后调用"""
print(f"✅ Eventlet Worker {worker.pid} 已初始化 (10,000 并发连接 + 150 数据库连接就绪)")
# 触发事件轮询初始化(使用 Redis 锁确保只有一个 Worker 启动调度器)
try:
from app import _auto_init_polling
print(f"[轮询] Worker {worker.pid} 尝试初始化事件轮询...")
_auto_init_polling()
except Exception as e:
print(f"[轮询] Worker {worker.pid} 初始化事件轮询失败: {e}")
def worker_abort(worker):
"""Worker 收到 SIGABRT 信号时调用(超时)"""
print(f"⚠️ Worker {worker.pid} 超时被终止,正在重启...")
def on_exit(server):
"""服务器退出时调用"""
print("🛑 Gunicorn + Eventlet 服务器已关闭")
# ==================== systemd 服务配置示例 ====================
"""
保存为 /etc/systemd/system/vf_eventlet.service:
[Unit]
Description=VF React Flask (Eventlet 160K Concurrent) - 48 Core 128GB
After=network.target redis.service mysql.service
[Service]
User=root
Group=root
WorkingDirectory=/path/to/vf_react
Environment="PATH=/path/to/venv/bin"
Environment="REDIS_HOST=127.0.0.1"
# 系统资源限制48核128GB专用服务器
LimitNOFILE=200000
LimitNPROC=65535
ExecStart=/path/to/venv/bin/gunicorn -c gunicorn_eventlet_config.py app:app
ExecReload=/bin/kill -s HUP $MAINPID
Restart=always
RestartSec=5
TimeoutStopSec=120
[Install]
WantedBy=multi-user.target
启用服务:
sudo systemctl daemon-reload
sudo systemctl enable vf_eventlet
sudo systemctl start vf_eventlet
sudo systemctl status vf_eventlet
查看日志:
sudo journalctl -u vf_eventlet -f
============================================================
系统优化(在 110.42.32.207 上执行):
# 1. 增加文件描述符限制
echo "* soft nofile 200000" >> /etc/security/limits.conf
echo "* hard nofile 200000" >> /etc/security/limits.conf
# 2. 内核参数优化(/etc/sysctl.conf
cat >> /etc/sysctl.conf << 'EOF'
# TCP 连接优化
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 65535
net.ipv4.tcp_max_syn_backlog = 65535
# 端口范围
net.ipv4.ip_local_port_range = 1024 65535
# TIME_WAIT 优化
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 15
# 内存优化128GB 内存)
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
# 连接跟踪(防火墙)
net.netfilter.nf_conntrack_max = 1000000
EOF
# 3. 应用内核参数
sysctl -p
============================================================
"""