本文主要是介绍如何扛住100亿次请求?后端架构应该这样设计!,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
点击上方“朱小厮的博客”,选择“设为星标”
回复”1024“获取独家整理的学习资料

- QPS:Queries per second 每秒的请求数目
- PPS:Packets per second 每秒数据包数目
- 摇红包:客户端发出一个摇红包的请求,如果系统有红包就会返回,用户获得红包
- 发红包:产生一个红包里面含有一定金额,红包指定数个用户,每个用户会收到红包信息,用户可以发送拆红包的请求,获取其中的部分金额。
- 支持至少100万连接用户
- 每秒至少能处理2.3万的QPS,这里我们把目标定得更高一些 分别设定到了3万和6万。
- 摇红包:支持每秒83个的速度下发放红包,也就是说每秒有2.3万次摇红包的请求,其中83个请求能摇到红包,其余的2.29万次请求会知道自己没摇到。当然客户端在收到红包以后,也需要确保客户端和服务器两边的红包数目和红包内的金额要一致。因为没有支付模块,所以我们也把要求提高一倍,达到200个红包每秒的分发速度
- 支持用户之间发红包业务,确保收发两边的红包数目和红包内金额要一致。同样也设定200个红包每秒的分发速度为我们的目标。
服务器CPU信息:
客户端:esxi 5.0 虚拟机,配置为4核 5G内存。一共17台,每台和服务器建立6万个连接。完成100万客户端模拟 系统配置以及优化文档:
https://github.com/xiaojiaqi/C1000kPracticeGuide/tree/master/docs/cn 5.2) 3万QPS 这个问题需要分2个部分来看客户端方面和服务器方面。
客户端QPS
算法很容易实现:假设有100万用户,则用户id 为0-999999.要求的QPS为5万, 客户端得知QPS为5万,总用户数为100万,它计算 100万/5万=20,所有的用户应该分为20组,如果 time() % 20 == 用户id % 20,那么这个id的用户就该在这一秒发出请求,如此实现了多客户端协同工作。每个客户端只需要知道 总用户数和QPS 就能自行准确发出请求了。 (扩展思考:如果QPS是3万 这样不能被整除的数目,该如何办?如何保证每台客户端发出的请求数目尽量的均衡呢?)
服务器QPS
- 第一:需要记录每秒处理的请求数目,这需要在代码里埋入计数器。
- 第二:我们需要监控网络,因为网络的吞吐情况,可以客观的反映出QPS的真实数据。为此,我利用python脚本 结合ethtool 工具编写了一个简单的工具,通过它我们可以直观的监视到网络的数据包通过情况如何。它可以客观的显示出我们的网络有如此多的数据传输在发生。
我为了减少竞争,将所有的用户分在了不同的桶里。这样可以减少对锁的竞争。如果以后还有更高的性能要求,还可以使用 高性能队列——Disruptor来进一步提高性能。 注意,在我的测试环境里是缺少支付这个核心服务的,所以实现的难度是大大的减轻了。另外提供一组数字:2016年淘宝的双11的交易峰值仅仅为12万/秒,微信红包分发速度是5万/秒,要做到这点是非常困难的。(http://mt.sohu.com/20161111/n472951708.shtml)
- 客户端的摇红包请求消息
- 客户端的其他消息 比如聊天 好友这一类
- 服务器端对客户端消息的回应
对于第2种消息客户端的其他消息 比如聊天 好友这一类,只需简单地从队列里拿走消息,转发给后端的聊天服务队列即可,其他服务会把消息转发出去。
对于第3种消息服务器端对客户端消息的回应。SET 只需要根据消息里的用户id,找到SET里保留的用户连接对象,发回去就可以了。 对于红包产生服务,它的工作很简单,只需要按照顺序在轮流在每个SET的红包产生对列里放至红包对象就可以了。这样可以保证每个SET里都是公平的,其次它的工作强度很低,可以保证业务稳定。
见代码: https://github.com/xiaojiaqi/10billionhongbaos
Alias ss2=Ss –ant | grep 1025 | grep EST | awk –F: “{print \$8}” | sort | uniq –c’ 结果如下:
观察网络监控和监控端反馈,发现QPS 达到预期数据,网络监控截图:
在服务器端启动一个产生红包的服务,这个服务会以200个每秒的速度下发红包,总共4万个。此时观察客户端在监控上的日志,会发现基本上以200个每秒的速度获取到红包。
等到所有红包下发完成后,再启动一个发红包的服务,这个服务系统会生成2万个红包,每秒也是200个,每个红包随机指定3位用户,并向这3个用户发出消息,客户端会自动来拿红包,最后所有的红包都被拿走。
如法炮制,在服务器端,启动一个产生红包的服务,这个服务会以200个每秒的速度下发红包。总共4万个。此时观察客户端在监控上的日志,会发现基本上以200个每秒的速度获取到红包。 等到所有红包下发完成后,再启动一个发红包的服务,这个服务系统会生成2万个红包,每秒也是200个,每个红包随机指定3位用户,并向这3个用户发出消息,客户端会自动来拿红包,最后所有的红包都被拿走。 最后,实践完成。 8. 分析数据 在实践过程中,服务器和客户端都将自己内部的计数器记录发往监控端,成为了日志。我们利用简单python 脚本和gnuplt 绘图工具,将实践的过程可视化,由此来验证运行过程。 第一张是客户端的QPS发送数据:
这张图的横坐标是时间,单位是秒,纵坐标是QPS,表示这时刻所有客户端发送的请求的QPS。 图的第一区间,几个小的峰值,是100万客户端建立连接的, 图的第二区间是3万QPS 区间,我们可以看到数据 比较稳定的保持在3万这个区间。最后是6万QPS区间。但是从整张图可以看到QPS不是完美地保持在我们希望的直线上。这主要是以下几个原因造成的
- 当非常多goroutine 同时运行的时候,依靠sleep 定时并不准确,发生了偏移。我觉得这是golang本身调度导致的。当然如果cpu比较强劲,这个现象会消失。
- 因为网络的影响,客户端在发起连接时,可能发生延迟,导致在前1秒没有完成连接。
- 服务器负载较大时,1000M网络已经出现了丢包现象,可以通过ifconfig 命令观察到这个现象,所以会有QPS的波动。
和客户端的向对应的,服务器也存在3个区间,和客户端的情况很接近。但是我们看到了在大概22:57分,系统的处理能力就有一个明显的下降,随后又提高的尖状。这说明代码还需要优化。 整体观察在3万QPS区间,服务器的QPS比较稳定,在6万QSP时候,服务器的处理就不稳定了。我相信这和我的代码有关,如果继续优化的话,还应该能有更好的效果。 将2张图合并起来 :
基本是吻合的,这也证明系统是符合预期设计的。 这是红包生成数量的状态变化图:
非常的稳定。 这是客户端每秒获取的摇红包状态:
可以发现3万QPS区间,客户端每秒获取的红包数基本在200左右,在6万QPS的时候,以及出现剧烈的抖动,不能保证在200这个数值了。我觉得主要是6万QPS时候,网络的抖动加剧了,造成了红包数目也在抖动。 最后是golang 自带的pprof 信息,其中有gc 时间超过了10ms, 考虑到这是一个7年前的硬件,而且非独占模式,所以还是可以接受。
Refers: - 单机百万的实践
- https://github.com/xiaojiaqi/C1000kPracticeGuide
- 如何在AWS上进行100万用户压力测试
- https://github.com/xiaojiaqi/fakewechat/wiki/Stress-Testing-in-the-Cloud
- 构建一个你自己的类微信系统
- https://github.com/xiaojiaqi/fakewechat/wiki/Design
- http://djt.qq.com/article/view/1356
- http://techblog.cloudperf.net/2016/05/2-million-packets-per-second-on-public.html
- http://datacratic.com/site/blog/1m-qps-nginx-and-ubuntu-1204-ec2
- @火丁笔记
- http://huoding.com/2013/10/30/296
- https://gobyexample.com/non-blocking-channel-operations
项目地址:https://github.com/xiaojiaqi/
10billionhongbaos
权申明:内容来源网络,版权归原创者所有。除非无法确认,我们都会标明作者及出处,如有侵权烦请告知,我们会立即删除并表示歉意。谢谢。
想知道更多?扫描下面的二维码关注我

相关推荐:
《科普 | 明星公司之Netflix》
《看我如何作死 | 将CPU、IO打爆》
《看我如何作死 | 网络延迟、丢包、中断一个都没落下》
《7102-2019年技术文全套整理,建议收藏》
《看我如何假死!》
《总结缓存使用过程中的几种策略以及优缺点组合分析》
加技术群入口(备注:技术):>>>Learn More<<
免费资料入口(备注:1024):>>>Learn More<<
免费星球入口:>>>Free<<<
点个"在看"呗^_^
这篇关于如何扛住100亿次请求?后端架构应该这样设计!的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!