阅读此文前建议先阅读 个人博客html
gunicorn 是一个 python wsgi http server,只支持在 unix 系统上运行node
gunicorn 实际上是 python 的一个包,安装方法同通常包的安装python
pip install gunicorn
也可 tar 包安装nginx
安装完毕可用以下命令检测web
[root@node bin]# gunicorn -h
-h 就是 help,查看 gunicorn 命令的参数flask
-c CONFIG : CONFIG,配置文件的路径,经过配置文件启动;生产环境使用; -b ADDRESS : ADDRESS,ip加端口,绑定运行的主机; -w INT, --workers INT:用于处理工做进程的数量,为正整数,默认为1; -k STRTING, --worker-class STRTING:要使用的工做模式,默认为sync异步,能够下载eventlet和gevent并指定 --threads INT:处理请求的工做线程数,使用指定数量的线程运行每一个worker。为正整数,默认为1。 --worker-connections INT:最大客户端并发数量,默认状况下这个值为1000。 --backlog int:未决链接的最大数量,即等待服务的客户的数量。默认2048个,通常不修改; -p FILE, --pid FILE:设置pid文件的文件名,若是不设置将不会建立pid文件 --access-logfile FILE : 要写入的访问日志目录 --access-logformat STRING:要写入的访问日志格式 --error-logfile FILE, --log-file FILE : 要写入错误日志的文件目录。 --log-level LEVEL : 错误日志输出等级。 --limit-request-line INT : HTTP请求头的行数的最大大小,此参数用于限制HTTP请求行的容许大小,默认状况下,这个值为4094。值是0~8190的数字。 --limit-request-fields INT : 限制HTTP请求中请求头字段的数量。此字段用于限制请求头字段的数量以防止DDOS攻击,默认状况下,这个值为100,这个值不能超过32768 --limit-request-field-size INT : 限制HTTP请求中请求头的大小,默认状况下这个值为8190字节。值是一个整数或者0,当该值为0时,表示将对请求头大小不作限制 -t INT, --timeout INT:超过这么多秒后工做将被杀掉,并从新启动。通常设定为30秒; --daemon: 是否以守护进程启动,默认false; --chdir: 在加载应用程序以前切换目录; --graceful-timeout INT:默认状况下,这个值为30,在超时(从接收到重启信号开始)以后仍然活着的工做将被强行杀死;通常使用默认; --keep-alive INT:在keep-alive链接上等待请求的秒数,默认状况下值为2。通常设定在1~5秒之间。 --reload:默认为False。此设置用于开发,每当应用程序发生更改时,都会致使工做从新启动。 --spew:打印服务器执行过的每一条语句,默认False。此选择为原子性的,即要么所有打印,要么所有不打印; --check-config :显示如今的配置,默认值为False,即显示。 -e ENV, --env ENV: 设置环境变量;
gunicorn 有两种配置方式服务器
示例以下架构
gunicorn -w 8 -b 0.0.0.0:5002 simple_flask:app
simple_flask 是 flask 的主文件并发
app 是 主文件中那个 app flask 对象app
# gunicorn.conf # 并行工做进程数 workers = 4 # 指定每一个工做者的线程数 threads = 2 # 监听内网端口5000 bind = '127.0.0.1:5000' # 设置守护进程,将进程交给supervisor管理 daemon = 'false' # 工做模式协程 worker_class = 'gevent' # 设置最大并发量 worker_connections = 2000 # 设置进程文件目录 pidfile = '/var/run/gunicorn.pid' # 设置访问日志和错误信息日志路径 accesslog = '/var/log/gunicorn_acess.log' errorlog = '/var/log/gunicorn_error.log' # 设置日志记录水平 loglevel = 'warning'
启动 gunicorn
gunicorn -c gunicorn.conf app:app
flask 项目
from flask import Flask app = Flask(__name__) @app.route("/") def hello(): return "Hello, World!" if __name__ == '__main__': app.run(host='0.0.0.0')
对其进行压力测试,模拟 200 个用户发起 9000 个请求
ab -n 9000 -c 200 -r "http://172.16.89.80:5000/"
输出
Server Software: Werkzeug/0.16.0 Server Hostname: 172.16.89.80 Server Port: 5000 Document Path: / Document Length: 13 bytes Concurrency Level: 200 Time taken for tests: 13.862 seconds Complete requests: 9000 Failed requests: 0 Write errors: 0 Total transferred: 1503000 bytes HTML transferred: 117000 bytes Requests per second: 649.26 [#/sec] (mean) Time per request: 308.043 [ms] (mean) Time per request: 1.540 [ms] (mean, across all concurrent requests) Transfer rate: 105.89 [Kbytes/sec] received
Complete requests 9000 个请求;
Time taken for tests 共耗时 13.862 s;
Requests per second 每秒处理请求 649.26 个; 649.26 x 13.862 = 9000.04
注意 200 个用户(并发)并非说并发量是 200,由于一个用户可能 狂点,在一个 request-response 没结束以前,狂点屡次请求,这也是并发,因此上述输出代表 并发量 为 649
gunicorn -w 8 -b 0.0.0.0:5002 simple_flask:app
压力测试,一样模拟 200 个用户 发起 9000 个请求
/usr/bin/ab -n 9000 -c 200 -r -k 'http://172.16.89.80:5002/'
输出
Concurrency Level: 200 Time taken for tests: 1.998 seconds Complete requests: 9000 Failed requests: 0 Write errors: 0 Keep-Alive requests: 0 Total transferred: 1557000 bytes HTML transferred: 117000 bytes Requests per second: 4503.48 [#/sec] (mean) Time per request: 44.410 [ms] (mean) Time per request: 0.222 [ms] (mean, across all concurrent requests) Transfer rate: 760.84 [Kbytes/sec] received
类比上面来看本次输出,很明显,效率高;
并发量 4503,将近 8 倍
有意思的是咱们让 gunicorn 开了 8个 进程,因此能够这么理解, gunicorn 效率 = 单进程效率(自带服务器)x 进程数
固然 这也要跟 硬件 有关系,若是你只是 8 核 的服务器,开了 80 个进程,就不能这么算了
用 gevent 并发量更大
gunicorn -k gevent -w 8 -b 0.0.0.0:5002 simple_flask:app
并发量 4890。
测试样例仍是上面那个 flask 项目
这里只作简单分析,由于测试时跟硬件有必定关系
gunicorn 性能
Concurrency Level: 10000 Time taken for tests: 25.494 seconds Complete requests: 100000 Failed requests: 292 (Connect: 0, Receive: 88, Length: 116, Exceptions: 88) Write errors: 0 Total transferred: 17279932 bytes HTML transferred: 1298492 bytes Requests per second: 3922.52 [#/sec] (mean) Time per request: 2549.384 [ms] (mean) Time per request: 0.255 [ms] (mean, across all concurrent requests) Transfer rate: 661.92 [Kbytes/sec] received
失败 292 次请求,并发 3922
nginx 性能
Concurrency Level: 10000 Time taken for tests: 26.333 seconds Complete requests: 100000 Failed requests: 42 (Connect: 0, Receive: 0, Length: 42, Exceptions: 0) Write errors: 0 Total transferred: 17292734 bytes HTML transferred: 1299454 bytes Requests per second: 3797.45 [#/sec] (mean) Time per request: 2633.344 [ms] (mean) Time per request: 0.263 [ms] (mean, across all concurrent requests) Transfer rate: 641.29 [Kbytes/sec] received
失败 42 次请求,并发 3797
nginx 性能不差,重要的是稳定。
参考资料:
https://www.cnblogs.com/cwp-bg/p/8780204.html python之gunicorn的配置
https://blog.csdn.net/y472360651/article/details/78538188 Gunicorn-配置详解
https://www.jianshu.com/p/69e75fc3e08e gunicorn 详解
https://blog.csdn.net/bbwangj/article/details/82684573 gunicorn简介、架构、安装与配置
https://www.jianshu.com/p/b97f80a630db
https://blog.51cto.com/7613336/2074032 优雅的退出/关闭/重启gunicorn进程