加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

gunicorn

发布时间:2020-12-20 10:49:49 所属栏目:Python 来源:网络整理
导读:?gunicorn? 1.????? 简介 官网:https://gunicorn.org/#docs Gunicorn ‘Green Unicorn‘ is a Python WSGI HTTP Server for UNIX. It‘s a pre-fork worker model. The Gunicorn server is broadly compatible with various web frameworks,simply implemen

?gunicorn?

1.????? 简介

官网:https://gunicorn.org/#docs

Gunicorn ‘Green Unicorn‘ is a Python WSGI HTTP Server for UNIX. It‘s a pre-fork worker model. The Gunicorn server is broadly compatible with various web frameworks,simply implemented,light on server resources,and fairly speedy.

它是一个pythonWSGI HTTP Server,运行于UNIX平台。pre-fork worker model。

?

Gunicorn是一个unix上被广泛使用的高性能的Python WSGI UNIX HTTP Server。

和大多数的web框架兼容,并具有实现简单,轻量级,高性能等特点。

?

1.1.??? 相关概念

架构

服务模型(Server Model)

Gunicorn是基于pre-fork模型的。也就意味着有一个中心管理进程(masterprocess)用来管理worker进程集合。Master从不知道任何关于客户端的信息。所有的请求和响应处理都是由worker进程来处理的。

Master(管理者)

主程序是一个简单的循环,监听各种信号以及相应的响应进程。master管理着正在运行的worker集合,通过监听各种信号比如TTIN,TTOU,andCHLD.TTINandTTOU响应的增加和减少worker的数目。CHLD信号表明一个子进程已经结束了,在这种情况下master会自动的重启失败的worker。

worker

woker有很多种,包括:ggevent、geventlet、gtornado等等。这里主要分析ggevent。

每个ggeventworker启动的时候会启动多个server对象:worker首先为每个listener创建一个server对象(注:为什么是一组listener,因为gunicorn可以绑定一组地址,每个地址对于一个listener),每个server对象都有运行在一个单独的geventpool对象中。真正等待链接和处理链接的操作是在server对象中进行的。

?

1.2.??? gunicorn安装

pip install gunicorn

?

示例:

wsgi_my.py

#!/usr/bin/env python

# -*- coding: utf-8 -*-

from app import create_app

application = app = create_app()

?

1.2.1.?? 测试运行

gunicorn wsgi_my:app

默认绑定127.0.0.1,所以不能在其它ip访问

测试结果:

[[email?protected] ~]# curl http://localhost:8000

Index.

[[email?protected] ~]# curl http://localhost:8000/hello

Hello. number: 1

[[email?protected] ~]# curl http://localhost:8000/hello

Hello. number: 2

?

1.3.??? 使用及配置

?

doc: https://docs.gunicorn.org/en/stable/run.html

gunicorn

最简单的运行方式:gunicorn code:application

?

Gunicorn从三个不同地方获取配置:

框架设置(通常只影响到Paster应用)

配置文件(python文件):配置文件中的配置会覆盖框架的设置。

命令行

框架设置只跟Paster(一个Web框架)有关,不讨论;命令行配置如上部分所示;

?

1.3.1.?? 命令行常用配置参数:

-c CONFIG,--config=CONFIG - Specify a config file in the form $(PATH),file:$(PATH),or python:$(MODULE_NAME).指定配置文件

-b BIND,--bind=BIND - Specify a server socket to bind. Server sockets can be any of $(HOST),$(HOST):$(PORT)指定监听端口.

-w WORKERS,--workers=WORKERS - The number of worker processes. This number should generally be between 2-4 workers per core in the server. Check the FAQ for ideas on tuning this parameter.指定进程数,一般建议数量设置为2*CPU+1

-k WORKERCLASS,--worker-class=WORKERCLASS - The type of worker process to run. You’ll definitely want to read the production page for the implications of this parameter. You can set this to $(NAME) where $(NAME) is one of sync,eventlet,gevent,tornado,gthread,gaiohttp (deprecated). sync is the default. See the worker_class documentation for more information.

工作模式,有多种,默认sync,一般gevent,tornado。

?

--backlog INT 指定最大挂起的连接数;

--log-level LEVEL:debug,info,warning,error,critical

--access-logfile FILE 日志文件,-表示输出到标准输出

--error-logfile FILE 错误日志文件

典型启动命令:

gunicorn -w 1 -k gevent wsgi_my? -b 0.0.0.0:9000

?

1.3.2.?? 配置文件启动

生产中通常通过配置文件指定参数,它必须是一个python文件,只是将命令行中的参数写进py文件中而已,如果需要设置哪个参数,则在py文件中为该参数赋值即可。

配置文件案例:

#!/usr/bin/env python

# -*- coding: utf-8 -*-

?# gunicorn 配置文件

?import multiprocessing

?

debug = True

loglevel = ‘debug‘

bind = "0.0.0.0:9000"

# 最大挂起连接数

backlog = 512

?

# 日志

pidfile = "log/gunicorn.pid"

accesslog = "log/access.log"

errorlog = "log/debug.log"

#daemon = True

daemon = False

?

?

# 启动的进程数

workers = multiprocessing.cpu_count()

worker_class = ‘gevent‘

# 进程沉默限制时间,超过会重启该worker,单位秒,通常设为30

timeout = 30

?

x_forwarded_for_header = ‘X-FORWARDED-FOR‘

?

启动server

gunicorn -c gunicorn_conf.py wsgi_my:app

注意:指定app时不要有后缀名(例如wsgi_my.py),否则会找不到app

日志文件需要手动创建

