最后更新:2020-03-25 13:04:09 手机定位技术交流文章
序言
无意中看到了一篇文章《提100亿的要求——如何为春晚打造一个“确定”的红包系统》。读完之后,我觉得受益匪浅。俗话说,另一座山的石头可以用来攻击玉。虽然这篇文章发表于2015年,但我已经很久没有看到它了,但是它的思想仍然可以被许多后端设计所借鉴。
也是微信的后端工程师。读完之后,他会再想一想。学完这些文章后,他能给自己的工作带来一些实践经验吗?所谓的纸来自我的头脑,我知道我必须自己做。我可以练习100亿次索要红包吗?否则,读完之后,我脑海里只剩下100.14亿QPS整风这样的字眼。本文的其余部分将展示作者如何在本地环境中以这个过程为目标来模拟这个过程。
达到的目标:单机支持100万个连接,模拟震动红包和发出红包的过程,单机QPS峰值为6万,稳定支持业务。
注:本文和作者的所有内容仅代表个人的理解和实践。这个过程与微信团队无关,真正的在线系统也是不同的。它只是从一些技术角度进行了实践。请区分读者。
背景知识
qps:每秒查询数每秒请求数
PPS:packets每秒数据包数
抖红包:客户发出抖红包的请求。如果系统有一个红包,它将返回,用户将收到红包。
红包:生成一个包含一定金额的红包。红包指定了几个用户。每个用户都会收到红包信息。用户可以发送一个请求来打开红包并获得一部分金额。
确定目标
在所有系统启动之前,我们应该了解我们的系统在完成后应该具有什么样的负载能力
用户总数
通过本文我们可以了解到638个接入服务器,服务上限约为14.3亿用户,因此单机负载的用户上限约为14.3亿/638 = 228万用户/台
,但中国肯定不会同时有14亿在线用户。据http://qiye.qianzhan.com/show/detail/160818-b8d1c700.html, Q2报道,微信用户在2016年将达到8亿,月寿命约为5.4亿。所以在2015年春节期间,虽然会有很多用户,但同时在线的用户肯定会少于5.4亿。
服务器数量
总共有638台服务器。根据正常的操作和维护设计,我相信所有的服务器不会完全在线,并且会有一些硬件冗余来防止突然的硬件故障假设有600台接入服务器
单台机器每台服务器需要支持
个用户:5 . 4亿/600 = 900,000也就是说,平均每台机器支持90万用户。如果真实情况超过900,000,那么模拟情况可能会偏离,但我认为QPS在这个实验中更重要。
单机峰值QPS
文章明确指出1400万QPS这个值非常高,但是因为有600台服务器,一台机器的QPS值是1400万/600=大约23000 QPS。文章曾提到,该系统可以支持4000万QPS,那么该系统的QPS应该至少为4000万/600 =约66000,这大约是当前值的三倍,短期内不会被触及。但是我相信我应该做相应的压力测试。文章中提到的
红色数据包
系统以每秒50,000的速度传送,然后单机以每秒50,000/600 = 83的速度传送,也就是说,单机系统应该确保它以每秒83的速度传送。
最终考虑了系统的真实性,并且至少有用户登录动作。真正的系统还将包括聊天等服务
最后看一下对100亿个红包的需求。假设在春节联欢晚会的4个小时内,服务器的QPS应该是1000000000/600/3600/4.0 = 1157也就是说,一台机器每秒钟有1000次以上,这实际上并不高。如果
被1400万的峰值速度完全消化,100000000/(1400 * 10000) = 714秒,也就是说,所有请求只有在峰值持续11分钟后才能完成。可以看出,互联网产品的一个特点是峰值很高,持续时间不是很长。
摘要
从单个服务器的角度来看,它需要满足以下条件:
①支持至少100万个连接用户
(2)每秒至少可以处理23,000 QPS,这里我们将目标分别设置为30,000和60,000。
③摇动红包:支持以每秒83个的速率分发红包,也就是说,每秒有23,000个摇动红包的请求,其中83个可以摇动红包,其余22,900个请求将知道它们没有摇动红包。当然,客户收到红包后,也要确保客户和服务器双方的红包数量与红包数量一致。由于没有支付模块,我们将请求速度提高了一倍,达到每秒200个红色数据包。
④支持用户之间发送红包的业务,确保双方发送和接收的红包数量与红包金额一致。我们还将每秒200个红色数据包的速度设定为我们的目标。
真的很难完全模拟整个系统。首先,它需要大量的服务器,其次,它需要数亿个模拟客户端。这对我来说是不可能的,但有一点是肯定的,整个系统可以水平扩展,所以我们可以模拟100万个客户端,然后模拟一个服务器,然后完成1/600模拟。
与现有系统不同:与大多数高QPS测试不同,该系统的重点不同。我对两者做了一些比较。

