各语言框架并发性能测试

本文通过几个简单的试验,探究在 IO 等待为瓶颈的场景下,几个典型语言框架的并发能力。以论证异步框架在此场景下的优越性。

测试模型

假设这样一种场景,我们要搭建一个 api 转发服务器,即接到用户请求后,在服务器端调用第三方 api,等待 api 返回结果后,返回 response 给我们的用户。
本文讨论的就是当第三方 api 请求时间特别长(比如 20s)时的并发性能。如下图所示:

服务器配置

试验 web 服务器配置:1C 1G
并发请求客户端配置:2C 8G

测试结果

以 3000 并发为例,进行测试,结果如下:

开发语言 框架 运行方式 并发请求数 测试结果 内存占用% 最大 CPU%
nodejs express 直接 run 3000 无报错 9% 25%
go iris 直接 run 3000 无报错 12% 20%
python flask 直接 run 3000 大量报错
系统卡死
30%+ 70%+
python flask gunicorn
+ gevent
(1 个 worker)
3000 30% 报错 12% 60%
python django 直接 run 3000 全部报错
系统卡死
30%+ 80%+
python django gunicorn
+ gevent
(1 个 worker)
3000 30% 报错 18% 65%
python sanic 直接 run 3000 无报错 13% 35%

结论如下:

  • 在这种特殊测试场景(瓶颈在于 IO 等待)下,nodejs、go 这些语言的原生的异步框架确实性能出色
  • gunicorn + gevent 虽然可以通过打 patch 的方式实现异步协程,但效果还是始终原生的好
  • gunicorn + gevent 可以通过增加 worker 数量,提高并发能力(上例中如果将 worker 数增加到 3 后就不会报错了)
  • flask、django 直接 run,会创建一个框架默认的开发 server,它是以增加线程的方式来应对并发的,众所周知线程的切换成本比协程要高得多,由此例可以看出,当 server 维护 3000 个线程时就力不从心了
  • sanic 这类的异步框架,是 python 最后的牌面了(针对于这种特殊测试场景)

测试代码

代码仓库地址:https://github.com/taojy123/async_test
具体如下:

推荐阅读更多精彩内容

  • # Python 资源大全中文版 我想很多程序员应该记得 GitHub 上有一个 Awesome - XXX 系列...
    小迈克阅读 1,781评论 1 2
  • @synthesize和@dynamic分别有什么作用?@property有两个对应的词,一个是 @synthes...
    笔笔请求阅读 148评论 0 0
  • # Awesome Python [![Awesome](https://cdn.rawgit.com/sindr...
    emily_007阅读 901评论 0 3
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 6,134评论 1 20
  • 今天早上我们去学校返校了。 安老师先给我们发了一张假期的作业,再让背面抄上了假期学校让做的一些工作...
    小王子WXN阅读 55评论 3 1