• Django之WSGI浅谈


    一、什么是Web框架

    框架,即framework,特指为解决一个开放性问题而设计的具有一定约束性的支撑结构,使用框架可以帮你快速开发特定的系统。

    浏览器与服务器之间发起HTTP请求:

    1.浏览器发送一个HTTP请求;
    2.服务器收到请求,生成一个HTML文档;
    3.服务器把HTML文档作为HTTP响应的Body发送给浏览器;
    4.浏览器收到HTTP响应,从HTTP Body取出HTML文档并显示。
    

    对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端。

    import socket
    
    def handle_request(client):
    
        buf = client.recv(1024)
        client.send("HTTP/1.1 200 OK
    
    ".encode("utf8"))
        client.send("<h1 style='color:red'>Hello, yuan</h1>".encode("utf8"))
    
    def main():
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.bind(('localhost',8001))
        sock.listen(5)
    
        while True:
            connection, address = sock.accept()
            handle_request(connection)
            connection.close()
    
    if __name__ == '__main__':
    
        main()
    View Code

    接受HTTP请求、解析HTTP请求、发送HTTP响应都是底层的东西,如果要研究这些底层那得花上一定的时间。因此我们不希望接触到TCP连接、HTTP原始请求和响应格式,所以,需要一个统一的接口,让我们专心用Python编写Web业务。
    这个接口就是WSGI:Web Server Gateway Interface。

    二、WSGI

    Python Web Server Gateway Interface,翻译过来时Python web服务器网关接口,实际上就是一种协议,我们的应用(Django,Flask)实现了WSGI,就可以配合实现了WSGI(uWSGI,gunicorn)的服务器工作了。
    以下是结构图:

    两级结构

    在这种结构里,uWSGI作为服务器,它用到了HTTP协议以及wsgi协议,flask应用作为application,实现了wsgi协议。当有客户端发来请求,uWSGI接受请求,调用flask app得到相应,之后相应给客户端。
    这里说一点,通常来说,Flask等web框架会自己附带一个wsgi服务器(这就是flask应用可以直接启动的原因),但是这只是在开发阶段用到的,在生产环境是不够用的,所以用到了uwsgi这个性能高的wsgi服务器。

    三级结构

    这种结构里,uWSGI作为中间件,它用到了uwsgi协议(与nginx通信),wsgi协议(调用Flask app)。当有客户端发来请求,nginx先做处理(静态资源是nginx的强项),无法处理的请求(uWSGI),最后的相应也是nginx回复给客户端的。


    多了一层反向代理有什么好处?

    提高web server性能(uWSGI处理静态资源不如nginx;nginx会在收到一个完整的http请求后再转发给wWSGI)
    nginx可以做负载均衡(前提是有多个服务器)
    保护了实际的web服务器(客户端是和nginx交互而不是uWSGI)

    示例1:

    from wsgiref.simple_server import make_server
    
    def application(environ, start_response):
        start_response('200 OK', [('Content-Type', 'text/html')])
        return [b'<h1>Hello, web!</h1>']
    
    httpd = make_server('', 8080, application)
    
    print('Serving HTTP on port 8080...')
    # 开始监听HTTP请求:
    httpd.serve_forever()
    test1.py

    浏览器效果:

    注意:
    ①整个application()函数本身没有涉及到任何解析HTTP的部分,也就是说,底层代码不需要我们自己编写,我们只负责在更高层次上考虑如何响应请求就可以了。
    ②Python内置了一个WSGI服务器,这个模块叫wsgiref
    ③application()函数就是符合WSGI标准的一个HTTP处理函数,它接收两个参数:
        //environ:一个包含所有HTTP请求信息的dict对象;
        //start_response:一个发送HTTP响应的函数。

    ④在application()函数中,调用:
    start_response('200 OK', [('Content-Type', 'text/html')])
    就发送了HTTP响应的Header,注意Header只能发送一次,也就是只能调用一次start_response()函数。
    start_response()函数接收两个参数,一个是HTTP响应码,一个是一组list表示的HTTP Header,每个Header用一个包含两个str的tuple表示。
    通常情况下,都应该把Content-Type头发送给浏览器。其他很多常用的HTTP Header也应该发送。
    ⑤最后,函数的返回值b'<h1>Hello, web!</h1>'将作为HTTP响应的Body发送给浏览器。

    示例2:

    调用本身的HTML响应给浏览器

    from wsgiref.simple_server import make_server
    
    
    def application(environ, start_response):
        # start_response('200 OK', [('Content-Type', 'text/html')])
    
        print(environ['PATH_INFO'])
        path = environ['PATH_INFO']
        start_response('200 OK', [('Content-Type', 'text/html')])
        f1 = open("index1.html", "rb")
        data1 = f1.read()
        f2 = open("index2.html", "rb")
        data2 = f2.read()
    
        if path == "/test1":
            return [data1]
        elif path == "/test2":
            return [data2]
        else:
            return ["<h1>404</h1>".encode('utf8')]
    
    
        return [b'<h1>Hello, web!</h1>']
    
    
    httpd = make_server('', 8080, application)
    
    print('Serving HTTP on port 8080...')
    # 开始监听HTTP请求:
    httpd.serve_forever()
    test2.py

     

     

  • 相关阅读:
    C# GDI+ 文字 阴影,描边 的实现
    NDatabase 入门,简单使用 增删改查。让NDatabase带你脱离ADO.net,各种SQL 语句,各种DBMS,各种CRM,IOC之类的烦恼。我们也不需要仓库设计模式了,你妹的。不要表了,不要设计数据库字段了。就这样!
    D3D 光和材质
    DirectX D3D texture 的Level,解释。。。。
    学习openssl中的hash算法
    ubuntu下使用魅族mx真机调试android程序
    boost 获取时间并格式化
    Mysql:The table‘xxxx’is full
    使用pmap查看进程占用的内存情况
    编译antrl c runtime 3.5步骤
  • 原文地址:https://www.cnblogs.com/ray-h/p/10513924.html
Copyright © 2020-2023  润新知