对 CGI WSGI 的一点理解
CGI 是 Web 服务器和应用程序之间的一种通信协议,服务器使用环境变量和输入输出与 CGI 脚本之间进行通信。它是一个很简单的协议,但是它有一个很大的问题,每一次执行脚本的时候,都会新建一个进程,完成之后,销毁该进程,这就导致了在请求量增加时,效率会很成问题。
为了解决效率问题,各式各样的人想出了各式各样的办法,不过大方向只有两个,一个是内联,一个是外延。内联的方式就是由服务器的服务进程(线程)来执行应用程序,比如 mod_php mod_python ,外延就是弄一个池(不管是进程池、线程池还是混合池,以下简称池)来执行应用程序,约定 池 和 服务器 之间的通信方式,比如 FastCGI 和 SCGI。
WSGI 是服务器与 Python 应用程序之间的通信协议,这里的服务器可能是真正的服务器比如:Apache 也可能是一个中间件比如:flup 。来看个图吧。
------------------------- ----------
| | | | |
| | | WSGI | |
| | mod_wsgi |----------------------------->| |
HTTP | | | | |
------->| | | | |
| |------------| ----------- | |
| | | | | | |
| | | FastCGI | | | Python |
------->| Apache | mod_fcgid |---------->| | | App |
| | | | | | |
| | | | | WSGI | |
| |------------| | flup |------->| |
------->| | | | | | |
| | | SCGI | | | |
| | mod_scgi |---------->| | | |
| | | | | | |
| | | | | | |
------------------------- ----------- ----------
其中 mod_scgi 使用的是外延的方式,它不提供池的功能,只提供和中间件之间以 SCGI 协议使用 Socket 通信的功能,池的功能是由中间件,这里是 flup 提供的。mod_fcgid 也是使用外延的方式,它本身提供了池的功能,App 在 mod_fcgid 提供的进程池中运行,至于池和 Apache 服务进程(线程)间的通信是由它自己来完成的。mod_wsgi 即提供了内联的功能,可以由 Apache 的服务进程(线程)来运行 App ,也提供了外延的功能,自己弄一个池,和 Apache 之间交互,对外提供 WSGI 的接口。