目录
2.5.1、服务中的内存泄漏会持续增高服务程序的“工作集(KB)”
2.5.4.1、不要让用户直接Logon到服务器成为独立的操作系统级别的会话
2.5.4.3、不要在服务器内启用office应用或其服务供应用直接调用
2.5.4.4、不要在服务器内直接远程开启QQ、微信等社交工具、资源浏览器服务而不注销
浅谈服务器http并发数的影响因素
一、问题的提出
比如,你租用了一个腾讯云服务器Server1,基本配置为:Intel(R) Xeon(R) Gold 6133 CPU @ 2.50GHz 8核16G(cpu:内存=1:2)5MBps带宽。你在这台服务器上部署好了你的应用服务MyService1,请问,MyService1最多能同时承载多少有效的http请求?即:MyService1在虚拟机Server1上http最大并发量是多少?为了便于更多人能够理解,本文尽量避免使用“深奥”的专业术语,而使用浅显易懂的描述方式。
1.1、讨论此问题的假设(基本条件)
假设,客户端的网络、设备基础设施、App是稳定的、客户端的计算机(含手机)环境是健康的,假设云服务器的网络、设备基础设施、提供服务的MyService1是稳定的、服务是健康的、服务本身是有高承压能力的(比如连续上亿次循环的客户端的5kb的简单线程请求),服务器上只运行着MyService1和基本的大型数据库(比如MS Sql Server), 没有其它活动的乱七八糟的第三方软件进程,服务器是“干净的”。在此基础之上,讨论此话题,否则没有可比性。
1.2、计量时间
统一为每秒。即:每秒并发数的上限是多少?亦即:每秒并发的有效请求的上限是多少?
二、讨论影响因素
过去,我们常用的方法,就是经验值。即:服务做统计,统计请求被有效响应的次数。直到服务器拖不动了,用户出问题了,才知道大致的并发上限。作为今后的参考值。当然,要看什么应用、用户的损失情况而定了,这种不能作为最终的评估标准。因为它是事后的。
2.1、首先要评估客户端应用(下文统称App)本身
打个比方,App1是存在数据库的普通数据类型,不存在图形数据类型和No-Sql数据,单次请求的响应不超过1024Kb;App2是混合型的,既有数据库普通数据类型、还有No-Sql数据(比如在客户端应用的很多环节存在上传或下载图片、文件等资源)。
显然App1和App2,在我们讨论此问题时,影响因素就会不同。
在现代化的应用中,App2很普遍了。就以App2的情形,作为比较的前提。
2.2、单位时间的请求次数并不能代表“并发上限”
我们有不少网友认为,并发上限就是我统计的“单位时间内的请求次数”,它只代表了“事后统计”的服务MyService1可承载“压力”的极限,属于“压力测试”,其中并未体现实时的“字节”变化,对服务器的内存I/O读写、硬盘I/O读写、网络I/O读写、cpu使用率是否长期处于高于85%甚至长期处于97%的水平,是全然不知的,服务器今后还能增加多少客户端请求,也是茫然的。
服务器的内存I/O读写、硬盘I/O读写、网络I/O读写、cpu使用率,这些关键因子,都会造成某些时间,我们的服务器已经“太累了”,已经服务器“拖不动”了,从而影响应用App2对客户服务的“可靠性”。服务的“可靠性”差了,一次、两次,用户能忍受,长此以往,客户就“放弃了”。
2.3、服务端的5Mbps带宽什么时候网路会拥堵
打个比方吧,高速公路4车道、如果把临时占道也算上(意思是你的道路开了多宽的口子,同时能过几个通道的车),就好比5MB,那么单位时间内,能在不堵塞的情况下正常通过多少车辆,就代表了我们这带宽5Mbps的正常的“网络高速公路”的吞吐能力。当然,前提是,这5Mbps是“独享”的真实流量速率,而非“共享带宽”,即:其真实的线路速率为下行5Mbps;上行带宽要根据云服务平台(或托管机房的运营商说明)的购买说明,比如腾讯云(购买的下行带宽<=10Mbps,上行就10Mbps;否则两者对等)。
网络并发能力怎么计算呢,可用“极限倒推法”,云服务器网卡的线路速率一般虚拟化部署为10Gbps,比如本案,8核心、5Mbps线路:
× 接入-汇聚 : N个接入数( =1280Mbps / (5 Mbps) ) * 1280Mbps
= 总接入能力10240Mbps / 8 = 1280Mbps --------接入层
× 汇聚-核心 : 8 * (总接入能力=10240Mbps / 8)
= 10Gbps = 10240Mbps --------汇聚层
× 核心-服务器 :4*10Gbps
= 3-5XGE --------核心层(只与云平台相关)
极限接入数N = 1280Mbps /5 Mbps = 如果用户同时传输5mb字节的数据,每秒256个接入将这5Mb的带宽消耗殆尽。这是下行(比如下载时),上行就是512个并发接入。
现在,我们同时传输16mb字节的数据:N = 256 * (5/16) = 80个并发接入(下行下载);上行160个并发接入(上行上传),如下:
App2内部,如果存在这样的上传任务,单次上传16mb的高清图片到服务器,而这16mb没有经过代码处理,那么并发时,就很容易“堵塞”。为什么呢,如果每秒,同时有200个用户同时按下“上传”按钮,那么等它们传输的16Mb字节,到达服务器的网卡,单个请求(此时内存读写、硬盘读写都不会有问题,假如它们的吞吐能力为0.0S秒的速度),就在此时刻已经将带宽5MB在0.0S秒的时刻内占满了,如果S=5,那么最多10个并发就会开始严重“拥堵”了,后面190个客户请求,要么来不及指派请求、要么响应超时(说起响应,客户端设置的响应超时如果>2秒,对用户而言就开始不友好了),因为我们这个是“极限数值”。当然,客户端网络,现如今能有保障,5G是很快、很稳定的。问题主要还是在服务端要有保障。
所以我们的App2内部,必须要对此类“业务”,做技术处理,要分段分块上传,比如每个分块为102.4kb,共将这16m的资源,分为160个字节数组块,分段上传、断点续传。这样,102.4kb相对于我们带宽5MBps的服务器网路来说,在1秒内我们就可以同时并发50个到服务器网卡端的响应接收,将这连续不断的50个102.4kb的响应顺利通过【每秒50个并发接入的客户端请求(50*160个分块=5120Kb=5Mb)】,就像上面“高度公路”的例子,能顺利的通行而不阻塞;那么到最终客户端,整机是完全能承载较高的连续请求的。最终,呈现给客户的视觉效果,就是“进度条”在不停的向后延伸,直到100%上传完毕;否则,用户的“进度条”感觉就没动静。“断点分块续传”能有效的缓解服务器的带宽的通道压力。
这里面有一个技巧:就是在客户端请求和服务端响应时,代码中给一个范围内的随机延时,比如范围为[1000ms,2000ms]之间,这样,来自客户端的请求也好,服务端的响应也好,都不会再是高粒度的,也能有效的增强并发能力。
这里需要注意的是:第三方DNS域名解析服务和https请求也会降低并发能力。https增加传输的安全性,由于第三方SSL服务机构的原因,通常免费版的SSL与单纯的http请求比较,会将并发能力降低1倍。
1天总共有86400秒,如果你的应用是面向常规企业的应用,通常这个企业会集中在8小时工作时间内(即28800秒内进行)进行客户端的操作请求,同时并发的可能性也会降低很多。
同样的道理,我们请求数据库,要分页请求,每页请求20~40笔,大约每页1kb/10的信息量(当然这要分功能模块具体问题具体分析),不要一次性就请求就成千上万笔记录,“分页请求”数据库资源同样会有效缓解服务器的带宽通道压力。
将上传、下载的资源,以压缩的字节流的方式分块处理,会极大提升并发能力。
2.4、服务器CPU何时会疲劳
Intel(R) Xeon(R) Gold 6133 CPU @ 2.50GHz 8核处理器,处理能力和算力是非常强劲的。为什么呢。这样的处理器,首先主频率2.50GHz代表什么?2.5*1024m=2560兆赫兹,“赫兹”是什么,是频率的计量单位,它代表了每秒的波动次数=2560兆次振动/秒。它代表了处理单个线程的能力,是让线程内部“自旋”2560兆次/秒的处理能力。上面我们断点续传分了160个段,此处理器简直不在话下。
其次,虽然它只分配了1个CPU插槽(1路Socket,即我们通常所说的1路处理器),但它有8核,8个逻辑处理核心,即8个虚拟处理器。还是用上面的例子,还是16m,但不是简单地上传高清图片了,而是16m分段续传的“语音”,服务MyService1需要为客户提供“语音识别”的功能,将这160个分段,转成文字。很明显,这个任务,相比简单上传“图片”的分块、最后将字节组装还原,需要“考验”CPU的算力,是很“耗时”的操作,单核心,可能就比较糟糕了;此时,服务器操作系统内核,会自动调配CPU的逻辑核心,让更多的CPU虚拟处理器参与到这160个“语音分块”的计算中来,当然前提是你的代码要请求CPU并行地作业,而不是按先后次序进行“队列”作业(队列作业会浪费多核心的CPU配置资源),从而顺利地让多核心同时作业,无“卡顿”地将用户的语音,还原成文字翻译。“多核心处理器”和“并行处理”能增强客户并发的能力,如上,50个客户端并发“语音识别”请求,Intel(R) Xeon(R) Gold 6133 CPU @ 2.50GHz 8核处理器,以其强悍的处理速度和并行能力,能完全胜任,到了企业客户的现场,800~1000个间断性的连续请求也是毫无问题的,而且CPU的使用率,也能随时维持在25%~85%的正常水平。
自此,你应该可以基本理解,为何上述,“并发能力”并非简单的“单位时间的请求次数”有多大。
同理,尽量减少应用单次请求的“长耗时”作业,尽量将应用单次请求通过技术手段转为“短耗时”的任务,也是能增强客户并发的能力的有效途径,同时也能提升用户的UE体验。
2.5、可被分配的可用内存也会影响并发上限
2.5.1、服务中的内存泄漏会持续增高服务程序的“工作集(KB)”
服务MyService1及其客制化代码,如果存在有内存泄漏的话,会随时间和客户对其的调用次数的递增,而以非线程的方式快速递增“提交工作集”,直至操作系统无法再继续为其分配更多的可用内存为止。
这些bug是因为服务MyService1中的代码,申请了内存地址空间,用完后却没有及时释放造成的,会严重影响客户的并发请求的能力。
有些网友在群里说,怎么我的服务程序最多支撑200多个客户端并发呢?这就需好好的调试和测试代码啦。
2.5.2、尽量减少长耗时的内存载入及其磁盘读写
有些服务函数,因计算需要,可能会读入大量的字节(比如上面的单次上传一次性16m)读入内存空间,而从内存写入磁盘存储,是需要时间的,往往,硬盘的I/O读写速率要远低于内存的I/O处理速度,从而造成内存进出和磁盘读写时的并发阻塞。一般,服务器配置,CPU和内存的占比为1:2,比如2核4G、4核8G、8核16G等等;如果你的应用属于高计算型的、高耗时型的,就增加CPU的权重,比如4核4G、8核4G等等;如果应用是高内存消耗型的就应增加内存的占比,比如4核8G、8核32G等等;服务器的CPU和内存占比配置不当,是对服务器硬件资源的浪费。
另外还是代码啦,如上,有些服务函数,因计算需要,可能会伴随大量的字节读写内存,如果这些内存占用,长时间得不到正常的释放,耗时太久,即会在此时段内降低可靠的可调度的并发请求的数量级别,如果在此基础上,进程的“优先级别”也无法提升的话,则严重影响并发。即:长耗时的高内存读写会直接降低客户端的并发上限。
这也就是为何,专业网盘,后端有专业的存储服务器集群或对象存储COS集群做支撑的道理。
2.5.3、尽量减少大块的内存读写及其大块的磁盘读写
减少每秒钟内,大块字节读写内存;减少大块读写磁盘。将它们分解为小块,增加频率和次数是可以的。内存的速度一般用存取时间衡量,即每次与CPU间数据处理耗费的时间,以纳秒(ns)为单位。大多数SDRAM内存芯片的存取时间为5、6、7、8或10ns,DDR(n)时代,就更快了,核心频率为133mHZ*(2^n)),比如DDR3,等效频率可以达到惊人的1600mMZ,内存数据带宽达到(等效频率X64/8=)12.5GB/S。普通硬盘都是有速度限制的,即便是SSD固态硬盘也就500m/s~g/s这个级别;硬盘总是应当与内存有效的协调;理论上内存的读写速度要远高于磁盘的读写速度。只有载入内存,才能与CPU进行交互处理。所以如果你有循环,在反复读写它们的I/O,如果块太大,并发时会让硬盘的I/O吃不消,严重降低系统的整体性能,降低并发性能。
打个比方,通过RDP微软的远程桌面连接,你同时复制本机的几个500M的文件到RDP的磁盘,你会发现,此时,无论是本机也好、还是目标RDP的机器也好,资源管理器都处于“卡顿”的状态,就是这个道理。
小块读写磁盘和内存,在高频CPU的协调下尽量增加频次会提升客户端的并发上限。
2.5.4、其它软件和服务的影响
2.5.4.1、不要让用户直接Logon到服务器成为独立的操作系统级别的会话
如果您的应用,涉及到以操作系统级别的用户(User)登录到服务器的会话(Session),无论是在服务端还是从客户端,因此会Logon启动这些用户和会话必须的关联进程,从而造成整机的正在运行的高内存使用。
2.5.4.2、不要在服务器内启用国内浏览器
多标签页,每N个分页,在内存中其实是对应了1个独立实例,打开的分页越多,就相当于打开了多个应用的实例。内存会急剧上升。
更不要在生产服务器上,运行并用这些浏览器进行远程桌面的浏览和在线编辑等操作。
2.5.4.3、不要在服务器内启用office应用或其服务供应用直接调用
如果涉及office文件的读写,应当以元数据格式的技术进行读写。
2.5.4.4、不要在服务器内直接远程开启QQ、微信等社交工具、资源浏览器服务而不注销
2.5.4.5、关闭输入法除输入功能以外其它任何服务
等等,不一而足。也就是说,除了你的服务及其必须的关联服务以外,不要安装其它应用及服务。
三、基本的结论
3.1、服务器可支配的http客户端并发上限的主要因子:应综合考虑网络收发包i/o、内存及磁盘读写i/o的大小及频率,应充分运用多核心CPU的并行处理能力
3.2、客户端并发上限应进行样本取样,实时监控上述主要影响因子及其关联指标
3.3、以上主要因子,我们将其称为服务器的负载(Server Loadings),当正常负载伴随并发用户数量的增加迟早会达到极限。如何让服务达到负载极限时,用户的应用不终端、可靠性不降低,就涉及到负载均衡器,用它自动将请求转发到其它物理服务器或其它虚拟机,使各个节点的服务器的负载能够平衡(Loading Balance);负载均衡除了上述主要因子以外,还要尽量将客户的IP地域性指派到就近的IP节点进行处理。
可以参考一下腾讯云负载均衡的计费规则: