Python3.4 和 Python3.5 有个较大区别是 asyncio库进化到 async关键字了. python3.5 当然是向下兼容的,官方在3.5这个版本里推进 async 、await 关键字. async 其实跟 @asyncio.coroutine 相等的, await是跟 asyncio 的 yield from 差不多的. python 2.7 与 python 3.5 我都在使用,对我个人最直观的感受是 async 有点壳子的感觉,很多一些网络库用的还是2.7的. 在异步的语法上也没有gevent用的爽 . 仁者见仁智者见智吧.
该文章写的有些乱,欢迎来喷 ! 另外文章后续不断更新中,请到原文地址查看更新. http://xiaorui.cc/?p=4139
不知道什么时候圈子里火了一个高性能的异步非阻塞框架 sanic ,搜了一大圈,貌似没看到有人的实测报告,及生产环境中遇到的问题。 python3.5+ 的 sanic 相关技术文章实在匮乏,但我还是很惊奇sanic在github中的介绍,强大到脚踢各种python web的框架….
sanic github 地址:
https://github.com/channelcat/sanic
既然我说是小测,那么肯定是瞎测试了,哈哈. 这里也不考虑分布式压测及test的标准性。 那么一句话,就干!
Server | Implementation | Requests/sec |
---|---|---|
Sanic | Python 3.5 + uvloop | 33,342 |
Wheezy | gunicorn + meinheld | 20,244 |
Falcon | gunicorn + meinheld | 18,972 |
Bottle | gunicorn + meinheld | 13,596 |
Flask | gunicorn + meinheld | 4,988 |
Kyoukai | Python 3.5 + uvloop | 3,889 |
Aiohttp | Python 3.5 + uvloop | 2,979 |
Tornado | Python 3.5 | 2,138 |
这个表格体现的数据还是有些意思的, Falcon,Bottle,Flask 都是使用 gunicorn多进程框架,使用meinheld来做wsgi网关… 至于 Aiohttp 、Kyoukai 跟着一个uvloop 。 这测试报告里tornado看样子是性能最差的? 不至于吧… 很是怀疑作者测试的hello world …
下面我将采用不理智的方法测试 sanic 的性能 , 同步的逻辑就不测试了,主要还是测试异步下的性能体现.
先前我通过sanic框架写了一些简单的业务逻辑,中间会涉及到redis及mysql. 但总的来说 基于asyncio的那些第三方网络库有些粗糙,使用方法上会有各种的不爽, 另外性能没觉得多厉害…
测试的代码很简单,就是加了个asyncio.sleep() , 另外已经做了 ulimit 和 sysctl的优化, 不会出现open many files的提示. 因为是本地之间的测试,ab作为
import asyncio from sanic import Sanic from sanic.response import json app = Sanic() @app.route("/") async def test(request): await asyncio.sleep(1) return json({"blog": " xiaorui.cc "}) if __name__ == "__main__": app.run(host="0.0.0.0", port=8000)
下面是测试的结果,QPS在900左右
Concurrency Level: 1000 Time taken for tests: 11.438 seconds Complete requests: 10000 Failed requests: 0 Total transferred: 1070000 bytes HTML transferred: 170000 bytes Requests per second: 874.32 [#/sec] (mean) Time per request: 1143.752 [ms] (mean) Time per request: 1.144 [ms] (mean, across all concurrent requests) Transfer rate: 91.36 [Kbytes/sec] received
可惜sanic有时会崩溃…
File "/usr/local/lib/python3.5/dist-packages/sanic/server.py", line 174 in write_error File "/usr/local/lib/python3.5/dist-packages/sanic/server.py", line 178 in bail_out File "/usr/local/lib/python3.5/dist-packages/sanic/server.py", line 174 in write_error File "/usr/local/lib/python3.5/dist-packages/sanic/server.py", line 178 in bail_out File "/usr/local/lib/python3.5/dist-packages/sanic/server.py", line 174 in write_error File "/usr/local/lib/python3.5/dist-packages/sanic/server.py", line 178 in bail_out File "/usr/local/lib/python3.5/dist-packages/sanic/server.py", line 174 in write_error File "/usr/local/lib/python3.5/dist-packages/sanic/server.py", line 178 in bail_out File "/usr/local/lib/python3.5/dist-packages/sanic/server.py", line 174 in write_error File "/usr/local/lib/python3.5/dist-packages/sanic/server.py", line 178 in bail_out File "/usr/local/lib/python3.5/dist-packages/sanic/server.py", line 174 in write_error File "/usr/local/lib/python3.5/dist-packages/sanic/server.py", line 178 in bail_out File "/usr/local/lib/python3.5/dist-packages/sanic/server.py", line 174 in write_error File "/usr/local/lib/python3.5/dist-packages/sanic/server.py", line 178 in bail_out File "/usr/local/lib/python3.5/dist-packages/sanic/server.py", line 174 in write_error File "/usr/local/lib/python3.5/dist-packages/sanic/server.py", line 178 in bail_out File "/usr/local/lib/python3.5/dist-packages/sanic/server.py", line 174 in write_error File "/usr/local/lib/python3.5/dist-packages/sanic/server.py", line 178 in bail_out File "/usr/local/lib/python3.5/dist-packages/sanic/server.py", line 174 in write_error ... 已放弃 (核心已转储)
Python 2.7 tornado的测试结果
Concurrency Level: 1000 Time taken for tests: 8.983 seconds Complete requests: 5000 Failed requests: 0 Total transferred: 1035000 bytes HTML transferred: 60000 bytes Requests per second: 556.63 [#/sec] (mean) Time per request: 1796.519 [ms] (mean) Time per request: 1.797 [ms] (mean, across all concurrent requests) Transfer rate: 112.52 [Kbytes/sec] received
Python 3.5 tornado的测试结果
Concurrency Level: 1000 Time taken for tests: 12.240 seconds Complete requests: 5000 Failed requests: 0 Total transferred: 1035000 bytes HTML transferred: 60000 bytes Requests per second: 408.49 [#/sec] (mean) Time per request: 2448.060 [ms] (mean) Time per request: 2.448 [ms] (mean, across all concurrent requests) Transfer rate: 82.57 [Kbytes/sec] received
下面是Tornado的测试代码: (python2.7 3.5 都可以跑)
#xiaorui.cc import datetime from tornado import web, ioloop, gen, options class MainHandler(web.RequestHandler): @gen.coroutine def sleep(self, seconds): ¦ yield gen.Task( ¦ ¦ ioloop.IOLoop.current().add_timeout, ¦ ¦ deadline=datetime.timedelta(seconds=seconds)) @gen.coroutine def get(self): ¦ yield self.sleep(seconds=1) ¦ self.write("when i sleep") application = web.Application([ (r'/', MainHandler), ], debug=True) if __name__ == "__main__": options.parse_command_line() application.listen(8000) ioloop.IOLoop.instance().start()
如果不考虑第三方库的质量和性能,单单纯纯的sleep测试来看, sanic这个框架性能还真的是更高一筹… 要比 tornado 高个 30%左右… 如果你的python版本正好是3.5,有敢于尝试新事物,我觉得可以试试…
sanic后期的更新里,不再像以前那样,只是做语法上的介绍。 现在更多的展示实际开发中遇到的场景,比如 sanic mysql, postgres的使用 . sanic上建议使用uvloop支持的第三方库. 3.4以后那些asyncio库虽然也可以用,但不能性能最大化…
END.