原文链接: https://blog.appdynamics.com/engineering/an-introduction-to-python-wsgi-servers-part-1/ 。本文主要是对 WSGI 的一些基本介绍,对 WSGI server选择提供一些概念基础。其中 waitress 在原文没有涉及,翻译时追加。waitress性能不错,开发也比较活跃,在Windows平台是一个不错的选择。
WSGI 历史
早期Python编写的web程序很难运行在web server(如Apache)之上,因此 Phillip J.Eby 在Ian Bicking 等人的协助下于21世纪初开发了WSGI,WSGI读作 "whiz-gee" 或者 "whiskey"(音同威士忌)。在WSGI出现之前,实际上有一个 Grisha Trubetskoy 开发的Apache module mod_python可以运行大部分Python开发的web小程序,但是它过于简单,也没有官方标准文档可以依循,最关键的是,它不够安全,这也是当时WSGI开发的关键背景。
WSGI实际上可以认为继承自CGI,Python的web程序在CGI模式下可以用CGI,mod_python,FastCGI等部署模式,但显然CGI方式运行的部署模式有诸多限制,运行效率也较慢。而开发WSGI的目的就是制定一个标准的接口规范,准确描述如何路由Python web应用或框架到各种Web Server。
Web Server 和 Web App
WSGI包括两部分
- 高性能Web Server,提供类似Nginx或Apache这样的web server功能
- Python编写的Web App
Web server 运行 Web App,发送web请求相关的信息到 Web App。Web App 处理请求,并发送其生成的响应数据到 Web App。
在Web Server 和 Web App 之间可能会有一个或多个WSGI 中间件,中间件用于路由请求到不同的 App 对象,并处理:负载均衡,预处理数据,或维护不同的 web 框架层或者维护多个 App 运行在同一进程中。python 中的常见 Web 框架如 Django,CherryPy,Flask,TurboGears,web2py 均是以这一模式运行在WSGI下。
为什么需要WSGI
为什么必须要用WSGI呢?有以下几个原因
- WSGI被设计用于处理大量并发请求,但你很容易从各种 Web 开发框架的文档发现,Web框架本身并不处理这样的需求,它们也不考虑如何与Web Server交互。
- WSGI加速了python web开发,因为你只需要了解基本的WSGI知识就可以用WSGI模式部署你的web程序,而WSGI标准也让python web服务器中间件的开发和优化更方便。虽然在你的实际的web程序开发中你不需要了解WSGI的实现,但是如果你对此有一定了解,也不无裨益。
- 由于WSGI是标准规范,得益于此,你可以自由选择各种WSGI组件来运行你的web程序而不需要修改web程序代码。
目前可选的 WSGI 服务器很多,有一些能支持很全面的WEB服务器功能,另外一些则是有特定应用场合的框架如 gunicorn 对django的开箱即用支持(译注:实际上现在gunicorn对主流的python web框架都能支持最简单的方式启用和部署)。
Bjoern
Bjoern是一个用C语言写的非常轻量级的异步CPython WSGI Server,设计初衷是创造一个小而快的工具,主要使用的组件库是 http_parser (由Node.js创造者Ryan Dahl所开发)和libev (Marc Lehmann)。
Bjoern 大小只有18KB,总代码行数不超过800行,运行时框架本身占用不超过1MB的内存,Bjoern完全兼容WSGI规范,运行效率非常快,但是,它不支持线程或协程(coroutine)运行模式。
Bjoern 支持网络连接持久化,可绑定监听Unix socket和TCP 端口,运行效率快于主流的一些WSGI Server如Gunicorn,uWSGI等,但是功能集(如命令行支持,配置,SSL支持等)也明显弱于主流WSGI server如uWSGI,另外一个较大缺陷是它还不兼容 HTTP/1.1。
uWSGI
uWSGI 的目标是成为一个提供全栈支持的web app运行服务(hosting service),通过配置选项和提供的API能够构建对多种编程语言,协议的支持,也提供进程管理,代理,监控等功能,uWSGI项目的命名就来自于WSGI项目,同时uWSGI也是为WSGI项目较早创建的WSGI Server。
uWSGI 实现了一个插件的架构,能够扩展其支持不同的语言和平台,其插件可用 Objective-C,C以及C++开发,在uWSGI最新的发布中主要包括以下核心组件
- 一个支持并发和时间处理的闭环引擎(Loop engine),可以支持Python的 Greenlet,Gevent,Tornado 等框架技术
- 内核部分,包括处理 socket,进程管理,集群管理,日志,配置,进程间通信(IPC),内存共享,以及uWSGI订阅服务等
- 网关部分(Gateway),用于代理,负载均衡,以及路由
- 网络请求处理,管理Web APP接口转换,包括 PHP,CGI,Rack 等
uWSGI是一个应用广泛并且持续改进(同时也非常稳定)的项目,它可以支持很多功能而不仅仅是作为 WSGI Server 运行 Web APP,很多人认为它非常强大,但是另外一些人觉得这种强大其实是一种功能上的臃肿冗余。目前uWSGI项目由一家意大利的网络服务提供商(ISP) Unbit 维护。
mod_wsgi
mod_wsgi 是 Apache Server 中的一个 module,由 Graham Dumpleton 开发,它提供一个 WSGI 接口以支持在 Apache 上运行 Python web app,最新的发布版本可以支持 Python2.6 和 Python 3.2。它的开发目的主要是为运行在Apache上的Web app提供一个除了CGI,FastCGI之外的选项,并且通过Apache module的方式安装,也可通过 mod_wsgi express 的方式安装。
mod_wsgi 目前仍在开发中,但是只有一个开发者在维护该项目,所以看起来进展较慢,另外文档组织也不是很好,甚至部分文档还没有与最新的功能同步更新,该项目现在主要的目标是希望能够更容易在Docker中与Apache一起运行。
Meinheld
由 Yutaka Matsubara 创建的项目,完全兼容WSGI标准,基于 picoev 和 greelet 支持异步IO以实现轻量级且快速的性能,可以作为独立的HTTP server运行或者通过Gunicorn运行。
Meinheld 基于greenlet,使用BSD license,代码库在Github上,可支持websocket,同时还包括对其他一些模块的monkeypatch(了解greentlet的同学应该知道,主要是greenlet对socket等IO模块的monkeypatch)。
CherryPy
CherryPy是Python的一个Web Framework,同时附带一个WSGI server,主要技术实现是基于线程池,兼容HTTP/1.1标准,CherryPy 运行速度很快,可应用于生产环境(据CherryPy 开发团队所说)。
- 快,易于配置
- 可支持扩展
- 小且易于部署
- SSL 支持
CherryPy 非常易于使用,你可以在很短时间内部署一个可支持多进程运行的CherryPy WSGI server。同时可以使用Nginx作为前端的Web server,通过反向代理的方式来负载均衡CherryPy WSGI server,这个部署架构非常简单,但完全可应用于生产环境。通过这种方式,可以很轻易的部署 CherryPy, Bottole,Flask,Pyramid,Django等Web框架开发的Python Web应用。CherryPy作者是Remi Delon,他的目标是希望CherryPy是一个尽可能的符合Python模式(所谓 Pythonic)的web框架。
Gunicorn
Gunicorn 是一个只能运行在Unix平台的WSGI HTTP Server,名字来源于"Green Unicorn”。Gunicorn主要是从Ruby的Unicorn项目的Python实现,它运行速度比较快,资源占用较少,易于使用,并且支持大部分Python的web框架。
Gunicorn开发团队推荐使用Nginx作为Gunicorn的前端代理web服务器。Gunicorn没有特别的依赖环境(除了只能运行在Unix系统),有如下特性:
- 很方便的支持Paster,Django和WSGI
- 自动的worker进程管理
- 可通过命令行或配置文件配置,丰富的配置选项
- 可配置运行大量的worker进程
- 可支持多种 server 钩子(hooks)
Gunicorn支持Python2.x,3.x直到3.2。需要注意的是,Gunicorn无法支持“keep-alive”,因为Gunicorn进程运行在Nginx后面,而Nginx的upstream仅支持HTTP/1.0。
Waitress
Waitress 主要支持 Python2.7 以上的python以及等同的pypy版本,完全由Python及python下的标准库编写,可同时运行在Windows和*nix下,采用多线程的运行模式,运行速度很快,可部署用于生产环境中,尤其是在Windows系统的部署,是一个优秀的备选方案。
结论
以上WSGI server横向比较下来,从稳定性和全面性来讲,uWSGI应该是首选,但是也要根据项目的实际需要进行选择。Bjoern用C语言开发,非常快,异步运行但是不支持HTTP/1.1。Meinheld也是用C语言开发,快而小。uWSGI应用广泛,功能强大,支持多种开发语言,但有人又觉得它大且臃肿笨拙。mod_wsgi可支持Apache但是看起来旧且过时。Gunicorn运行速度快,资源消耗小,对Django的支持非常友好。CherryPy的内置WSGI server 虽小,但是稳定,效率也不错。根据以上特性,再结合你的项目实际需要选择合适的WSGI server。
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.