11-Gunicorn 配置
- gunicron 官网:https://docs.gunicorn.org/en/stable/
- github 地址:https://github.com/benoitc/gunicorn
Gunicorn 常用参数
1 |
|
Gunicorn worker Model
Gunicorn 的工作模式是通过 work_class
参数配置的值,默认缺省值为 sync
当前支持的工作模式类型清单:sync, eventlet, gevent, tornado, gthread, gaiohttp
同步模式 sync
Sync 模式 是 Gunicorn 的默认工作模式,也是最简单的一种模式。它的工作方式是 每个请求对应一个工作进程,进程接收一个请求后会一直等待,直到请求处理完成并返回响应,然后该进程才能继续处理下一个请求。
工作原理:
- 在 Sync 模式下,Gunicorn 为每个请求分配一个 worker 进程。
- 每个 worker 进程只能同时处理一个请求。
- 处理完请求后,worker 进程会再次等待新的请求进入。
- 由于每个进程只能处理一个请求,I/O 操作会阻塞整个请求的处理流程。
Sync 模式的优缺点:
- 优点:
- 简单、稳定,适用于没有大量 I/O 操作的 CPU 密集型应用。
- 代码开发和调试较为简单,不需要考虑并发或协程的复杂性。
- 缺点:
- 由于每个请求都阻塞进程,处理大量 I/O 操作(如数据库查询、文件操作、API 调用等)的场景下,Sync 模式会导致效率低下。
- 无法处理高并发请求,容易成为性能瓶颈。
异步模式
与 Sync 模式不同,异步模式是基于协程的异步 I/O 模型,它允许单个进程在处理 I/O 操作时不阻塞,可以并发地处理多个请求。因此,异步模式特别适合于需要高并发的应用,尤其是大量 I/O 操作的场景。
异步 workers 分两种,一个是 eventlet,另一个是 gevent。二者都是基于 greenlets 实现的。
greenlet 是用 Python 来实现的协程方式实现的(cooperative multi-threading)。
Gevent 的工作机制
Gevent 的核心原理是将 Python 标准库中一些阻塞的 I/O 操作(如 socket
、ssl
、time
等)替换为异步的非阻塞版本。这种替换通过 monkey patching
完成。Gevent 使用 greenlet
(绿色线程)来调度协程,在遇到 I/O 操作时不会阻塞主线程,而是让其他任务先行执行,从而实现高效的并发处理。
工作流程:
- 协程创建:Gevent 使用
greenlet
创建协程,并使用gevent.spawn()
启动任务。 - 事件循环:当一个协程遇到阻塞 I/O 操作时,Gevent 将该协程挂起,并将控制权交给事件循环,事件循环调度其他任务执行。
- I/O 复用:Gevent 通过 I/O 复用(例如
select
、epoll
)管理多个 I/O 操作,当某个 I/O 操作准备就绪时,Gevent 会再次恢复相应的协程。 - 并发处理:多个协程可以同时存在,且在 I/O 操作时不会相互阻塞,达到高并发处理请求的效果。
Gevent 模式的优缺点
优点:
- 高并发:在处理大量 I/O 操作时,Gevent 能够极大地提高并发能力,因为协程的切换开销远低于线程或进程。
- 非阻塞 I/O:通过事件驱动模型,多个请求的 I/O 操作可以并行处理,不会阻塞进程,显著提高了请求的响应速度。
- 资源占用低:相比多线程或多进程,Gevent 的 Greenlet 协程更轻量,能高效利用系统资源。
缺点:
- 调试复杂:异步协程的调试与同步代码相比要复杂得多,尤其是在处理并发问题时容易引发 bug。
- 不适合 CPU 密集型任务:Gevent 在处理 CPU 密集型任务时并无优势,因为 CPU 计算任务无法释放协程,进而导致阻塞。
- Monkey Patch 引发问题:如果 Monkey Patch 操作在不合适的时机进行,可能会导致递归错误或其他不可预料的问题(例如
RecursionError: maximum recursion depth exceeded
)。
建议采用异步 worker 的场景:
- 需要长时间阻塞调用的应用,比如外部的web service
- 直接给internet提供服务
- stream流请求和响应
- 长轮询
- Web sockets(web sockets可以允许用户在浏览器中实现双向通信,实现数据的及时推送)
- Comet彗星(基于HTTP长连接的服务器推送技术(Server Push),是一种新的 Web 应用架构。服务器端会主动以异步的方式向客户端程序推送数据。Comet架构适用于事件驱动的 Web 应用,以及对交互性和实时性要求很强的应用)
Tornado Workers
可以用于使用 Tornado 框架编写应用程序。不推荐使用这种配置。
AsyncIO Workers(gthread, gaiohttp)
此 worker 与 Python3 兼容。
gaiohttp worker 利用 aiohttp 库实现异步I/O,支持 web socket;
gthread worker 采用的是线程工作模式,利用线程池管理连接。它在主循环中接受连接,已接受的连接作为连接作业添加到线程池中。
各模式对比
sync 底层实作是每个请求都由一个 process 处理。多进程模式,–workers参数,指定了工作进程的数量。
gthread 底层则是每个请求都由一个 thread 处理。多线程模式。
eventlet、gevent 底层则是利用非同步IO让一个 process 在等待 IO 回应时继续处理下个请求。协程模式。
如何选择工作模式
- IO受限,建议使用gevent或者asyncio
- CPU受限,建议增加workers数量
- 不确定内存占用?建议使用gthread
- 不知道怎么选择?建议增加workers数量
常见 log 格式
识别码 | 说明 |
---|---|
h | 远程地址 |
l | “-“ |
u | 用户名 |
t | 时间 |
r | 状态行,如:GET /test HTTP/1.1 |
m | 请求方法 |
U | 没有查询字符串的URL |
q | 查询字符串 |
H | 协议 |
s | 状态码 |
B | response长度 |
b | response长度(CLF格式) |
f | 参考 |
a | 用户代理 |
T | 请求时间,单位为s |
D | 请求时间,单位为ms |
p | 进程id |
{Header}i | 请求头 |
{Header}o | 相应头 |
{Variable}e | 环境变量 |
更多配置:http://docs.gunicorn.org/en/stable/settings.html#server-mechanics