【切尾】 - src/app.py:应用工厂(原 application/factory.py) - src/extensions.py:扩展注册编排(原 extensions/) - src/wsgi.py:生产 WSGI 入口 - 根 app.py 改为 from src.app import create_app(开发入口保留) - gunicorn/Docker/compose 指向 src.wsgi:app - 删除 application/、extensions/、utils/(全部代码已迁入 src/) 【清理】21 个 router 中间件导入改 src.core;修复 level 服务潜在 bug (utils.load2dict 不存在 → model_to_dict);测试文件 R 导入改 src.core 【里程碑】全项目 flake8 从 P1 基线 154 条 → **0 条**; 12 passed;app.py 与 src.wsgi 双入口均启动 Co-Authored-By: Claude <noreply@anthropic.com>
87 lines
3.0 KiB
Python
87 lines
3.0 KiB
Python
"""
|
||
Gunicorn 配置文件
|
||
=============================================================
|
||
|
||
生产环境启动:gunicorn -c gunicorn.conf.py src.wsgi:app
|
||
|
||
设计要点:
|
||
- 使用 gevent worker:单 worker 内协程并发,适合 I/O 密集型
|
||
- worker 数默认按 CPU 核心数动态计算(2 * cpu + 1)
|
||
- 所有可调参数通过环境变量覆盖,便于 docker-compose 注入
|
||
"""
|
||
|
||
import os
|
||
import multiprocessing
|
||
|
||
# ============================================================
|
||
# 网络配置
|
||
# ============================================================
|
||
|
||
# 监听地址(0.0.0.0 表示所有网卡,Docker 容器内必须)
|
||
bind = os.getenv('GUNICORN_BIND', f'0.0.0.0:{os.getenv("FLASK_PORT", "8021")}')
|
||
|
||
# ============================================================
|
||
# Worker 配置
|
||
# ============================================================
|
||
|
||
# worker 数量(默认 2 * CPU 核心数 + 1,可通过环境变量覆盖)
|
||
workers = int(os.getenv('GUNICORN_WORKERS', multiprocessing.cpu_count() * 2 + 1))
|
||
|
||
# worker 类型:gevent 协程模型,支持高并发
|
||
worker_class = 'gevent'
|
||
|
||
# 每个 worker 的协程数(gevent 并发上限)
|
||
worker_connections = int(os.getenv('GUNICORN_WORKER_CONNECTIONS', 1000))
|
||
|
||
# worker 处理指定请求数后重启(防内存泄漏,默认 10000)
|
||
max_requests = int(os.getenv('GUNICORN_MAX_REQUESTS', 1000))
|
||
|
||
# max_requests 的随机抖动,避免所有 worker 同时重启
|
||
max_requests_jitter = int(os.getenv('GUNICORN_MAX_REQUESTS_JITTER', 50))
|
||
|
||
# worker 启动超时(秒)
|
||
timeout = int(os.getenv('GUNICORN_TIMEOUT', 120))
|
||
|
||
# 优雅关闭超时(秒),超时后强制 kill
|
||
graceful_timeout = int(os.getenv('GUNICORN_GRACEFUL_TIMEOUT', 30))
|
||
|
||
# ============================================================
|
||
# 进程管理
|
||
# ============================================================
|
||
|
||
# 守护进程模式(生产环境建议配合 systemd/supervisor 使用,保持 False)
|
||
daemon = False
|
||
|
||
# PID 文件路径
|
||
pidfile = os.getenv('GUNICORN_PIDFILE', '/tmp/gunicorn.pid')
|
||
|
||
# 预加载应用(启动时加载,worker fork 后共享,节省内存)
|
||
# 注意:开启后 worker 间不共享运行时状态
|
||
preload_app = False
|
||
|
||
# ============================================================
|
||
# 日志配置
|
||
# ============================================================
|
||
|
||
# 日志级别:debug / info / warning / error / critical
|
||
loglevel = os.getenv('GUNICORN_LOG_LEVEL', 'info')
|
||
|
||
# 访问日志路径(- 表示输出到 stdout)
|
||
accesslog = os.getenv('GUNICORN_ACCESS_LOG', '-')
|
||
|
||
# 错误日志路径(- 表示输出到 stderr)
|
||
errorlog = os.getenv('GUNICORN_ERROR_LOG', '-')
|
||
|
||
# 访问日志格式
|
||
access_log_format = '%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s" %(D)s'
|
||
|
||
# ============================================================
|
||
# 其他
|
||
# ============================================================
|
||
|
||
# 启动时是否在控制台打印配置
|
||
print_config = False
|
||
|
||
# 启动时是否检查配置有效性
|
||
check_config = False
|