11-Gunicorn 配置

Gunicorn 常用参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
-c CONFIG, --config=CONFIG              # 设定配置文件。
-b BIND, --bind=BIND # 设定服务需要绑定的端口。建议使用HOST:PORT。
--backlog # 未决连接的最大数量,即等待服务的客户的数量。必须是正整数,一般设定在64~2048的范围内,一般设置为2048,超过这个数字将导致客户端在尝试连接时错误
-D, --daemon # 以守护进程形式来运行Gunicorn进程,其实就是将这个服务放到后台去运行。
-w INT, --workers INT # 设置工作进程数。建议服务器每一个核心可以设置2-4个。
-k STRTING, --worker-class STRTING # 选定异步工作方式使用的模块,包括:
# sync:默认的同步worker,适用于CPU密集型任务。
# gevent:基于协程的异步worker,适用于I/O密集型任务。(需要gevent>=0.13)
# eventlet:另一个基于协程的异步worker,与gevent类似。(需要eventlet>=0.9.7)
# tornado:基于Tornado框架的异步worker。(需要tornado>=0.2)
# uvicorn:适用于ASGI应用,例如FastAPI。
# gthread
# gaiohttp(需要python 3.4和aiohttp>=0.21.5)
# 对于大多数Web应用,使用默认的sync worker已经足够。但如果你的应用需要处理大量的I/O操作,可以考虑使用gevent或eventlet。

--threads INT # 处理请求的工作线程数,使用指定数量的线程运行每个worker。为正整数,默认为1。
--worker-connections INT # 最大客户端并发数量,默认情况下这个值为1000。此设置将影响gevent和eventlet工作模式
--max-requests INT # 重新启动之前,工作将处理的最大请求数。默认值为0
--max-requests-jitter INT # 要添加到max_requests的最大抖动。抖动将导致每个工作的重启被随机化,这是为了避免所有工作被重启。randint(0,max-requests-jitter)
-t INT, --timeout INT # 超过这么多秒后工作将被杀掉,并重新启动。一般设定为30秒
--graceful-timeout INT # 优雅的人工超时时间,默认情况下,这个值为30。收到重启信号后,工作人员有那么多时间来完成服务请求。在超时(从接收到重启信号开始)之后仍然活着的工作将被强行杀死。
--keep-alive INT # 在keep-alive连接上等待请求的秒数,默认情况下值为2。一般设定在1~5秒之间。
--limit-request-line INT # HTTP请求行的最大大小,此参数用于限制HTTP请求行的允许大小,默认情况下,这个值为4094。值是0~8190的数字。此参数可以防止任何DDOS攻击
--limit-request-fields INT # 限制HTTP请求中请求头字段的数量。此字段用于限制请求头字段的数量以防止DDOS攻击,与limit-request-field-size一起使用可以提高安全性。默认情况下,这个值为100,这个值不能超过32768
--limit-request-field-size INT # 限制HTTP请求中请求头的大小,默认情况下这个值为8190。值是一个整数或者0,当该值为0时,表示将对请求头大小不做限制
--reload # 代码更新时将重启工作,默认为False。此设置用于开发,每当应用程序发生更改时,都会导致工作重新启动。
--reload-engine STRTING # 选择重载的引擎,支持的有三种:auto、pull、inotity:需要下载
--spew # 打印服务器执行过的每一条语句,默认False。此选择为原子性的,即要么全部打印,要么全部不打印
--check-config # 显示现在的配置,默认值为False,即显示。
--preload # 在工作进程被复制(派生)之前加载应用程序代码,默认为False。通过预加载应用程序,你可以节省RAM资源,并且加快服务器启动时间。
--chdir # 加载应用程序之前将chdir目录指定到指定目录
--daemon # 守护Gunicorn进程,默认False
-p FILE, --pid FILE # 设置pid文件的文件名,如果不设置将不会创建pid文件
--worker-tmp-dir DIR # 设置工作临时文件目录,如果不设置会采用默认值。
--access-logfile FILE # 确认要写入Access log的文件FILE. '-' 表示输出到标准输出.
--access-logformat STRING # 要写入的访问日志格式。access_log_format = '%(h)s %(l)s %(u)s %(t)s'
--error-logfile FILE, --log-file FILE # 确认要写入Error log的文件FILE. '-' 表示输出到标准错误输出.
--log-level LEVEL # 错误日志输出等级。支持的级别名称为:debug(调试)、info(信息)、warning(警告)、error(错误)、critical(危急)

Gunicorn worker Model

Gunicorn 的工作模式是通过 work_class 参数配置的值,默认缺省值为 sync

当前支持的工作模式类型清单:sync, eventlet, gevent, tornado, gthread, gaiohttp

同步模式 sync

Sync 模式 是 Gunicorn 的默认工作模式,也是最简单的一种模式。它的工作方式是 每个请求对应一个工作进程,进程接收一个请求后会一直等待,直到请求处理完成并返回响应,然后该进程才能继续处理下一个请求。

工作原理:

  1. 在 Sync 模式下,Gunicorn 为每个请求分配一个 worker 进程。
  2. 每个 worker 进程只能同时处理一个请求。
  3. 处理完请求后,worker 进程会再次等待新的请求进入。
  4. 由于每个进程只能处理一个请求,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 操作(如 socketssltime 等)替换为异步的非阻塞版本。这种替换通过 monkey patching 完成。Gevent 使用 greenlet(绿色线程)来调度协程,在遇到 I/O 操作时不会阻塞主线程,而是让其他任务先行执行,从而实现高效的并发处理。

工作流程:

  1. 协程创建:Gevent 使用 greenlet 创建协程,并使用 gevent.spawn() 启动任务。
  2. 事件循环:当一个协程遇到阻塞 I/O 操作时,Gevent 将该协程挂起,并将控制权交给事件循环,事件循环调度其他任务执行。
  3. I/O 复用:Gevent 通过 I/O 复用(例如 selectepoll)管理多个 I/O 操作,当某个 I/O 操作准备就绪时,Gevent 会再次恢复相应的协程。
  4. 并发处理:多个协程可以同时存在,且在 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 的场景:

  1. 需要长时间阻塞调用的应用,比如外部的web service
  2. 直接给internet提供服务
  3. stream流请求和响应
  4. 长轮询
  5. Web sockets(web sockets可以允许用户在浏览器中实现双向通信,实现数据的及时推送)
  6. 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


11-Gunicorn 配置
https://flepeng.github.io/021-Python-34-框架-Gunicorn-11-Gunicorn-配置/
作者
Lepeng
发布于
2024年9月20日
许可协议