python nginx+uwsgi+WSGI 处理请求详解

之前在写的这个文章莫名被删除了。幸好CSDN有备份
python nginx+uwsgi+WSGI 处理请求详解

uWSGI和WSGI的关系

那么如何实现uWSGI和WSGI的配合呢?如何做到任意一个web服务器,都能搭配任意一个框架呢?这就产生了WSGI协议。只要web服务器和web框架满足WSGI协议,它们就能相互搭配。所以WSGI只是一个协议,一个约定。而不是python的模块、框架等具体的功能。

而uWSGI,则是实现了WSGI协议的一个web服务器。即用来接受客户端请求,转发响应的程序。实际上,一个uWSGI的web服务器,再加上Django这样的web框架,就已经可以实现网站的功能了。那为什么还需要Nginx呢?

那么uWSGI 用在哪里?

WSGI是一种编程接口,而uwsgi是一种传输协议 , 类似fastuwsgi , 是跟nginx 沟通的

image.png

为什么需要Nginx

一个普通的个人网站,访问量不大的话,当然可以由uWSGI和Django构成。但是一旦访问量过大,客户端请求连接就要进行长时间的等待。这个时候就出来了分布式服务器,我们可以多来几台web服务器,都能处理请求。但是谁来分配客户端的请求连接和web服务器呢?Nginx就是这样一个管家的存在,由它来分配。这也就是由Nginx实现反向代理,即代理服务器。

给application 增加中间件

from wsgiref.simple_server import make_server

def application(environ, start_response):

    response_body = 'hello world!'

    status = '200 OK'

    response_headers = [
        ('Content-Type', 'text/plain'),
        ('Content-Length', str(len(response_body)))
    ]

    start_response(status, response_headers)
    return [response_body]

# 中间件
class Upperware:
   def __init__(self, app):
      self.wrapped_app = app

   def __call__(self, environ, start_response):
      for data in self.wrapped_app(environ, start_response):
        yield data.upper()

wrapped_app = Upperware(application)

httpd = make_server('localhost', 8051, wrapped_app)

httpd.serve_forever()

print 'end'

这里的Upperware 就是中间件,把app作为参数传进去,wrapped_app = Upperware(application)
因为实现了__call__()方法,可以 wrapped_app() 这样调用,然后注意,因为application() 执行完是返回可迭代对象的,可以是list、tuple、dict、set、str, 一般都是返回列表,比如上面的[response_body],
然后server 就会迭代这个对象,逐个读出。

那么问来来了, 如果我们需要对application()返回的对象全部大写,那么我们一般的做法是,遍历返回的对象,全部upper(), 再返回一次。

这样做法可以,但这样就变成了迭代两次了,一次是中间处理,一次是server的遍历。
而这个中间件实现方法很聪明的使用了生成器! 生成器也是可迭代对象。
wrapped_app() 执行完返回的是生成器,一整个生成器,还没启动遍历的生成器

而server这里拿到对象,再迭代,就既能只遍历一次,而且每次遍历过程中再upper了

参考:
好文:理解Python WSGI

你可能感兴趣的:(python nginx+uwsgi+WSGI 处理请求详解)