python web 程序的几种部署方式解读

别为不属于你的观众,演不擅长的人生!

这两年的运维人员多数人都折腾过 python 的 web 框架,python 的兴起也是一方面,但是多数人仅仅只是写,部署到线上算是另一码事,看到这篇文章介绍的比较全面,转载之,转载自 鲁塔弗的博客

一、简介

1.1 简介

python 有很多 web 开发框架,代码写完了,部署上线是个大事,通常来说,web 应用一般是三层结构

web server —->application —–> DB server

  • 主流的 web server 一个巴掌就能数出来,apache,lighttpd,nginx,iis
  • application, 中文名叫做应用服务,就是你基于某个 web framework 写的应用代码
  • DB server 泛指存储服务,web 开发中用 mysql 比较多,最近几年因为网站规模扩大,memcache,redis 这种 key-value 等存储也流行开来

放在最前面的 web server 主要有 3 个功能

  • 高效率处理静态文件,web server 基本上都是用 c 开发,调用是 native 的函数,对 IO,文件传输都做针对性的优化
  • 充当一个简易的网络防火墙,可以 deny 一些 ip,简单的控制并发连接数量等等,聊胜于无
  • 处理高并发短连接请求,把成千上万用户的 request 通过内网的几十个长连接进行转发,原因一个是 web server 处理高并发很专业,另外一个原因是大部分的 application 所用的框架都不具备处理高并发的能力

实际上,市面上有部分 web framework 由于内置了支持 epoll/kqueue 等高效网络库,而具备了处理高并发的能力,比如说 python 的 tornado,java 系的 tomcat,jetty 等等,有人就去掉前端的 web server,直接裸奔,但是在部署公网应用时候,最好别这样做,因为前面提到的 1,2 两个原因,用户 brower 到 web server 的网络状况是千奇百怪,你无法想象的,

web server 强烈建议使用 nginx,原因有三

  • 性能非常卓越,非常稳定
  • 安装简单,依赖包少
  • conf 文件非常容易配置,比 apache/lighttpd 都要简单

1.2 部署

  • mod_python
    这是 apache 内置的模块,很严重的依赖于 mod_python 编译使用的 python 版本,和 apache 配套使用,不推荐

  • cgi
    这个太 old,不推荐,而且 nginx 不支持 cgi 方式,只能用 lighttpd 或者 apache

  • fastcgi
    这个是目前流行最广的做法,通过 flup 模块来支持的,在 nginx 里对应的配置指令是 fastcgi_pass

  • spawn-fcgi
    这个是 fastcgi 多进程管理程序,lighttpd 安装包附带的,和 flup 效果一样,区别是 flup 是 python 代码级引入,spawn-fcgi 是外部程序。spawn-fcgi 用途很广,可以支持任意语言开发的代码,php, python, perl,只要你代码实现了 fastcgi 接口,它都可以帮你管理你的进程

  • scgi
    全名是 Simple Common Gateway Interface,也是 cgi 的替代版本,scgi 协议很简单,我觉得和 fastcgi 差不多,只是没有怎么推广开来,nginx 对应的配置指令是 scgi_pass,你想用就用,flup 也支持。

  • http
    nginx 使用 proxy_pass 转发,这个要求后端 appplication 必须内置一个能处理高并发的 http server,在 python 的 web 框架当中,只能选择 tornado.

  • tornado
    python 程序员喜欢发明轮子,tornado 除了是一个 web framework 之外,它还可以单独提供高性能 http server,所以,如果你采用其他 python 框架写代码,比如说 bottle,也一样可以通过 import tornado 来启动一个高性能的 http server,同样的可以采用 http 协议和 nginx 一起来部署。扩展开来,python 包里面能处理高并发的 http server 还有很多,比如说 gevent,也可以被其他框架引用来支持 http 方式部署。

现实当中,用 java 来做 web 程序,通常就用 http 和 nginx 配合,应用服务器选择 tomcat 或者 jetty

  • uwsgi,包括4部分组成

    • uwsgi协议
    • web server内置支持协议模块
    • application服务器协议支持模块
    • 进程控制程序

nginx 从 0.8.4 开始内置支持 uwsgi 协议,uwsgi 协议非常简单,一个 4 个字节 header + 一个 body,body 可以是很多协议的包,比如说 http,cgi 等(通过 header 里面字段标示),我曾经做个一个小规模的性能对比测试,结果表明,uwsgi 和 fastcgi 相比,性能没有太明显的优势,也可能是数据集较小的原因

uwsgi 的特点在于自带的进程控制程序.它是用 c 语言编写,使用 natvie 函数,其实和 spawn-fcgi/php-fpm 类似。所以 uwsgi 可以支持多种应用框架,包括( python, lua, ruby, erlang, go )等等

  • Gunicorn
    和 uwsgi 类似的工具,从 rails 的部署工具 (Unicorn) 移植过来的。但是它使用的协议是 WSGI,全称是 Python Web Server Gateway Interface ,这是 python2.5 时定义的官方标准( PEP 333 ),根红苗正,而且部署比较简单,http://gunicorn.org/ 上有详细教程

  • mod_wsgi
    apache 的一个 module,也是支持 WSGI 协议,源码地址在 https://code.google.com/p/modwsgi/

1.3 fastcgi 协议和 http 协议在代码部署中的的优劣对比

  • fastcgi 虽然是二进制协议,相对于 http 协议,并不节省资源。二进制协议,只能节省数字的表达,比如 1234567,用字符串表示需要 7 个 Byte,用数字就是 4 个 Byte,而字符串到哪里都一样

  • fastcgi 在传输数据的时候,为了兼容 cgi 协议,还要带上一堆 cgi 的环境变量,所以和 http 协议相比,用 fastcgi 传输数据并不省,反而多一些

  • fastcgi 唯一的优点是,它是长连接的,用户并发 1000 个 request,fastcgi 可能就用 10 个 链接转发给后端的 appplication,如果用 http 协议,那来多少给多少,会向后端 appplication 发起 1000 个请求

  • http 代理转发方式,在面对超高并发的情况下会出问题,因为 tcp 协议栈当中,port 是 int16 整型 你本地新建一个 connect,需要消耗一个端口,最多能到 65536。外部并发几十万个请求,port 池耗干,你的服务器只能拒绝响应了

文章最后作者喜欢个人站点程序习惯是用 fastcgi 协议部署 python 程序,简单省事,选择技术方案,一定要选择最简单最常见的。推荐大家尝试 Gunicorn ,这是未来发展方向。

  

参考阅读