首页 Gunicorn简介
文章
取消

Gunicorn简介

背景

  虽然之前也写了些python代码,但是都是脚本,并没有做过web项目,所以对web项目部署了解的很少。而这次使用Django开发了一个web系统,部署的时候用到Gunicorn,使用过程中还遇到了一些问题,通过反复测试才找到问题的原因。这里做一下记录。

介绍

  Gunicorn 是一个 Python 的 WSGI(Web Server Gateway Interface) HTTP 服务器。它所在的位置通常是在反向代理(如 Nginx)或者 负载均衡(如 AWS ELB)和一个 web 应用(比如 Django 或者 Flask)之间。它是一个移植自Ruby的Unicorn项目的pre-fork worker模型,即支持eventlet也支持greenlet。Gunicorn启动项目之后一定会有一个主进程Master和一个或者多个工作进程。工作进程的数量可以指定。工作进程是实际处理请求的进程。主进程维护服务器的运行。

  Gunicorn 是通过工作进程来实际处理请求的,Gunicorn 启动的时候会启动一个主进程来维护服务器的运行,包括端口监听等。然后会启动多个工作进程来处理请求,这些工作进程是实际处理请求的进程。每一个进程都是独立的。还可以通过多线程的方式提高处理请求的效率。

Gunicorn

特点

  • 简单:Gunicorn 的配置相对简单,易于使用。

  • 预分叉模型:Gunicorn 使用预分叉模型来处理请求,这意味着它在启动时创建一组 worker 进程,每个进程处理一个请求。

  • 可伸缩性:可以通过增加 worker 进程的数量来提高并发处理能力。

  • 稳定性:Gunicorn 相对稳定,适用于大多数生产环境。

  • 轻量级:Gunicorn 是轻量级的,不需要额外的依赖项。

  • 同步 worker:默认情况下,Gunicorn 使用同步 worker,但在高并发场景下可以使用 gevent 或 gthread worker 来提高性能。

安装

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
# 安装最新版本的gunicorn
pip install gunicorn


# 下面这些涉及到 worker 模式,可以选择使用

# 如果需要异步worker需要安装这些
pip install greenlet            # Required for both
pip install eventlet            # For eventlet workers
pip install gunicorn[eventlet]  # Or, using extra
pip install gevent              # For gevent workers
pip install gunicorn[gevent]    # Or, using extra

# 或者安装下面扩展
pip install gunicorn[eventlet] - Eventlet-based greenlets workers
pip install gunicorn[gevent] - Gevent-based greenlets workers
pip install gunicorn[gthread] - Threaded workers
pip install gunicorn[tornado] - Tornado-based workers, not recommended
pip install gunicorn[setproctitle]- 允许设置进程名称

# 可以组合
pip install gunicorn[gevent,setproctitle]

# 启动
gunicorn -w 10 --threads 5 --worker-class gthread -b 127.0.0.1:8000 app.wsgi

# 重启
kill -HUP gunicorn的pid

模式

  Gunicorn 的命令行-k STRING或者–worker-class STRING 默认的工作模式是sync,即同步的工作模式。 一共有五种工作模式,分别是 sync, eventlet, gevent, tornado, gthread 。 下面就分别介绍下这些工作模式。

  • sync 模式(同步工作模式): 这是最基本的工作模式,也是默认的工作模式,线程为native类型。即请求先来后到,排队模式。

  • eventlet 模式(协程异步): eventlet 工作模式是基于eventlet库,利用python协程实现的。要使用该工作模式的话必须先安装eventlet库,安装命令是:pip install eventlet pipinstall gunicorn[eventlet]

  • gevent模式(协程异步): gevent是基于Greentlet库,利用python协程实现的。 安装命令是:pip install geventpip install gunicorn[gevent] Gunicorn允许通过设置对应的worker类来使用这些异步Python库。这里的设置适用于我们想要在单核机器上运行的gevent:

1
gunicorn --worker-class=gevent -w 2  app.wsgi
  • tornado模式: tornado利用python Tornado框架来实现。安装命令是:pip install tornadopip install gunicorn[tornado] 安装的tornado库的版本要大于等于0.2。

  • gthread模式: gthread采用的是线程工作模式,利用线程池管理连接,需要安装gthread库。 安装命令是:pip install gthreadpip install gunicorn[gthread]。 Gunicorn允许每个worker拥有多个线程。在这种场景下,Python应用程序每个worker都会加载一次,同一个worker生成的每个线程共享相同的内存空间。为了在 Gunicorn 中使用多线程。我们使用了 gthreads 模式,指定threads参数。

工作模式的补充说明

  当worker指定为gevent或者evenlet类型时,线程变成基于Greentlet的task(伪线程),这时候线程数量threads参数是无效的。

  使用gevent模式会出现一些兼容性问题。使用gevent时,系统会使用monkey patch。系统的部分函数会被修改, 有些库会兼容gevent的类型, 例如,任务调度的库apscheduler,web socket需要socketio的库等,需要专门选择gevent的函数。 而有些库则直接无法使用,例如多进程multiprocess。 例如,在一个api请求中,如果需要使用多核cpu资源,采用multiprocess进行多进程计算。则会出现卡死的问题。gevent中,不能使用multiprocess库。

常用参数

  Gunicorn可以使用命令行参数也可以使用配置文件。

命令行

  Gunicorn支持多种配置参数,可以使用 gunicorn --help 查看,可以通过命令行或配置文件进行设置。以下是一些常用的配置参数:

  • workers(w):工作进程数,通常设置为CPU核心数的2-4倍。

  • threads:每个工作进程的线程数,当需要处理大量IO阻塞任务时可以增加线程数。

  • worker-class:worker运行模式。

  • bind(b):绑定地址和端口,例如127.0.0.1:8000。

  • timeout(t):请求超时时间,单位为秒。

  • access-logfile:访问日志文件路径。

  • error-logfile:错误日志文件路径。

  • log-level:日志级别。

  • config(c):配置文件。

1
2
3
# 命令行
gunicorn -w 10 --threads 5 --worker-class gthread -b 127.0.0.1:8000 app.wsgi

配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# gunicorn_config.py
import multiprocessing

bind = '0.0.0.0:8000'
workers = multiprocessing.cpu_count() * 2 + 1
workers = 2
backlog = 2048
worker_class = "gevent"
worker_connections = 1000
threads = 2
daemon = False
debug = True
proc_name = 'gunicorn_demo'
pidfile = './log/gunicorn.pid'
errorlog = './log/gunicorn.log'

1
2
# 使用配置文件
gunicorn -c gunicorn_config.py app.wsgi

使用中的问题

  • 使用 Gunicorn 的时候,用空 Django 项目测试,使用 ps -efL|grep gunicorn 或者 pstree -p 线程pid 查看线程,发现没有,只有worker进程,开始以为 ```–threads 10`` 参数没有生效,后来才知道,只有访问的时候才会根据访问创建。

  • 使用 Gunicorn 部署 Django 的时候,发现不光创建了worker进程,还创建了和 CPU 数相同的线程,这个和上面现象不一致,后来发现是因为使用了 Celery 和 lancedb。

参考资料

1、Gunicorn 23.0.0 documentation

2、Gunicorn 23.0.0 documentation » Settings

3、gunicorn使用

本文由作者按照 CC BY 4.0 进行授权

Server-Sent Events

Celery-分布式任务队列