?

2.????? 测试

2.1.??? 并发模式测试1-验证可用性

测试环境准备:

  1. 在路由函数中添加阻塞代码time.sleep(2)
  2. 请求使用deferred模拟并发,具体代码见下文;

?

flask自带server及uWSGI是不支持并发的;

直接运行app:python run.py

测试结果:

测试并发请求数:5 测试耗时:10.08759880065918

?

使用gvent模式

[[email?protected] website]# gunicorn -w 1 -k gevent wsgi_my? -b 0.0.0.0:9000

测试并发请求数:5 测试耗时:2.1450159549713135

?

结果释义:

阻塞模式下不能同时处理多个请求,所以耗时为2*5,最终大约为10;

协程模式下可以同时处理多个请求,所以耗时为2*1,最终大约为2;

?

2.1.1.?? 并发测试代码

import time
from twisted.internet import defer,reactor
from twisted.web.client import getPage

# 测试url
url = b"http://192.168.199.129:9000/hello"

def time_count(*args,**kw):
??? print(测试结束。‘)
??? t = time.time()
??? print("测试并发请求数:{} 测试耗时:{}".format(kw[‘req_nums‘],t - kw[‘t_start‘]))

t_start = time.time()
d = defer.DeferredList([getPage(url) for x in range(5)])
#d = getPage(url)
d.addCallbacks(time_count,lambda x:print(‘error‘),callbackKeywords={‘req_nums‘:5,‘t_start‘:t_start})
?

reactor.callLater(20,reactor.stop)

reactor.run()

?

2.2.??? 性能测试

主要测试flask+ gunicorn与werkzurg的性能。

?

2.2.1.?? python自带web server

E:Apache24bin>ab -n 3000 -c 50 http://192.168.199.129:9000/req_test

This is ApacheBench,Version 2.3 <$Revision: 1843412 $>

?

Benchmarking 192.168.199.129 (be patient)

Completed 3000 requests

Finished 3000 requests

?

Server Software:??????? Werkzeug/0.14.1

Server Hostname:??????? 192.168.199.129

Server Port:??????????? 9000

?

Document Path:????????? /req_test

Document Length:??????? 27 bytes

?

Concurrency Level:????? 50

Time taken for tests:?? 27.518 seconds

Complete requests:????? 3000

Failed requests:??????? 2951

?? (Connect: 0,Receive: 0,Length: 2951,Exceptions: 0)

Total transferred:????? 548002 bytes

HTML transferred:?????? 86002 bytes

Requests per second:??? 109.02 [#/sec] (mean)

Time per request:?????? 458.632 [ms] (mean)

Time per request:?????? 9.173 [ms] (mean,across all concurrent requests)

Transfer rate:????????? 19.45 [Kbytes/sec] received

?

Connection Times (ms)

????????????? min? mean[+/-sd] median?? max

Connect:??????? 0??? 1?? 3.0????? 1????? 73

Processing:??? 35? 454? 72.2??? 429???? 683

Waiting:?? ?????4? 453? 72.1??? 427???? 680

Total:???????? 35? 455? 72.4??? 430???? 684

?

Percentage of the requests served within a certain time (ms)

? 50%??? 430

? 66%??? 457

? 75%??? 499

? 80%??? 518

? 90%??? 569

? 95%??? 592

? 98%??? 613

? 99%??? 628

?100%??? 684 (longest request)

?

2.2.2.?? gunicorn gevent模式

gunicorn -w 1 -k gevent wsgi_my? -b 0.0.0.0:9000

E:Apache24bin>ab -n 3000 -c 50 http://192.168.199.129:9000/req_test

This is ApacheBench,Version 2.3 <$Revision: 1843412 $>

Copyright 1996 Adam Twiss,Zeus Technology Ltd,http://www.zeustech.net/

Licensed to The Apache Software Foundation,http://www.apache.org/

?

Benchmarking 192.168.199.129 (be patient)

Finished 3000 requests

?

Concurrency Level:????? 50

Time taken for tests:?? 10.541 seconds

Complete requests:????? 3000

Failed requests:??????? 2991

?? (Connect: 0,Length: 2991,Exceptions: 0)

Total transferred:????? 565893 bytes

HTML transferred:?????? 85893 bytes

Requests per second:??? 284.60 [#/sec] (mean)

Time per request:?????? 175.688 [ms] (mean)

Time per request:?????? 3.514 [ms] (mean,across all concurrent requests)

Transfer rate:????????? 52.43 [Kbytes/sec] received

?

Connection Times (ms)

????????????? min? mean[+/-sd] median?? max

Connect:??????? 0??? 1?? 0.4????? 1?????? 3

Processing:??? 32? 174? 16.6??? 171???? 277

Waiting:??????? 2? 173? 16.7??? 170???? 277

Total:???????? 32? 174? 16.6??? 172???? 278

?

Percentage of the requests served within a certain time (ms)

? 50%??? 172

? 66%??? 174

? 75%??? 176

? 80%??? 177

? 90%??? 184

? 95%??? 190

? 98%??? 217

? 99%??? 276

?100%??? 278 (longest request)

?

2.2.3.?? 测试结果解析

?

无论是从任务总时长,单个任务耗时各项指标上看,gevent模式是大大优于同步阻塞模式的。至于说具体优化比例要取决于各项因素了,这里的实验环境只是一台虚拟机,不具有实际应用意义。

?

3.????? 总结

常用命令

gunicorn -w 1 -k gevent wsgi_my? -b 0.0.0.0:9000

gunicorn -c gunicorn_conf.py wsgi_my

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读