Python服务部署 Flask/Django + uWSGI/Gunicorn

一. flask、django项目不推荐使用自带run/runserver方法部署

  • run/runserver方式是flask/django调试模式,使用的是自带WSGI服务器运行,开启的方式为单进程,性能低
  • flask的run方法默认开启方式是单进程且单线程,通过设置threaded=True可开启多线程,设置processes=10可开启多进程,但多进程和多线程不能同时开启,且需要关闭debug模式,且设置多进程在windows系统下不支持
  • 在官方描述中也声明,flask/django自带的server只能用于开发调试,并不适合用于生产环境
  • 推荐使用专业的web server进行部署,如:uWSGI、Gunicorn,本质原因是uWSGI、Gunicorn在配置:多线程可以绕过IO阻塞 + 多进程充分利用多核

二. Web服务器、WSGI、Flask/Django框架关系

1. WSGI简介

WSGI(Web Server Gateway Interface),既不是服务器,也不是应用,而是一种接口(规范),描述web server如何与web application通信的规范:

1. 服务器的请求处理要调用符合WSGI规范的网关接口;
2. 由网关接口来调用应用程序,并且其要定义start_response(status, headers)函数,用于返回响应;
3. 应用程序须是一个可调用对象(函数/类),webapp(environ, start_response)。接受两个参数,environ是环境设置的字典,由服务器和WSGI网关接口设置,start_response是由网关接口定义的函数。
  • web server:实现了WSGI server协议的服务器,如uWSGI、Gunicorn
  • Gateway Interface:网关接口,如CGI、WSGI
  • application:实现了WSGI application协议的框架,如Django、Flask

网络通信的完整流程:

先创建一个web服务器,监听端口,接收请求,并将请求路由转发给对应的应用程序。
再创建一个web应用程序,用于接收到请求,经过必要的处理,返回响应给服务器。
服务器接收响应,返回给客户端(浏览器)

WSGI 只适用于 Python 语言,定义了 web服务器和 web应用之间的接口规范。解耦了服务器类与应用程序类,只要 web服务器和 web应用都遵守WSGI协议,那么 web服务器和 web应用就可以随意的组合

2. Application实现

WSGI规范规定,Application 必须是一个可调用的对象,它可以是函数,可以实现了__call__的类的实例对象,也可以是实现了__iter__的类对象。

不管是哪种方式的可调用对象,都要遵循两个原则:
  1. 必须接收environ(WSGI环境信息), start_response(响应请求函数)两个参数;(这两个参数都由Web Server来定义的)
  2. 必须返回可迭代的对象。
  • 其中传入的start_response方法接收两个参数:
    1. status:HTTP状态,譬如:“200 OK”
    2. response_headers:响应消息的头,譬如:[(‘Content-Type’, ‘text/plain’)],以list的形式,每个元素是一个tuple,而每一个tuple里有两个元素,key和value
同理,Web Server也必须实现这两个对象,定义完成后,要调用application,将两个参数传入
3. Web框架层协议体现

Web框架的作用主要是方便我们开发 web应用程序,也遵循WSGI协议,以flask为例,遵循WSGI协议体现的源码:

class Flask(_PackageBoundObject):
    .....
    def wsgi_app(self, environ, start_response):
        ctx = self.request_context(environ)
        error = None
        try:
            try:
                ctx.push()
                response = self.full_dispatch_request()
            except Exception as e:
                error = e
                response = self.handle_exception(e)
            except:
                error = sys.exc_info()[1]
                raise
            return response(environ, start_response)
        finally:
            if self.should_ignore_error(error):
                error = None
            ctx.auto_pop(error)

    def __call__(self, environ, start_response):
         return self.wsgi_app(environ, start_response)
    ...

在Flask中处理请求的入口__call__方法, 又调用了另一个方法wsgi_app,所有的请求将会在这几行代码中处理完成, 并且最终返回

  • 补充:在Web Server和应用之间还存在中间件middleware,中间件也必须满足两方的WSGI协议
4. uwsgi协议、uWSGI服务器
  • uwsgi同wsgi 一样也是一种协议,uWSGI服务器正是使用了 uwsgi 协议
  • uWSGI实现了 uwsgi 和 WSGI 两种协议的web服务器。注意 uWSGI 本质上也是一种 web服务器,处于上面描述的三层结构中的Web Server层。
三. Gunicorn
1. 简介
  • gunicorn-绿色独角兽,python的WSGI HTTP Server,WSGI的实现,同时也自带Web Server,能直接对外提供web服务。既支持eventlet也支持greenlet。
  • 只支持在Unix系统上运行,所在位置通常在反向代理(如:Nginx)和一个Web应用(如Flask)之间
2. Gunicorn工作模式
  • gunicorn支持使用不同的worker进程类型,可通过worker-class参数配置。
    启动后,gunicorn的所有worker共用一组listener(Gunicorn支持绑定多个socket,所以说是一组)。在启动worker时,worker内为每个listener创建一个WSGI server,接收HTTP请求,并调用app对象去处理请求。
  • Gunicorn启动项目后会有一个主进程Master和一个或多个工作进程。工作进程的数量可以指定。工作进程是实际处理请求的进程。主进程维护服务器的运行
  • gunicorn的工作模式一般分为同步worker使用和异步worker使用(默认是异步,异步worker有Gevent和Eventlet两种,都是基于Greenlet实现的),例如在单核机器上运行的gevent:
gunicorn --worker-class=gevent --worker-connections=1000 --workers=3 main:app

worker-connection 是对于 gevent worker 类的特殊设置。(2CPU)+1 是建议的worker数量。因为这里是单核,我们设置的是3个worker。在这种情况下,最大的并发请求数是3000(3个worker1000个连接数/worker)

3. Gunicorn实现高并发
  • Gunicorn在启动时就已经把worker进程预先fork出来了,当多个请求到来的时候,会轮流复用这些worker进程,从而提高服务器并发负载能力
  • 对于worker数量配置,推荐2CPU数+1;这样在任何时间,都有大概一半worker在做I/O,剩下一半才是需要CPU的;如果在开多进程的同时,也开多线程(即选择gthread类型的worker),那么,配置总的并发数(worker进程线程数),仍然建议2CPU数+1
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值