uWSGI与uwsgi协议_Lockey23的博客-CSDN博客_uwsgi协议
python nginx+uwsgi+WSGI 处理请求详解_码农富哥-CSDN博客_python uwsgi
python nginx+uwsgi+WSGI 处理请求详解 - 萌哥-爱学习 - 博客园
概念
- 图示
- WSGI协议
Web Server Gateway Interface,WSGI不是服务器,python模块,框架,API或者任何软件,只是一种规范,描述web server如何与web application通信的规范。server和application的规范在PEP 3333中有具体描述。要实现WSGI协议,必须同时实现web server和web application,当前运行在WSGI协议之上的web框架有Bottle, Flask, Django
WSGI定义了两种角色,分别为server端(或者gateway端)和application端(或者framework端),需要server端和application端都支持WSGI,一般而言server端是uWSGI,application端是一个可调用对象(callable object),可调用对象可以是类、方法或者可调用的实例,这个对象接受两个参数environ(请求的环境变量)和start_response(回调函数)。
environ是一个字典,包含了客户端请求的信息,如 HTTP 请求的首部,方法等信息,可以认为是请求上下文
start_response一个用于发送HTTP响应状态(HTTP status )、响应头(HTTP headers)的回调函数。在返回内容之前必须先调用这个回调函数- 本质
定义了一种server与application解耦的规范
可以有多个实现WSGI server的服务器,也可以有多个实现WSGI application的框架,那么就可以选择任意的server和application组合实现自己的web应用
uWSGI和Gunicorn都是实现了WSGI server协议的服务器,Django,Flask是实现了WSGI application协议的web框架 - 优点
多样的部署选择和组件之间的高度解耦——灵活性 - 组成
WSGI server负责从客户端接收请求,将request转发给application,将application返回的response返回给客户端;
WSGI application接收由server转发的request,处理请求,并将处理结果返回给server。application中可以包括多个栈式的中间件(middlewares),这些中间件需要同时实现server与application,因此可以在WSGI服务器与WSGI应用之间起调节作用:对服务器来说,中间件扮演应用程序,对应用程序来说,中间件扮演服务器。 - 操作
1、黑白名单规则防御
2、通过重写环境变量,根据目标URL,将请求消息路由到不同的应用对象—proxy
3、允许在一个进程中同时运行多个应用程序或应用框架
4、负载均衡和远程处理,通过在网络上转发请求和响应消息 - 实现过程
以Django为例,分析一下WSGI协议的具体实现过程- Django WSGI application
WSGI application应该实现为一个可调用对象,例如函数、方法、类(包含call方法)。需要接收两个参数:
一个字典,该字典可以包含了客户端请求的信息以及其他信息,可以认为是请求上下文,一般叫做environment(编码中多简写为environ、env)
一个用于发送HTTP响应状态(HTTP status )、响应头(HTTP headers)的回调函数
通过回调函数将响应状态和响应头返回给server,同时返回响应正文(response body),响应正文是可迭代的、并包含了多个字符串- 流程
加载所有中间件,以及执行框架相关的操作,设置当前线程脚本前缀,发送请求开始信号;
处理请求,调用get_response()方法处理当前请求,该方法的的主要逻辑是通过urlconf找到对应的view和callback,按顺序执行各种middleware和callback。
调用由server传入的start_response()方法将响应header与status返回给server。
返回响应正文- 代码
- 流程
- Django WSGI Server
负责获取http请求,将请求传递给WSGI application,由application处理请求后返回response
- Django WSGI application
- 本质
在启动时都会调用下面的run方法,创建一个WSGIServer的实例,之后再调用其serve_forever()方法启动服务
- 代码[印象笔记-简易server实现](https://app.yinxiang.com/shard/s62/nl/20661438/daecaad7-4fe3-427d-9bcc-528b56b0c92a/)
- uwsgi协议
与WSGI一样是一种通信协议,是uWSGI服务器的独占协议,用于定义传输信息的类型(type of information),每一个uwsgi packet前4byte为传输信息类型的描述,与WSGI协议是两种东西,据说该协议是fcgi协议的10倍快
uwsgi主要用在代理服务器(如Nginx)与uWSGI服务器之间的通信,而WSGI主要是用在uWSGI服务器和应用程序之间的通信 - uWSGI
一个web服务器,实现了WSGI协议、uwsgi协议、http协议等
旨在为部署分布式集群的网络应用开发一套完整的解决方案。主要面向web及其标准服务。由于其可扩展性,能够被无限制的扩展用来支持更多平台和语言。uWSGI是一个web服务器,实现了WSGI协议,uwsgi协议,http协议等
实现了基于uwsgi协议的server部分,我们只需要在uwsgi的配置文件中指定application的地址,uWSGI就能直接和应用框架中的WSGI application通信。- 特点
超快的性能
低内存占用
多app管理
详尽的日志功能(可以用来分析app的性能和瓶颈)
高度可定制(内存大小限制,服务一定次数后重启等) - 请求流程
首先nginx 是对外的服务接口,外部浏览器通过url访问nginx;
nginx 接收到浏览器发送过来的http请求,将包进行解析,分析url,如果是静态文件请求就直接访问用户给nginx配置的静态文件目录,直接返回用户请求的静态文件。如果不是静态文件,而是一个动态的请求,那么nginx就将请求转发给uWSGI,uWSGI接收到请求之后将包进行处理,处理成WSGI可以接受的格式,根据请求调用应用程序的某个文件,某个文件的某个函数,最后处理完将返回值再次交给uWSGI,uWSGI将返回值进行打包,打包成UWSGI能够接收的格式,并转发给nginx,nginx最终将返回值返回给浏览器. - 为什么需要Nginx而不是直接使用uWSGI
安全问题,程序不能直接被浏览器访问到,而是通过nginx,nginx只开放某个接口,uWSGI本身是内网接口,这样运维人员在nginx上加上安全性的限制,可以达到保护程序的作用
负载均衡问题,一个uWSGI很可能不够用,即使开了多个work也是不行,毕竟一台机器的cpu和内存都是有限的,有了nginx做代理,一个nginx可以代理多台uWSGI完成uWSGI的负载均衡
静态文件问题,用django或是uWSGI这种东西来负责静态文件的处理是很浪费的行为,而且他们本身对文件的处理也不如nginx好,所以整个静态文件的处理都直接由nginx完成,静态文件的访问完全不去经过uWSGI以及其后面的东西
- 特点
- 高并发配置优化
- 参考文档