基本软硬件
软件
格朗1.8r3、shell、python(开发时没有使用C++而是使用格朗,因为使用格朗的原始原型满足了系统要求尽管格朗仍存在一些问题,但与开发效率相比,这种损失是可以接受的)
服务器操作系统:Ubuntu 12.04
客户端操作系统:debian 5.0
硬件环境
服务器:戴尔R29508核物理机,不拥有工作中的其他业务,16G内存这种硬件是大约7年前的产品,其性能要求应该不是很高。
服务器硬件版本:

服务器CPU信息:

客户端:esxi 5.0虚拟机,配置为4核5G内存总共17个,每个服务器有60,000个连接完成100万个客户端模拟
技术的分析与实现在一台机器上连接
到100万用户相对简单。作者几年前在一台机器上完成了100万用户的开发和操作。现代服务器可以支持数百万用户。相关内容可查看github代码和相关文档、系统配置和优化文档。
参考链接:
佳AQI/c100 kpraceguide
佳AQI/c100 kprace guide/tree/master/docs/cn
3百万QPS
这个问题需要分成两部分来看客户端和服务器端
1)客户端QPS
因为有100万个到服务器的连接,所以QPS是30,000个这意味着每隔33秒钟,每个连接都需要向服务器发送一个请求,以摆脱红色信封因为单个IP可以建立的连接数约为60,000,所以17台服务器同时模拟客户端行为。我们必须做的是确保每秒钟向服务器发送这么多请求。
,其中技术关键点是客户合作然而,每个客户端的启动时间和连接建立时间是不一致的,并且还存在网络断开和重新连接的情况。每个客户端如何确定何时需要发送请求,以及每个客户端应该发送多少请求?
我这样解决了这个问题:使用NTP服务来同步所有服务器时间,客户端使用时间戳来确定此时需要发送多少请求。
算法易于实现:假设有100万用户,用户id为0-999999。所需的QPS是50,000。客户知道QPS有50,000名用户,用户总数为100万。它计算100万/50,000 =20。所有用户应该被分成20组。如果时间% 20 ==用户id% 20,该id的用户应该在这一秒内发出请求,从而实现多客户端协同工作每个客户只需要知道用户总数和QPS,就可以准确地发出请求。
扩展思维:如果QPS是30,000,不能被整除,我们该怎么办?我们如何确保每个客户端的请求数量尽可能平衡?
2)服务器QPS QPS
服务器端QPS相对简单,它只需要处理客户端的请求然而,为了客观地了解情况,我们仍然需要做两件事。
first:需要记录每秒处理的请求数,这需要在代码中嵌入一个计数器
秒:网络需要监控,因为网络的吞吐量能够客观地反映QPS的真实数据为此,我使用python脚本和ethtool工具编写了一个简单的工具,通过它我们可以直观地监控通过网络的数据包它可以客观地显示出在我们的网络中正在发生如此多的数据传输。
工具截图:

