小测几种python web server的性能
http://blog.csdn.net/raptor/article/details/8038476
因为换了nginx就不再使用mod_wsgi来跑web.py应用了,现在用的是gevent-wsgi,效果还不错。但还是想试试别的,比如传说中超级猛的meinheld什么的。
软硬件环境
硬件:
一台04年初购置的IBM X235服务器,CPU为Xeon 2.4G两颗,内存1G,100M网卡。
软件:
Ubuntu Server 10.04 LTS
Apache 2.2.14
Nginx 0.7.65
Python 2.6.5
web.py 0.37
mako 0.7.2
sqlalchemy 0.7.8
gevent 0.13.7
gunicorn 0.14.6
meinheld 0.4.15
测试代码
有五个版本,分别是:
最基本的WSGI helloworld
- def application(environ, start_response):
- status = '200 OK'
- resp = "Hello world!"
- resp_headers = [('Content-type','text/plain;charset=utf-8')]
- start_response(status, resp_headers)
- return [resp]
最基本的web.py your IP
- class yourip:
- def GET(self):
- return "Your IP is : %s" % web.ctx.ip
加了mako模板的web.py
- class onlymako(BaseHandler):
- @expose("yourip")
- def GET(self):
- return dict(yourip=web.ctx.ip)
加了数据库的web.py
- class onlydb:
- def GET(self):
- created = web.ctx.provider.once_access(web.ctx.ip)
- return "You have logged : %s" % created
和同时加了数据库和mako模板的web.py —— 这也是最接近实际应用的情况
- class makodb(BaseHandler):
- @expose("index")
- def GET(self):
- created = web.ctx.provider.once_access(web.ctx.ip)
- return dict(created=created)
测试目标
五种运行环境:
web.py的测试环境app.run
web.py+gevent-WSGI
gunicorn默认(sync)
gunicorn+gevent
gunicorn+meinheld
gunicorn使用 -w 4 参数,经实际比较过,这个参数并不能有效增加rps,但在高并发测试情况下可以在一定程度上减少失败率。
测试方式
ApacheBench 2.3(Ubuntu Desktop 12.04)
RPS测试参数为 -n 200 -c 22 测五次取rps平均值。
之所以用这样比较小的参数,是因为再高了,其中某些测试就通不过了。
测试结果
RPS测试 | WSGI helloworld | Web.py YourIP | Web.py+Mako | Web.py +SQLAlchemy (SQLite) |
Web.py+Mako +SQLAlchemy (SQLite) |
Web.py |
Web.py+Mako +SQLAlchemy (Postgresql) |
---|---|---|---|---|---|---|---|
Web.py app.run | 无 | 130 | 93 | 75* | 45* | 59 | 40 |
web.py+gevent | 无 | 422 | 130 | 82 | 54 | 74 | 53 |
gunicorn default | 854 | 439 | 136 | 93 | 66 | 90 | 62 |
gunicorn+gevent | 695 | 291 | 115 | 74 | 56 | 78 | 56 |
gunicorn+meinheld | 3565 | 682 | 160 | 84 | 65 | 98 | 64 |
其中加了“*”的数字发生了数据库错误,仅供参考。
另外,用同样的参数测了一下Apache2处理静态文件的rps为:1780,nginx为:2951。
===附加的分割线===
再附加一个在我的Atom小服务器上的部分测试结果:
Nginx处理静态文件的rps为:4000左右。
WSGI hello world测试:gunicorn+meinheld约为:3800。gunicorn+gevent约为:1100。gunicorn default约为:1400。
your IP测试:gunicorn+meinheld约为:1000。gunicorn+gevent约为:450。gunicorn default约为:700。
相比之下这个Atom小机器比IBM服务器猛好多。硬件发展速度真是太快了。
附软硬件环境:
Atom D525 1.6G双核,2GRAM,FreeBSD 9,Nginx 1.2.2,Python 2.7.3,其它同IBM服务器。
并且在这个Atom机器上 -w 参数对rps有明显贡献…看来是因为老服务器的问题才效果不明显,只是不确定是硬件问题还是OS问题。
结论
meinheld的确猛,处理最简单的WSGI比Apache2处理静态文件还要猛一倍,跟Nginx相当甚至更强。
app.run的rps比预想的要好很多,只是并发数真不行,-c 参数略加大就会出现大量失败测试。
gevent已经足够好了,不过居然比gunicorn的sync模式还慢真是有点不科学啊。
gunicorn的好处在于管理方便,并且可以灵活使用各种work_class,特别奇怪的一点是居然sync模式也这么快。
web.py的性能影响还是很明显的。
模板的影响也很明显——mako已经算是很快的模板了,真不知道用那些KID之类很慢的模板会是什么效果。
数据库的影响更大,不过pgsql的性能居然能跟sqlite差不多,真不知道是sqlite太慢还是pgsql太快…
本来前一阵我刚听说OpenResty这货的时候还是很有兴趣的,但是现在看到meinheld的表现以后,觉得还是算了吧,毕竟用OpenResty还要去学Lua…现在要学的东西太多,能用Python搞定的事情就不去麻烦Lua了。
上次的测试见《小测几种python web server的性能》。
前两天参加了PyCon2012上海站。虽然今年的PyCon被各种吐槽,但还是有点收获的。比如ShellXu的元编程,赖总的state/message,沈大侠谈的pypy等。
回来就想测一下用pypy跑web应用看看性能如何。顺便也对上次的测试范围作了点扩大化。
PyCon上谈到的Pyramid我虽然没用过,但是前身Pylons和Turbogears我是用过的,只是现在对这种重量级的东西兴趣不大。
轻量级的框架除了上次测试用到的web.py以外,bottle和flask也是很热的东西,尤其是flask,但是因为它对Werkzeug的依赖令我不是很喜欢——我不喜欢名字不好念的东西,除了Werkzeug以外还有像Django这种。
不过这次还是都拿来测了。软硬件环境与上次测试相同。测试代码功能都是 your IP。bottle和flask的测试代码由令狐虫(http://ch-linghu.me/blog/)友情提供,特此鸣谢。
Server都是用的gunicorn default(sync),单进程。没有特别精确统计,取近似平均值。
RPS测试 | WSGI helloworld | Web.py YourIP | Bottle Your IP | Flask Your IP |
---|---|---|---|---|
python | 850 | 440 | 580 | 400 |
pypy(*) | 1100 | 800 | 1000 | 600 |
就这个结果来看,pypy的作用还是比较明显的。另外flask看上去也一般啊,虽然号称扩展能力强,不知道扩下去性能是不是会影响更大。但bottle的确是很不错的样子。
(*)当然因为pypy是JIT方式运行的,所以有一个“预热”的过程。请求量过小的时候不但不会更快,反而会慢很多。基本上在“冷”状态下,pypy环境下的RPS只有python环境的一半不到。需要有连续大量请求之后才能达到“热”状态。上面的RPS数据都是“热”状态的结果。
达到“热”状态的过程也各不相同。标准WSGI在几百个请求之后即可达到,bottle大概需要一千多个请求,web.py需要将近一万个请求,而flask要超过一万。
另外,就测试的软硬件环境来说,gunicorn default(sync)单进程最高只能达到130个并发左右,4进程可以达到270个并发左右。因为换用不同的框架结果都是如此,当然标准WSGI会略高一些(单进程170左右),所以主要应该还是gunicorn决定。
换用gunicorn+gevent测试的话,所有框架上到单进程1000并发没问题,只是RPS会有相应下降而已。这个时候就体现出gevent相比sync的优势所在了——虽然低并发时sync速度比gevent还快,但是在高并发下,sync直接死掉(无响应直至超时),gevent只是速度慢了而已。
同样换用gunicorn+meinheld,最高并发也只能到260而已,只比sync模式高一倍,但还是远低于gevent。而且meinheld的表现比较奇怪,一开始还可以接受1000并发的,然后就越来越少。另外,它的表现也与gevent不同,gevent在高并发下是一开始就按比较低RPS工作,而meinheld则是仍然以高RPS工作,但到后面就会爆掉(客户端显示连接被服务端中断)。
经令狐分析,可能的原因是这样的:
sync从字面上理解应该是使用线程阻塞模式,所以在低并发下可以利用到服务器的多核,所以RPS比gevent要高。但是在高并发下,因为线程过多,导致线程切换成本过高失去响应。
meinheld应该也是使用了多线程(同时使用greenlet的协程),所以性能最好,但是在高并发下同样会面临与sync一样的多线程问题。
gevent则胜在轻量,虽然没有多线程利用多核的优势,但同样可以用多进程来利用,而且在高并发的时候,处理不了的请求是在排队中,所以不会爆掉或死掉,只是RPS下降而已。当然,在极端高并发的情况下,请求队列是有可能溢出的,但那已经是比sync/meinheld高得多得多的并发了。
不过之前对meinheld过于乐观的看法是需要改变了,因为在同样高并发的情况下,nginx毫无压力,虽然RPS下降不少,但仍然是远高于gevent,更不用说已经趴下的sync和meinheld……
最后,在测试中还发现了bottle的一个性能问题:404错误的响应比正常页面慢很多。令狐因此对测试程序作了改进,加了一个自定义404页面,这样404的响应就和正常页面差不多了。这一点在使用bottle时需要作为一个注意事项加以考虑。
小测几种python web server的性能的更多相关文章
- a simple and universal interface between web servers and web applications or frameworks: the Python Web Server Gateway Interface (WSGI).
WSGI is the Web Server Gateway Interface. It is a specification that describes how a web server comm ...
- Python Web Server Gateway Interface -- WSGI
了解了HTTP协议和HTML文档,我们其实就明白了一个Web应用的本质就是: 浏览器发送一个HTTP请求: 服务器收到请求,生成一个HTML文档: 服务器把HTML文档作为HTTP响应的Body发送给 ...
- python web server gateway interface (wsgi ) notes
前言: 注:如果需要得到支持批Python3.x以及包含了勘误表,附录,和说明的更新版规范,请查看PEP 3333 摘要: 这篇文档详细说明了一套在web服务器与Python web应用程序(web框 ...
- Notes on PEP333 (Python Web Server Gateway Interface)
This note is about PEP3333- Python Web Server Gateway Interface. Refer to (Source: http://legacy.pyt ...
- C# 启动 a Python Web Server with Flask
概览 最近有个需求是通过c#代码来启动python 脚本.嘿~嘿!!! 突发奇想~~既然可以启动python脚本,那也能启动flask,于是开始着手操作. 先看一波gif图 通过打开控制台启动flas ...
- 全面解读python web 程序的9种部署方式
转载自鲁塔弗的博客,本文地址http://lutaf.com/141.htm python有很多web 开发框架,代码写完了,部署上线是个大事,通常来说,web应用一般是三层结构 web serve ...
- python web 程序的9种部署方式
python有很多web 开发框架,代码写完了,部署上线是个大事,通常来说,web应用一般是三层结构 Web Server====> Application=====> DB S ...
- 【Python Programe】WSGI (Web Server Gateway Interface)
Part1: What is a Web server? 一个位于物理服务器上的网络服务器(服务器里的服务器),等待客户端去发送request,当服务器接收到request,就会生成一个respons ...
- 全面解读Python Web开发框架Django,利用Django构建web应用及其部署
全面解读Python Web开发框架Django Django是一个开源的Web应用框架,由Python写成.采用MVC的软件设计模式,主要目标是使得开发复杂的.数据库驱动的网站变得简单.Django ...
随机推荐
- BTrace使用总结
btracejvisualvmhotswap 一.背景 在生产环境中可能经常遇到各种问题,定位问题需要获取程序运行时的数据信息,如方法参数.返回值.全局变量.堆栈信息等.为了获取这些数 ...
- Servlet中文乱码解决方法
程序中的输入输出都是以流的形式保存的,流中保存的实际上全都是字节文件. 字节流和字符流的区别: 在Java.io包中操作文件内容的主要有两大类:字节流.字符流,两类都分为输入和输出操作. 在字节流中输 ...
- hdu2007
import java.util.*;class Main{public static void main(String args[]){Scanner cin=new Scanner(System. ...
- android UI生成器
可根据选择的效果生成资源 http://jgilfelt.github.io/android-actionbarstylegenerator/#name=example&compat=sher ...
- js中跨域请求原理及2种常见解决方案
一.同源策略: 说到跨域请求,首先得说说同源策略: 1995年,同源政策是由 Netscape 公司引入浏览器的.目前,所有浏览器都实行了这个政策. 同源策略是浏览器的一种安全策略,所谓同源是指,域名 ...
- CentOS7安装Cobbler
安装EPEL源 # rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm 安装cobbler ...
- SQL SERVER将某一列字段中的某个值替换为其他的值 分类: MSSQL 2014-11-05 13:11 67人阅读 评论(0) 收藏
SQL SERVER将某一列字段中的某个值替换为其他的值 UPDATE 表名 SET 列名 = REPLACE(列名 ,'贷','袋') SQL SERVER"函数 replace 的参数 ...
- [功能帮助类] JsHelper--Javascript操作帮助类 (转载)
点击下载 JsHelper.rar 这个类是关于加密,解密的操作,文件的一些高级操作1.Javascript弹出信息,并跳转指定页面. 2.Javascript弹出信息,并返回历史页面3.Javasc ...
- RelativeLayout相对布局 安卓布局技巧
http://blog.csdn.net/nieweiking/article/details/38417317 RelativeLayout相对布局 相对布局 RelativeLayout 允许子元 ...
- LINQ数据库连接对象制造工厂
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.D ...