WSGI服务器

Web Server Gateway Interface (WSGI),为Python web应用实现web服务器端的WSGI接口。

WSGI为什么必须?

一个传统的web服务器并不了解或知道如何去运行一个Python web应用。上世纪90年代后期,一个名叫Grisha Trubetskoy的开发者开发了一个用于Apache上的模块an Apache module called mod_python来执行Python代码。从那以后到2000年后,Apache配置mod_python来跑大多数Python web应用。

然而,mod_python不是一个标准。它只是让Python代码跑在一个web服务器上。 mod_python开发上的拖延和安全问题被发现,社区认识到web应用需要一个更连贯性的模块。

因此Python社区提出了WSGI作为模块和容器可以执行的标准接口, 现在WSGI已经被认可为运行Python web应用的标准方式。

WSGI server invoking a WSGI application.

如上图所示,WSGI服务器从WSGI应用唤起一个可被调用的对象,具体定义参见PEP 3333标准。

WSGI的目的

为什么使用WSGI,而不是让web服务器直接指向应用?

  • WSGI 让你具有灵活性。应用开发者能复用web组件。比如,一个开发者能从Green Unicorn转向uWSGI,而无需修改执行WSGI的应用框架。根据PEP 3333:可用性和这种为Python服务的API,能够把对web服务器和web框架的选择给分离开来,让开发者专注于它们擅长的领域。
  • WSGI 服务器提供了伸缩性。同时响应上千个动态请求的是WSGI服务器,而不是应用框架。WSGI服务器处理来自web服务器的请求,并决定如何将这些请求发送到应用框架。这种分割有效提升了网络流量的伸缩性。

WSGI Server - Web server - Browser

WSGI 从设计上讲是运行Python代码的一个标准接口。作为一个开发者,你只需要知道:

  • WSGI代表web服务器网关接口(Web Server Gateway Inteface)
  • WSGI容器是一个单独的进程,跟你的web服务器跑在不同的端口
  • 你的web服务器被配置成传输请求到WSGI容器,后者跑你的web应用,然后把响应结果(以HTML形式)传递回请求者

如果你正在使用标准web框架,比如Django,Flask,或Bottle,或任何其他Python框架,你无需知道框架如何执行WSGI标准。同样,如果你正在使用一个标准的WSGI容器,比如Green Unicorn,uWSGI,mod_wsgi,或gevent,你也无需知道他们如何执行WSGI标准。

但是,当你成为只剩Python web开发者时,知道WSGI标准以及这些框架和容器如何执行WSGI,应该是你学习的一部分。

官方WSGI规范

The WSGI standard v1.0 is specified in PEP 0333. As of September 2010, WSGI v1.0 is superseded by PEP 3333, which defines the v1.0.1 WSGI standard. If you’re working with Python 2.x and you’re compliant with PEP 0333, then you’re also compliant with 3333. The newer version is simply an update for Python 3 and has instructions for how unicode should be handled.

wsgiref in Python 2.x and wsgiref in Python 3.x are the reference implementations of the WSGI specification built into Python’s standard library so it can be used to build WSGI servers and applications.

web服务器配置案例

A web server’s configuration specifies what requests should be passed to the WSGI server to process. Once a request is processed and generated by the WSGI server, the response is passed back through the web server and onto the browser.

For example, this Nginx web server’s configuration specifies that Nginx should handle static assets (such as images, JavaScript, and CSS files) under the /static directory and pass all other requests to the WSGI server running on port 8000:

# this specifies that there is a WSGI server running on port 8000
upstream app_server_djangoapp {
    server localhost:8000 fail_timeout=0;
}

# Nginx is set up to run on the standard HTTP port and listen for requests
server {
  listen 80;

  # nginx should serve up static files and never send to the WSGI server
  location /static {
    autoindex on;
    alias /srv/www/assets;
  }

  # requests that do not fall under /static are passed on to the WSGI
  # server that was specified above running on port 8000
  location / {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;

    if (!-f $request_filename) {
      proxy_pass http://app_server_djangoapp;
      break;
    }
  }
}

Note that the above code is a simplified version of a production-ready Nginx configuration. For real SSL and non-SSL templates, take a look at the Underwear web server templates on GitHub.

WSGI服务器

WSGI Read the Docs上有一张网站的WSGI服务器列表。下面的WSGI服务器是社区推荐的:

  • Green Unicorn is a pre-fork worker model based server ported from the Ruby Unicorn project.
  • uWSGI is gaining steam as a highly-performant WSGI server implementation.
  • mod_wsgi is an Apache module implementing the WSGI specification.
  • CherryPy is a pure Python web server that also functions as a WSGI server.

WSGI资源

WSGI服务器学习清单

  1. 理解WSGI是关于应用和服务器执行的Python规范
  2. 选一个WSGI服务器。Green Unicorn是一个好的开始。
  3. 把WSGI服务器增加到你的服务器部署里。
  4. 配置web服务器,让它把请求传输到WSGI服务器。
  5. 测试WSGI服务器,让它相应本地请求,不相应你本地之外的请求。