红包甩卖业务
红包甩卖业务非常简单。首先,服务器以一定的速度制作红包如果红包没有被拿走,它们就会堆积起来。服务器接收来自客户端的请求。如果服务器中有红包,它会告诉客户端有,否则会提示没有红包。
因为一台机器每秒有30,000个请求,所以大多数请求都会失败。只需要处理锁的问题
为了减少竞争,我将所有用户分成不同的类别。这可以减少对锁的竞争。如果将来有更高的性能要求,可以使用高性能队列中断或来进一步提高性能。
请注意,在我的测试环境中,这一核心服务的费用很少,因此实现难度大大降低另一组数据显示:2016年淘宝双11的交易峰值仅为12万次/秒,微信红包的分发速度为5万次/秒,这很难实现。
参考链接:
http://mt.sohu.com/2016111/n472951708.shtml
红包业务
红包业务非常简单,系统随机生成一些红包,并随机选择一些用户,系统用红包提示这些用户这些用户只需发出一个打开红包的请求,系统就可以从红包中随机分出一部分金额,分发给用户完成业务。同样,这项核心服务在这里也不收费。
监控
最后,我们需要一个监控系统来了解系统的状态。我从我的另一个项目中借用了一些代码来完成这个监控模块。使用这种监控,服务器和客户端将向监控发送当前计数器内容,监控需要集成和显示每个客户端的数据。同时,日志将被记录下来,为以后的分析提供原始数据。在线系统使用更多的时间序列数据库,如opentsdb,那里的资源是有限的,所以使用一个原始的方案。
参考链接:
嘉AQI/fakew echat
监控和显示日志是这样的:

代码实现和分析
在代码方面,使用的技术并不多,主要是设计思路和戈兰自身的问题需要考虑。
首先控制Golang的goroutine的数量,因为至少有100多万个连接,所以根据通用设计方案,至少需要200万或300万个go例程才能工作。这将对系统本身造成沉重的负担。
之后是管理100万个连接,连接和业务都会造成一些精神负担。
我的设计如下:
首先将100万个连接分成多个集合,每个集合是一个独立的并行对象每个SET只管理数千个连接。如果单个SET工作正常,我只需要添加SET来提高系统的处理能力。
,然后仔细设计每个SET中的数据结构的大小,以确保每个SET的压力不会太大,并且不会有消息的累积。
再次减少了GC routine的数量,每个连接只使用一个goroutine,并且一个SET中只有一个GC routine负责发送消息,因此节省了100万个GO routine这样,整个系统只需要保留100万和数百个gcroutine来完成业务。大大节省了cpu和内存
系统的工作流程大致如下:每个客户端连接成功后,系统会分配一个路由器读取客户端的消息。当消息读取完成时,它将被转换成一个消息对象,并放入SET中的接收消息队列,然后返回以获取下一条消息。
在SET里面,有一个goroutine工作,它只做非常简单和高效的事情,它做下面的事情,检查SET的接受消息,它会收到三种类型的消息:
客户抖红包请求消息;来自
客户的其他消息,如聊天朋友;
服务器对客户端消息的响应
以这种方式处理第一条消息。从客户那里获取抖动红包的请求消息,尝试从SET的红包队列中获取一个红包,如果得到了,将红包信息返回给客户,否则,构造一个没有抖动的消息,并返回给相应的客户
对于第二条消息,只需从队列中取出消息,并将其转发到后端的聊天服务队列。其他服务将转发该消息
对于第三条消息,SET只需要根据消息中的用户标识找到SET中保留的用户连接对象并发送回去
为红包生成服务,其工作非常简单,只需要依次将红包对象放置在每个SET的红包生成队列中这可以确保每个器械包的公平性。其次,它的工作强度很低,可以保证稳定的业务。
参考链接:
贾AQI/100亿红宝
练习
练习过程分为三个阶段
阶段1
分别启动服务器端和监控端,然后逐一启动17个客户端,建立100万条链路在服务器端,ss命令用于计算每个客户端和服务器之间建立了多少个连接
命令如下:
别名ss2 = ss-ant | grep 1025 | grepst | awk-f:" { print $ 8 } " | sort | uniq-c '
结果如下:

阶段2
使用客户端的http接口将所有客户端QPS调整为30,000,允许客户端发出3W QPS强度请求
运行以下命令:

观察网络监控和来自监控端的反馈,发现QPS达到预期数据。网络监控截图:

启动了一项在服务器端生成红包的服务,以每秒200的速度发送红包,总计40,000个此时,如果您查看监视器上客户端的日志,您会发现您基本上以每秒200的速度获得了红色数据包。

等到所有的红包都发完了,再启动红包分发服务。服务系统将产生20,000个红包,也就是每秒200个。每个红包将随机指定3个用户,并向这3个用户发送消息。客户会自动取走红包,最后所有的红包都会被取走。

