wsgiref模块是python提供的,用于测试和学习的简单的WSGI服务器模块。
这个模块监听8000端口(监听端口能够改变),把Http请求,根据WSGI协议,转换application函数中的environ参数,而后调用application函数。
wsgiref会把application函数提供的响应头设置转换为HTTP协议的响应头,把application的返回(return)做为响应体,根据HTTP协议,生成响应,返回给浏览器。php
- WSGI
- uWSGI
- uwsgi
- Nginx html
浏览器发起请求,都是请求80端口python
WSGI 是一种协议,不是任何包不是任何服务器,就和 TCP 协议同样。它定义了 Web 服务器和 Web 应用程序以前如何通讯的规范。
至于为何和 Python 扯在一块儿?由于这个协议是由 Python 在 2003 年提出的。(参考:PEP-333 和 PEP-3333 )
> WSGI is the Web Server Gateway Interface. It is a specification that describes how a web server communicates with web applications, and how web applications can be chained together to process one request.
uWSGI 是一个全功能的 HTTP 服务器,他要作的就是把 HTTP 协议转化成语言支持的网络协议。好比把 HTTP 协议转化成 WSGI 协议,让 Python 能够直接使用。
> The uWSGI project aims at developing a full stack for building hosting services.
>
> Application servers (for various programming languages and protocols), proxies, process managers and monitors are all implemented using a common api and a common configuration style.
uwsgi 是一种 uWSGI 的内部协议,使用二进制方式和其余应用程序进行通讯。
> The uwsgi (lowercase!) protocol is the native protocol used by the uWSGI server.
>
> It is a binary protocol that can carry any type of data. The first 4 bytes of a uwsgi packet describe the type of the data contained by the packet.
Nginx 是一个 Web 服务器其中的 HTTP 服务器功能和 uWSGI 功能很相似,可是 Nginx 还能够用做更多用途,好比最经常使用的反向代理功能。
因此用一张图来描述一下这个过程: nginx
不少框架和应用服务器均可以对静态文件的请求(如JavaScript、CSS、图片等)返回来自应用的响应,不过更好的作法是用反向代理服务器(好比Nginx)来处理此类请求,减轻应用服务器的负载,得到更好的性能。web
随着应用扩大,可能会须要分布到不一样的服务器(云主机)上,此类需求在早期能够用反向代理实现。apache
此外,Nginx的可扩展性(除了缓存以外,还有failover等其余机制)对于一些比较复杂的Web应用也颇有帮助。django
一个简单的服务器架构:编程
客户端请求 ----> Nginx (反向代理) | /|\ | | `-> App. Server I. 127.0.0.1:8081 | `--> App. Server II. 127.0.0.1:8082 `----> App. Server III. 127.0.0.1:8083
注:只监听127.0.0.1
的应用只能从本地访问,而若是设置成0.0.0.0
就可以从外部访问了。flask
flask,是一种python开发web的一种框架,相似的还有django,flask比较轻量,django适合大型项目。 flask框架写的web,一般能够直接运行起来就能够访问web了。可是这种方式只适合开发调试,前面已经提过。实际是它内部有一个web服务,叫wsgi。这个东西不是很全,只是做为部分被提供在flask框架内。生产环境中,须要另外的web服务来挂起flak写的网站。一般这个web服务就是uwsgi。稍后咱们会讲到,怎么去安装配置uwsgi;api
而对于nginx,它扮演的是反向代理角色。在大型项目里面经常扮演者反向代理和负载均衡的角色。 什么意思呢,就是用户发送的请求,所有经过这个nginx服务,nginx会去请求真正的内容服务器,也就是咱们部署好的,uwsgi服务。uwsgi服务将用户须要的网页和数据,送到nginx服务那,再由nginx推送给用户。这个过程,对于用户来讲,只和uwsgi服务发生关系。真正的内容服务器是不可见的。 因此从安全的角度来讲,这无疑更安全。 另一个缘由选择nginx,是因为nginx服务性能很稳定,高并发能力强。
uWSGI
咱们知道 Flask 中自带了 web server,经过 Werkzeug,咱们能够搭建 WSGI 服务,运行咱们的网站,但 Flask 是 Web 框架,并非 Web 服务器,尽管 Werkzeug 很强大,但只能用于开发,不能用于生产,对于 Web 服务器,咱们有更专业的选择,那就是 uWSGI, uWSGI 是一个全站式的托管服务,它实现了应用服务器(支持多种编程语言)、代理、进程管理器、监视器。取名为 uWSGI 是由于它最先实现的是 Python 语言的 WSGI。
uWSGI 包括四个部分:
uwsgi协议
web server 内置支持协议模块
application 服务器协议支持模块
进程控制程序
uWSGI 是 C 语言写的,性能比较高。
WSGI, uWSGI, uwsgi 的区别
当咱们部署完一个应用程序,浏览网页时具体的过程是怎样的呢?首先咱们得有一个 Web 服务器来处理 HTTP 协议的内容,Web 服务器得到客户端的请求,交给应用程序,应用程序处理完,返回给 Web 服务器,这时 Web 服务器再返回给客户端。Web 服务器与应用程序之间显然要进行交互,这时就出现了不少 Web 服务器与应用程序之间交互的规范,最先出现的是 CGI,后来又出现了改进 CGI 性能的FasgCGI,Java 专用的 Servlet 规范,Python 专用的 WSGI 规范等等。有了统一标准,程序的可移植性就大大提升了。这里咱们只介绍 WSGI。
WSGI 全称是 Web Server Gateway Interface,也就是 Web 服务器网关接口,它是 Python 语言定义出来的 Web 服务器和 Web 应用程序之间的简单而通用的接口,基于现存的 CGI 标准设计,后来在不少其余语言中也出现了相似的接口。 总的来讲,WSGI 能够分为服务器和应用程序两个部分,实际上能够将 WSGI 理解为服务器与应用程序之间的一座桥,桥的一边是服务器,另外一边是应用程序。
按照 web 组件分类,WSGI 内部能够分为三类,web 应用程序,web 服务器,web 中间件。应用程序端的部分经过Python 语言的各类 Web 框架实现,好比 Flask,Django这些,有了框架,开发者就不须要处理 WSGI,框架会帮忙解决这些,开发者只需处理 HTTP 请求和响应,web 服务器的部分就要复杂一点,能够经过 uWSGI 实现,也能够用最多见的 Web 服务器,好比 Apache、Nginx,但这些 Web 服务器没有内置 WSGI 的实现,是经过扩展完成的。如 Apache,经过扩展模块 mod_wsgi 来支持WSGI,Nginx能够经过代理的方式,将请求封装好,交给应用服务器,好比 uWSGI。uWSGI 能够完成 WSGI 的服务端,进程管理以及对应用的调用。WSGI 中间件的部分能够这样理解:咱们把 WSGI 看作桥,这个桥有两个桥墩,一个是应用程序端,另外一个是服务器端,那么桥面就是 WSGI 中间件,中间件同时具有服务器、应用程序端两个角色,固然也须要同时遵照 WSGI 服务器和 WSGI 应用程序两边的限制和须要。更详细的内容能够看PEP-333 中间件的描述
Flask 依赖的 Werkzeug 就是一个 WSGI 工具包,官方文档的定义是 Werkzeug 是为 Python 设计的 HTTP和 WSGI 实用程序库。咱们须要注意的是,Flask 自带的 Werkzeug 是用来开发的,并不能用于生产环境,Flask 是 Web 框架,而 Werkzeug 不是 Web框架,不是 Web 服务器,它只是一个 WSGI 工具包,它在 Flask 的做用是做为 Web 框架的底层库,它方便了咱们的开发。
咱们将 uwsgi 和 uWSGI 放在一块儿讲解。uWSGI 是一个 Web 服务器程序,WSGI,上面已经谈到,是一种协议,uwsgi 也是一种协议,uWSGI 实现了 uwsgi、WSGI、http 等协议。 uwsgi 的介绍能够看这里,uwsgi 是 uWSGI 使用的一个自有的协议,它用4个字节来定义传输数据类型描述。尽管都是协议,uwsgi 和 WSGI 并无联系,咱们须要区分这两个词。
Nginx
Nginx 是高效的 Web 服务器和反向代理服务器,能够用做负载均衡(当有 n 个用户访问服务器时,能够实现分流,分担服务器的压力),与 Apache 相比,Nginx 支持高并发,能够支持百万级的 TCP 链接,十万级别的并发链接,部署简单,内存消耗少,成本低,但 Nginx 的模块没有 Apache 丰富。Nginx 支持 uWSGI 的 uwsgi 协议,所以咱们能够将 Nginx 与 uWSGI 结合起来,Nginx 经过 uwsgi_pass 将动态内容交给 uWSGI 处理。
官方文档在这
最好的 Nginx 教程在这
uWSGI 和 Nginx 的关系
从上面的讲解中,咱们知道,uWSGI 能够起到 Web 服务器的做用,那么为何有了 uWSGI 还须要 Nginx 呢?
最广泛的说法是 Nginx 对于处理静态文件更有优点,性能更好。其实若是是小网站,没有静态文件须要处理,只用 uWSGI 也是能够的,但加上 Nginx 这一层,优点能够很具体:
对于运维来讲比较方便,若是服务器被某个 IP 攻击,在 Nginx 配置文件黑名单中添加这个 IP 便可,若是只用 uWSGI,那么就须要在代码中修改了。另外一方面,Nginx 是身经百战的 Web 服务器了,在表现上 uWSGI 显得更专业,好比说 uWSGI 在早期版本里是不支持 https 的,能够说 Nginx 更安全。
nginx自己只能调用静态文件, 它须要依赖网关协议文件来调用脚本.
uwsgi是nginx的标准模块, 用于调用其它脚本.
修改nginx的配置文件conf/nginx.conf以指向uwsgi
location / { include uwsgi_params; uwsgi_pass 127.0.0.1:5000; root html; index index.html index.htm; }
修改uwsgi文件, 配置脚本文件app_config.xml,
即运行的文件名以及应用名(nginx, uwsgi和app间须要经过socket进行交互)
<uwsgi> <pythonpath>/home/chenjiebin/web/flaskdemo</pythonpath> <module>flask</module> <callable>app</callable> <socket>127.0.0.1:5000</socket> <master/> <processes>4</processes> <memory-report/> </uwsgi>
Nginx经常使用的几个命令:
sudo service nginx start
sudo service nginx stop
sudo service nginx restart
一个Nginx中,能够同时运行多个应用,不必定是Python的应用。咱们指望经过不一样的路径来路由不一样的应用,所以就不能像上例那样直接修改根目录的配置。假设咱们但愿经过”http://localhost/myapp”来访问咱们的应用,首先要在Nginx的配置文件中,加入下面的内容:
location /myapp { include uwsgi_params; uwsgi_param SCRIPT_NAME /myapp; uwsgi_pass 127.0.0.1:3031; }
这里咱们定义了一个uWSGI参数”SCRIPT_NAME”,值为应用的路径”/myapp”。接下来,在uWSGI的启动配置中,去掉”wsgi-file”项,并加上:
[uwsgi] ... mount=/myapp=server.py manage-script-name=true
“mount”参数表示将”/myapp”地址路由到”server.py”中,”manage-script-name”参数表示启用以前在Nginx里配置的”SCRIPT_NAME”参数。再次重启Nginx和uWSGI,你就能够经过”http://localhost/myapp”来访问应用了。
上面的全部例子中,咱们是经过”127.0.0.1:3031″Socket端口来链接Nginx和uWSGI的,其实咱们也能够采用socket文件的方式,这样能够不用写死端口。在uWSGI的启动配置中,咱们要修改”socket”项:
[uwsgi] socket=/tmp/uwsgi.sock ...
启动uWSGI服务器后,它会自动建立一个”/tmp/uwsgi.sock”文件。而后让咱们修改Nginx配置文件,将”uwsgi_pass”配置项改成文件:
location /myapp { include uwsgi_params; uwsgi_param SCRIPT_NAME /myapp; uwsgi_pass unix:/tmp/uwsgi.sock; }
重启Nginx服务器便可。这里我开始一直没跑通,研究了很久才发现,Nginx的用户(默认的www-date:adm),必需要对该文件有读写的权限才行。由于运行uWSGI的用户与运行Nginx的用户不同,而”/tmp/uwsgi.sock”是由uWSGI的用户建立的,致使Nginx没有足够的权限。若是朋友们也遇到一样的问题,那就只能chmod了。
另外,仍是要提一下”.egg”包的解压缩临时目录,咱们在介绍mod_wsgi的最后提到过,在uWSGI应用中也同样,Linux上默认是在用户主目录下,好比”/home/bjhee/.python-eggs”。你能够经过设置系统环境变量”PYTHON_EGG_CACHE”来改变它。