用 Python 实现每秒处理 120 万次 HTTP 请求
用 Python 做到每秒处理上百万次 HTTP 请求,可能吗?也许不能,但直到最近,这已成为现实。
很多公司都在为了提升程序的执行性能和降低服务器的运营成本,而放弃 Python 去选择其它编程语言,其实这样做并不是必须,因为 Python 完全可以胜任这些任务。
Python 社区最近做了大量关于性能的优化。CPython 3.6 重写了新的字典从而全面提升解析器的执行性能。由于引入更快的调用规则和字典查询缓存,CPython 3.7 甚至还要更快。
我们可以用 PyPy 的 Just-in-Time 来编译复杂的科学计算任务,NumPy 的测试套件也优化了和 C 扩展的兼容性,同时 PyPy 还计划于今年晚些时候做到和 Python 3.5 保持一致。
了解 Japronto!
Japronto 是一个全新的,为微服务量身打造的微框架。实现它的主要目标包含够快、可扩展和轻量化。的确它快的吓人,甚至远比 NodeJS 和 Go 还要快的多的多。要感谢 asyncio,让我可以同时编写同步和异步代码。
Python 的微框架(蓝色)、NodeJS 和 Go (绿色) 和 Japronto (紫色)
勘误表:用户 @heppu 提到,如果谨慎点用 Go 的 stdlib HTTP 服务器可以写出比上图的 Go 快 12% 的代码。另外 fasthttp 也是一个非常棒的 Go 服务器,同样的测试中它的性能几乎只比 Japronto 低 18%。真是太棒了!更多细节查可以看
https://github.com/squeaky-pl/japronto/pull/12 和
https://github.com/squeaky-pl/japronto/pull/14
我们可以看到其实 Meinheld WSGI 服务器已经和 NodeJS 和 Go 的性能差不多了。尽管它用的是阻塞式设计,但还是要比前面那四个要快的多,前面四个用的是异步的 Python 解决方案。所以,不要轻易相信别人那些关于异步系统总是比同步系统更快的说法,虽然都是并发处理的问题,但事实远不如想象的那么简单。
虽然我只是用 “Hello World” 来完成上面这个关于微框架的测试,但它清晰的展现了各种服务器框架的处理能力。
这些测试是在一台亚马逊 AWS EC2 的 c4.2xlarge 实例上完成的,它有 8 VCPUs,数据中心选在圣保罗区域,共享主机、HVM 虚拟化、普通磁盘。操作系统是 Ubuntu 16.04.1 LTS (Xenial Xerus),内核为 Linux 4.4.0–53-generic x86_64。操作系统显示的 CPU 是 Xeon® E5–2666 v3 @ 2.90GHz。Python 我用的版本是 3.6,刚从源码编译来的。
公平起见,所有程序,包括 Go,都只运行在单个处理器内核上。测试工具为 wrk,参数是 1 个线程,100 个链接和每个链接 24 个请求(累计并发 2400 次请求)。
HTTP 流水线(图片来自 Wikipedia)
HTTP 流水线在这里起着决定性的因素,因为 Japronto 用它来做执行并发请求的优化。
大多数服务器把来自客户端的流水线和非流水线请求都一视同仁,用同样的方法处理,并没有做针对性的优化。(实际上 Sanic 和 Meinheld 也是默默的把流水线请求当做非流水线来处理,这违反了 HTTP 1.1 协议)
简单来说,通过流水线技术,客户端不用等到服务器端返回,就可以在同一条 TCP 链接上继续发送后续的请求。为了保障通讯的完整性,服务器端会按照请求的顺序逐个把结果返回给客户端。
细节优化过程
当一堆小的 GET 请求被客户端以流水线打包发送过来,服务器端很可能只需要一次系统调用,读取一个 TCP 数据包就能拿到全部的请求。
系统调用,以及在内核空间到用户空间之间移动数据,相比起在进程内部移动数据,成本要高的多。这就是为什么不到万不得已,要尽可能少做系统调用的次数。
当 Japronto 收到数据并成功解析出请求序列时,它会尝试尽可能快的把这些请求执行完成,并以正确的顺序合并所有结果,然后只执行一次系统调用发送数据给客户端。实际上因为有 scatter/gather IO 这样的系统调用,合并的工作并不需要自己去完成,只不过 Japronto 暂时还没有用到这些功能。
然而事情并不总是那么完美,有时候请求需要耗费很长时间去处理,等待完成的过程增加了不必要的延迟。
当我们做优化时,有必要考虑系统调用的成本和请求的预期完成时间。
经过优化 Japronto 拿到了 1,214,440 RPS 的成绩
除了利用客户端流水线请求,和优化调用,还有一些其它可用的技术。
Japronto 几乎都是用 C 写的。包含解析器、协议、链接管理、路由、请求、应答等对象都是用 C 扩展写的。
Japronto 力图做到 Python 的懒加载,比如,协议头的字典只有在被试图请求到时才会被创建,另外一系列的对象也只有在第一次使用时才会被创建。
Japronto 使用超牛逼的 picohttpparser C 库来解析状态、协议头以及分片的 HTTP 消息体。Picohttpparser 是直接调用现代 CPU 集成的 SSE4.2 扩展文本处理指令去快速匹配 HTTP 标记的边界(那些 10 年前的老 x86_64 CPU 都有这玩意儿)。I/O 用到了超棒的 uvloop,它是一个 libuv 的封装,在最底层,它是调用 epoll 来提供异步读写通知。
Picohttpparser 依赖 SSE4.2 和 CMPESTRI x86_64 的特性做解析
Python 是有垃圾收集功能的语言,为避免不必要的增加垃圾收集器的压力,在设计高性能系统时一定要多加注意。Japronto 的内部被设计的尝试避免循环引用和尽可能少的分配、释放内存,它会预先申请一块区域来存放对象各种,同时尝试在后续请求中重用那些没有被继续引用的 Python 的对象,而不是将那些对象直接扔掉。
这些预先申请的内存的大小被固定为 4KB 的倍数。内部结构会非常小心和频繁的使用这些连续的内存区域,以减少缓存失效的可能性。
Japronto 会尽可能避免不必要的缓存间复制,只在正确的位置执行操作。比如,在处理路由时,先做 URL 解码再进行路由匹配。
Japronto 已经可靠的实现了下面这些功能:
实现 HTTP 1.x 并且支持分片上传
完整支持 HTTP 流水线
可配置是否让链接 Keep-alive
支持同步和异步视图
Master-multiworker 多任务处理
代码热加载
简单易用的路由规则
结束语
上面提到的所有技术不只适用于 Python,也同样可以被应用到其它语言,如 Ruby、JavaScript,甚至 PHP 等。
在此要感谢 Python 社区为优化性能所付出的持续投入。尤其是 Victor Stinner @VictorStinner、INADA Naoki @methane 和 Yury Selivanov @1st1 以及整个 PyPy 团队。
献给我挚爱的 Python。
原文链接:
https://blog.csdn.net/sinat_38682860/article/details/72862220
识别图中二维码,领取python全套视频资料
用 Python 实现每秒处理 120 万次 HTTP 请求的更多相关文章
- 使用Python抓取猫眼近10万条评论并分析
<一出好戏>讲述人性,使用Python抓取猫眼近10万条评论并分析,一起揭秘“这出好戏”到底如何? 黄渤首次导演的电影<一出好戏>自8月10日在全国上映,至今已有10天,其主演 ...
- CYQ.Data 批量添加数据性能测试(每秒千、万)
今天有网友火晋地同学进了CYQ.Data官方群了,他正在折腾了一个各大ORM性能测试的比较的软件,如下图 折腾的种类也不少: 感觉这软件折腾的不错~~~值的期待~~~ 另外,他指出CYQ.Data 在 ...
- [原创]K8一句话密码爆破工具{秒破10万} 支持ASP/PHP/ASPX/JSP/CFM/DIY
工具: K8_FuckOneShell 20161224编译: VS2012 C# (.NET Framework v4.0)组织: K8搞基大队[K8team]作者: K8拉登哥哥博客: http ...
- CYQ.Data 批量添加数据性能测试(每秒千、万)---003
原文地址:https://www.cnblogs.com/cyq1162/p/3216267.html 今天有网友火晋地同学进了CYQ.Data官方群了,他正在折腾了一个各大ORM性能测试的比较的软件 ...
- [转帖]支撑双11每秒17.5万单事务 阿里巴巴对JVM都做了些什么?
支撑双11每秒17.5万单事务 阿里巴巴对JVM都做了些什么? https://mp.weixin.qq.com/s?__biz=MzA3OTg5NjcyMg==&mid=2661671930 ...
- 让Windows Server 2008 + IIS 7+ ASP.NET 支持10万个同时请求
具体设置如下: 1. 调整IIS 7应用程序池队列长度 由原来的默认1000改为65535. IIS Manager > ApplicationPools > Advanced Setti ...
- 优化IIS7.5支持10万个同时请求的配置方法
通过对IIS7的配置进行优化,调整IIS7应用池的队列长度,请求数限制,TCPIP连接数等方面,从而使WEB服务器的性能得以提升,保证WEB访问的访问流畅. IIS7.5是微软推出的最新平台IIS,性 ...
- [转]优化IIS7.5支持10万个同时请求的配置方法
通过对IIS7的配置进行优化,调整IIS7应用池的队列长度,请求数限制,TCPIP连接数等方面,从而使WEB服务器的性能得以提升,保证WEB访问的访问流畅 通过对IIS7的配置进行优化,调整IIS7应 ...
- 让Windows Server 2008+IIS 7+ASP.NET支持10万个同时请求
具体设置如下: 1. 调整IIS 7应用程序池队列长度 由原来的默认1000改为65535. IIS Manager > ApplicationPools >Advanced Settin ...
随机推荐
- 一款基于css3的散子3D翻转特效
css3使我们能够跳出2d空间,实现3维空间的动画效果,这里给出一个自动翻转的3d色子动画效果制作过程. 第一步,首先进行HTML的布局,对于3D效果,布局有一定的规律,代码如下: <body& ...
- SenCha Touch HTML 5 应用程序缓存
http://www.cnblogs.com/qidian10/p/3292876.html https://developer.mozilla.org/zh-CN/docs/HTML/Using_t ...
- 2018-11-17 js的this引起的血案
js的this. 昨天测试,删除商品会报错,马上去测了一把,的确会报错.为毛线呢? SubOrderItem: function (orderitem) { if (orderitem.ordernu ...
- Jquery右下角消息提示框
找了好久,终于找到一个不错的提示框jquery,免费给大家一起用下吧(可是花了我很多积分哦),顺便重写了一下样式,原来的样式真的不敢恭维啊... 下载地址:http://files.cnblogs.c ...
- Libgdx window add alpha action change the background actor alpha
现象: Stage中包括一个Window,一个Actor,Window中加入alpha action后,Actor也随之消失:Actor加入alpha action后,不起作用. 解决: 重写draw ...
- mongodb和redis设计原理简析
转自:http://blog.csdn.net/yangbutao/article/details/8309539 redis: 1.NIO通信 因都在内存操作,所以逻辑的操作非常快,减少 ...
- 按SCI影响因子排序的前50人工智能期刊列表
附录二:按SCI影响因子排序的前50人工智能期刊列表 出版物名称,影响因子 IEEE TRANSACTIONS ON FUZZY SYSTEMS, 6.701 International Jou ...
- php -- php缓存技术
为了尽量减少不必要的数据库查询,我对一些数据进行了缓存和静态化处理. 缓存的原理:把一些经常要用到但又很少改动的数据以数组或其它形式存储到一个独立的PHP文件中,然后在需要用到的时候包含进来. 缓存的 ...
- 【BZOJ】1638: [Usaco2007 Mar]Cow Traffic 奶牛交通(dfs+dp)
http://www.lydsy.com/JudgeOnline/problem.php?id=1638 一条边(u, v)经过的数量=度0到u的数量×v到n的数量 两次记忆化dfs算出他们即可 #i ...
- InstallShield Build Error -1014: Cannot rename directory <PATH> to <PATH>\folder.Bak.
InstallSheild执行Build结果错误: 错误详细信息: Cannot rename directory <PATH> to <PATH>\folder.Bak. W ...