阶段3
使用客户端的http接口将所有客户端的QPS调整到60,000,允许客户端发出6W QPS强度的请求

做了同样的事情。在服务器端,启动了一项生成红包的服务。这项服务将以每秒200个的速度分发红包,总共40,000个此时,如果您查看监视器上客户端的日志,您会发现您基本上以每秒200的速度获得了红色数据包。
等到所有红包都发完了,再开始红包分发服务。服务系统将产生20,000个红包,也就是每秒200个。每个红包将随机指定3个用户,并向这3个用户发送消息。客户会自动取走红包,所有的红包最终都会被取走
最后,练习结束
分析数据
实际上,服务器和客户端都将它们的内部计数器记录发送到监控端并成为日志我们使用简单的python脚本和gnuplt绘图工具来可视化实际过程,从而验证运行过程
的第一部分是客户端发送的QPS数据:

的横坐标是时间,单位是秒,纵坐标是QPS,表示此时所有客户端发送请求的QPS。
图的第一个间隔有几个小峰,由100万个客户端连接。图表的第二个区间是30,000 QPS区间。我们可以看到,数据在30,000个区间内相对稳定。最后是60,000 QPS区间然而,从整个画面可以看出,QPS并没有完美地保持在我们想要的直线上。这主要是由以下原因造成的:
①当多条数据线同时运行时,睡眠时间不准确,出现偏移。我认为这是由戈朗自己的时间安排造成的当然,如果cpu相对强大,这种现象就会消失。
②由于网络的影响,客户端在启动连接时可能会有延迟,导致在前1秒内无法完成连接。当
③服务器负载较大时,1000M网络出现丢包,这可以通过ifconfig命令观察到,所以QPS会有波动第二部分
是服务器处理的QPS图:

对应客户端,服务器也有3个间隔,非常接近客户端的情况。然而,我们看到在大约22: 57,系统的处理能力明显下降,然后急剧增加。这表明代码仍然需要优化
的总体观察表明,在30,000 QPS区间,服务器的QPS相对稳定,在60,000 QSP区间,服务器的处理不稳定。我相信这和我的代码有关。如果继续优化,应该会有更好的结果。
结合了两张地图:

基本一致,这也证明了系统达到了预期的设计
这是生成的红色数据包数量的状态变化图:

非常稳定
这是客户端每秒获得的抖动红色数据包的状态:

可以找到30,000 QPS的范围。客户端每秒获得的红色数据包数量基本上在200个左右。在60,000 QPS,有严重的摇晃,没有价值200的保证。我认为当主要是60,000 QPS时,网络的抖动增加了,导致红色数据包的数量也抖动了。
最终是Golang自己的pprof信息,其中gc时间超过10ms。考虑到这是一个有7年历史的硬件和非独占模式,它仍然是可以接受的。

摘要
根据设计目标,我们模拟并设计了一个支持100万用户的系统,每秒至少可以支持30,000 QPS和60,000 QPS。我们简单地模拟了在微信上摇晃和发红包的过程可以说达到了预期的目标
如果600台主机每个可以支持60,000个QPS,只需7分钟就可以完成100亿个请求来发送红色数据包。
虽然这个原型只是完成了预设的业务,但它和真正的服务有什么区别?我列出了

>。>。>。>。
参考文献
单机实践百万
https://github.com/Xiao JAAQI/C1000 KPRATICEGUIDE
如何在AWS上实现百万用户压力
https://github.com/Xiao JAAQI/Fakewhat/wiki/压力测试云中构建您自己的微信式系统
https://github . com/焦姣qi/faf提交的电子邮件地址是editor@dbaplus.cn
>。>。>。>。
2年4月17日020,北京,全球敏捷运营峰会将迎来今年的第一站!专注于数据库、智能运维、金融科技等领域,与阿里、腾讯、蚂蚁金服、中国银行、平安银行、中国邮政消费金融、中国建设银行、农业银行、民生银行、中国联通大数据、浙江移动、新居网络等技术代表合作。展望云时代数据库的发展趋势,解决运维转型的困境
本文由 在线网速测试 整理编辑,转载请注明出处。