wsgi 与 asgi
什么是wsgi
Web服务器网关接口(Python Web Server Gateway Interface,缩写为WSGI),是一套Web Server与APP之间的接口标准协议/规范,确保不同Web服务器可以和不同的Python程序之间相互通信。
Flask、Django属于APP的角色,都有内置自带的Web Server并遵守了wsgi(如app.run()
和python manage.py runserver
),但性能较差,只适用于本地调试或低并发场景。
实际生产场景中,通常各司其职,Flask/Django负责APP,Gunicorn/uswgi负责wsgi,Nginx负责Web Server

Gunicorn
相比于uswgi,Gunicorn更为轻量。Gunicorn采用master-worker模式,有一个master进程和多个worker进程,worker进程用于监听端口、处理请求,master进程用于管理worker进程。
通常worker数量建议为:cpu数 × 2 + 1,保证在任何时间,都有大概一半的worker是在做I/O,剩下一半才是需要CPU的。

三种常用worker并发模式
-
sync
用于CPU密集型(如图像处理),python由于GIL,并行的上限即CPU数。
默认模式,每个worker一次只处理一个请求,多余的需要排队
最大并发量即 workers -
gthread
使用多线程,可配置threads
属性。
最大并发量为 workers * threads,推荐该值也为:cpu数 × 2 + 1 -
gevent
用于IO密集型项目(如Web服务),使用前需要先安装pip install gevent
基于协程实现单线程异步。当请求等待db的IO时,能自动yield让出控制权给其他请求。
最大并发量为 workers × worker_connections
安装配置过程如下:
-
pip install gunicorn
安装gunicorn -
gunicorn -v
确认安装完成 -
启动gunicorn
可以通过gunicorn -help
查看各参数及其默认值- 通过命令行启动
gunicorn -w 进程数量 -b 监听地址:监听端口 入口实例 -D
-D
:后台运行
入口文件:module.path:attribute
格式,flask为app:app
或manage:app
,django为swallow.wsgi:application
- 通过配置文件启动
gunicorn -c gunicorn.conf.py swallow.wsgi:application
- 通过命令行启动
import os
import multiprocessing
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
LOG_DIR = os.path.join(BASE_DIR, "logs")
#chdir = '/home/flaskProject' # 工作目录,默认为当前命令行所在目录
bind = "0.0.0.0:8088" #ip+端口号
errorlog = os.path.join(LOG_DIR, 'gunicorn.log')
worker_class = "gevent" # worker进程模式,默认为sync。这里使用gevent
workers = multiprocessing.cpu_count() * 2 + 1 # worker进程数,默认为1,推荐为CPU个数*2 + 1。服务器上配置了多个服务时,数量相应减少。
# threads = 2 # 适用于gthread,每个worker处理请求的线程数,默认为1
forworded_allow_ips = '*' #信任IP来源 默认为'127.0.0.1'
worker_connections = 5000 #每个worker的最大并发量,默认1000。此设置将影响gevent工作模式
timeout = 60 # 超时后工作将会被杀死,并重启
graceful_timeout = 30 # 收到重启信号后,保留一段时间以处理未完成的工作。默认为30
keepalive = 5 #在keep-alive连接上等待请求的秒数,默认情况下值为2。一般设定在1~5秒之间
limit_request_line = 4094 # 限制HTTP请求头行数,默认为4094。值是0~8190的数字。
limit_request_fields = 1000 # 限制HTTP请求头字段数,默认为100。最大为32768
limit_request_field_size = 8190 # 限制HTTP请求头大小,默认为8190字节。为0则不限制。
max_requests = 0 # 重新启动之前,工作将处理的最大请求数。默认为0。
max_requests_jitter = 50 # 要添加到max_requests的最大抖动。抖动将导致每个工作的重启被随机化,这是为了避免所有工作被重启。
reload = True # 默认为False。监听应用程序改变时,自动重启
#daemon = True # 是否以守护进程启动,默认为False。使用了supervisor的情况下,无需自己守护进程。
通常将gunicorn添加到supervisor中,以实现自动重启等功能
什么是asgi
asgi是wsgi的扩展异步Python标准,比只能同步的wsgi性能更好,且可支持websocket,在 Django3+ 和 Flask2+ 中得到支持。
目前常用的asgi服务器包括:Uvicorn 、Daphne 、Hypercorn ,可通过接入swallow.asgi:application
调用