从零开始:用Gunicorn构建更高效的HTTP服务器
简介
当我们使用flask本地启动项目时会看到这么一条提示:
这是 Flask 在提醒你,当前使用的是开发服务器,它仅适用于开发和测试环境,不要直接在生产环境中部署。为了确保应用的性能和安全性,建议在生产环境中使用 WSGI 服务器来部署你的应用。
Gunicorn,全称为 Green Unicorn,是一个 Python WSGI HTTP 服务器,专门用于 Unix 系统。注意,不要试图在windows系统上运行Gunicorn,会出现各种错误。这篇文章将介绍Gunicorn的基本用法。
使用
首先安装gunicorn
pip install gunicorn
配置文件
新建一个文件名为gunicorn.conf.py的文件
workers = 5
bind = "0.0.0.0:8000"
# loglevel = 'debug'
timeout = 60
bind
指定服务器绑定的地址和端口。
示例:bind = "127.0.0.1:8000"
或bind = "unix:/tmp/gunicorn.sock"
默认值:"127.0.0.1:8000"
workers
设置工作进程的数量。通常建议设置为 CPU 核心数的 2 倍 + 1。
示例:workers = 4
默认值:1
worker_class
指定工作进程的类型。常见的有sync
(同步)、gevent
(异步)、uvicorn.workers.UvicornWorker
(用于 ASGI 应用)。
示例:worker_class = "gevent"
默认值:"sync"
threads
每个工作进程的线程数。适用于gthread
工作器类型。
示例:threads = 2
默认值:1
timeout
设置工作进程的超时时间(秒)。如果工作进程在指定时间内未完成任务,会被重启。
示例:timeout = 30
默认值:30
keepalive
设置客户端连接的保持时间(秒)。
示例:keepalive = 2
默认值:2
loglevel
设置日志的级别。可选值:debug
、info
、warning
、error
、critical
。
示例:loglevel = "info"
默认值:"info"
启动
gunicorn -c gunicorn.conf.py your_app:app
其中:
your_app
是你的 Python 模块名。app
是你的 Flask 应用实例。
如果你使用Dockerfile构建,那么启动代码如下:
CMD ["gunicorn", "app:app", "-c", "./gunicorn.conf.py"]
异步问题
使用gunicorn部署flask应用后,能明显感受到速度上的提升,但是也出现了一个问题:每隔一段时间,网页就会无法访问,几秒后又恢复。控制台显示有worker退出后又重启。这样的情况很影响用户体验。
经过查询资料得知,这是由于worker执行的任务超时而重启。修改配置中的timeout时间可以延长worker超时时间,从而防止worker退出。这种方法不能完全解决问题,timeout时间设置的再长,被阻塞的worker也无法恢复。
另外,有的文章说可以通过设置更多的worker数量来解决这个问题。只要worker没有全部同时退出,网站就还能继续访问,但这种修改方式会增加CPU和内存的占用率。
最终,我在gunicorn worker timeout问题排查 - 知乎中找到了答案,总的来说,只需要将gunicorn从同步模式改为异步模式就可以解决这个问题。在gunicorn.conf.py中加上这一行代码,采用gevent库,支持异步处理请求,提高吞吐量。
worker_class = "gevent"
详细的排查步骤和原因可以自行学习原文章,这里不做过多解释。