对 CGI WSGI 的一点理解

CGI 是 Web 服务器和应用程序之间的一种通信协议,服务器使用环境变量和输入输出与 CGI 脚本之间进行通信。它是一个很简单的协议,但是它有一个很大的问题,每一次执行脚本的时候,都会新建一个进程,完成之后,销毁该进程,这就导致了在请求量增加时,效率会很成问题。

为了解决效率问题,各式各样的人想出了各式各样的办法,不过大方向只有两个,一个是内联,一个是外延。内联的方式就是由服务器的服务进程(线程)来执行应用程序,比如 mod_php mod_python ,外延就是弄一个池(不管是进程池、线程池还是混合池,以下简称池)来执行应用程序,约定 池 和 服务器 之间的通信方式,比如 FastCGISCGI

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 的接口。

blog comments powered by Disqus