文章目录
- 一、什么是 Gunicorn?
- 二、为什么需要Gunicorn?
- 三、安装Gunicorn
- 四、基本使用
-
- 启动最简单的Gunicorn服务器
- 五、Worker类型
- 六、配置文件
- 七、与Flask结合实践
-
- 1. 项目结构建议
- 2. 创建WSGI入口文件
- 3. 使用Gunicorn启动
- 八、性能调优
-
- Worker数量计算
- 内存考虑
- 超时设置
- 九、日志配置
-
- 访问日志
- 错误日志
- 十、常见问题解决
-
- Worker超时
- 内存泄漏
- 502 Bad Gateway
- 十一、高级特性
-
- 热重载
- 十二、监控与维护
-
- 查看运行状态
- 优雅重启
- 优雅停止
- 十三、生产环境建议
一、什么是 Gunicorn?
Gunicorn是一个纯Python的WSGI HTTP服务器,用于运行Python Web应用程序。它简单易用,性能良好,是部署Flask、Django等WSGI兼容应用的流行选择。
WSGI是 Python 定义的一个标准接口,用于规范 Web 服务器(如 Nginx、Apache)与 Python Web 应用(如 Flask、Django)之间的通信方式。它的核心作用是让不同的 Web 服务器和 Python Web 框架能够无缝协作。
二、为什么需要Gunicorn?
开发服务器(如Flask内置的app.run())虽然方便,但有严重限制。
并发处理 | 单线程 | 多worker进程 |
性能 | 低(约每秒几十个请求) | 高(可处理数千请求) |
稳定性 | 不适合长时间运行 | 生产级稳定性 |
配置选项 | 有限 | 丰富的调优选项 |
请求队列 | 无 | 智能请求队列管理 |
三、安装Gunicorn
pip install gunicorn
四、基本使用
启动最简单的Gunicorn服务器
假设你的Flask应用主文件是app.py,其中包含一个名为app的Flask实例:
gunicorn -w 4 -b 127.0.0.1:8000 app:app
参数说明 -w 4: 使用4个worker进程 -b 127.0.0.1:8000: 绑定到127.0.0.1的8000端口 app:app: 第一个app是模块名(app.py),第二个app是Flask实例名
app = Flask(__name__) # 这个变量名`app`就是第二个`app`所指的对象
如果你的文件是myapp.py且实例变量名为application,则命令应为:
gunicorn -w 4 -b 127.0.0.1:8000 myapp:application
常用命令行参数
-w, –workers | worker进程数 | -w 4 |
-b, –bind | 绑定地址和端口 | -b 0.0.0.0:8000 |
-k, –worker-class | worker类型 | -k gevent |
–timeout | worker超时时间(秒) | –timeout 120 |
–log-level | 日志级别 | –log-level debug |
–access-logfile | 访问日志文件 | –access-logfile – (输出到stdout) |
–error-logfile | 错误日志文件 | –error-logfile – (输出到stdout) |
五、Worker类型
Gunicorn支持多种worker类型,适用于不同场景: sync (默认): 同步worker,每个请求一个进程,适合CPU密集型任务 gevent: 基于协程的异步worker,适合IO密集型应用 eventlet: 类似gevent的异步worker tornado: 使用Tornado框架的异步worker gthread: 使用线程的worker,需要关注线程安全问题
选择建议 CPU密集型: sync或增加worker数量 IO密集型: gevent或eventlet
gunicorn -k gevent -w 4 app:app
Worker 之间相互隔离,一个 Worker 崩溃不会直接影响其他 Worker(主进程会重启崩溃的 Worker)。 Gunicorn 的主进程(Master)负责监听端口、管理 Worker,并将请求轮询分配给空闲的 Worker。 Worker 是实际干活的进程,数量(-w)和类型(-k)直接影响并发能力。
六、配置文件
对于更复杂的配置,可以使用配置文件(通常命名为gunicorn.conf.py):
# gunicorn.conf.py
bind = "0.0.0.0:8000"
workers = 4
worker_class = "gevent"
timeout = 120
accesslog = "-" # 输出到stdout
errorlog = "-" # 输出到stdout
然后使用配置文件启动:
gunicorn -c gunicorn.conf.py app:app
七、与Flask结合实践
1. 项目结构建议
myapp/
├── app/ # 应用包
│ ├── __init__.py # 创建app实例
│ ├── views.py # 路由和视图
│ └── …
├── gunicorn.conf.py # Gunicorn配置
└── wsgi.py # WSGI入口点
2. 创建WSGI入口文件
wsgi.py内容:
from app import create_app # 假设你的app工厂函数名为create_app
app = create_app()
if __name__ == "__main__":
app.run()
3. 使用Gunicorn启动
gunicorn -c gunicorn.conf.py wsgi:app
八、性能调优
Worker数量计算
经验公式:
workers = (2 * CPU核心数) + 1
内存考虑
每个worker都会加载完整的Python应用,确保服务器有足够内存:
总内存 ≈ (worker数量 × 单个worker内存) + 系统开销
超时设置
根据应用响应时间调整:
timeout = 120 # 秒
九、日志配置
访问日志
accesslog = "/var/log/gunicorn/access.log"
access_log_format = '%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"'
错误日志
errorlog = "/var/log/gunicorn/error.log"
loglevel = "info"
capture_output = True # 捕获stdout/stderr
十、常见问题解决
Worker超时
错误信息:
[CRITICAL] WORKER TIMEOUT
解决方案:
- 增加timeout值
- 优化应用性能
- 考虑使用异步worker
内存泄漏
现象:内存使用持续增长 解决方案:
- 定期重启worker
- 使用max_requests和max_requests_jitter参数
502 Bad Gateway
可能原因:
- Gunicorn未运行
- Nginx配置错误
- 端口不匹配
检查步骤:
- 确认Gunicorn是否运行:ps aux | grep gunicorn
- 检查Nginx错误日志:/var/log/nginx/error.log
- 确认端口配置一致
十一、高级特性
热重载
开发时自动重载代码变化,但生产环境中不建议使用这个功能,因为它会影响性能。
gunicorn –reload app:app
十二、监控与维护
查看运行状态
pstree -ap | grep gunicorn
优雅重启
kill -HUP <master_pid>
优雅停止
kill –TERM <master_pid>
十三、生产环境建议
- 不要使用root运行:创建专用用户
- 使用进程管理器:如systemd或supervisor
- 配置日志轮转:使用logrotate
- 设置资源限制:防止内存泄漏影响系统
评论前必须登录!
注册