服务器的高并发

服务器的高并发

尊重原创来源于:石头大V  今日头条

在网上购物,秒抢某个商品,比如说小米手机,这对我们来说都不陌生。这些看似很简单的东西从技术的角度来说对于Web系统是一个巨大的考验,一个Web系统,在很短时间内收到很多请求时,系统的优化和稳定至关重要,我们就来详细解释一下这些问题。

1、大规模并发带来的挑战

比如说5w每秒的高并发秒杀功能,在这个过程中,整个Web系统遇到了很多的问题和挑战。如果Web系统不做针对性的优化,会轻而易举地陷入到异常状态。一起来讨论下优化的思路和方法。

1.1、请求接口的合理设计

一个抢购页面,通常分为2个部分,一个是静态的HTML等内容,另一个就是Web后台请求接口。通常静态HTML等内容,是通过CDN的部署,一般压力不大,核心瓶颈实际上在后台请求接口上。这个后端接口,必须能够支持高并发请求,同时必须尽可能“快”,在最短的时间里返回用户的请求结果。为了实现尽可能快这一点,接口的后端存储使用内存级别的操作会更好一点,仍然直接面向MySQL之类数据库的存储是不合适的,如果有这种复杂业务的需求,都建议采用异步写入。

1.2、高并发的挑战

衡量一个Web系统的吞吐率的指标是QPS(Query Per Second,每秒处理请求数),解决每秒数万次的高并发场景,这个指标非常关键。假设处理一个业务请求平均响应时间为100ms,同时系统内有20台Apache的Web服务器,配置MaxClients为500个(表示Apache的最大连接数目)。那么Web系统的理论峰值QPS为(理想化的计算方式):20*500/0.1 = 100000 (10万QPS) ,系统似乎很强大,1秒钟可以处理完10万的请求,实际情况当然没有这么理想。在高并发的实际场景下,机器都处于高负载的状态,在这个时候平均响应时间会被大大增加。就Web服务器而言,Apache打开了越多的连接进程,CPU需要处理的上下文切换也越多,额外增加了CPU的消耗,然后就直接导致平均响应时间增加。因此上述的MaxClient数目,要根据CPU、内存等硬件因素综合考虑,绝对不是越多越好。可以通过Apache自带的abench来测试一下,取一个合适的值。然后,我们选择内存操作级别的存储的Redis,在高并发的状态下,存储的响应时间至关重要,不考虑网络带宽和负载均衡问题。假设系统,在5w/s的高并发状态下,平均响应时间从100ms变为250ms(实际情况,甚至更多):20*500/0.25 = 40000 (4万QPS)于是系统剩下了4w的QPS,面对5w每秒的请求,中间相差了1w。 举个通俗例子说明,收费站1秒钟来5部车,每秒通过5部车,收费站运作正常。突然这个收费站1秒钟只能通过4部车,车流量仍然依旧,结果必定出现大塞车。(5条车道忽然变成4条车道的感觉)同理某一个秒内,20*500个可用连接进程都在满负荷工作中,却仍然有1万个新来请求,没有连接进程可用,系统陷入到异常状态也是预期之内。其实在正常的非高并发的业务场景中,也有类似的情况出现,某个业务请求接口出现问题,响应时间极慢,将整个Web请求响应时间拉得很长,逐渐将Web服务器的可用连接数占满,影响其他正常的业务请求,无连接进程可用。更严重的是用户的行为,系统越是不可用,用户的点击越频繁,恶性循环最终导致“雪崩”(其中一台Web机器挂了,导致流量分散到其他正常工作的机器上,再导致正常的机器也挂,然后恶性循环),将整个Web系统拖垮。

1.3、重启与过载保护

如果系统发生“雪崩”,贸然重启服务,是无法解决问题的。这种情况最好在入口层将流量拒绝,然后再将重启,如果是redis/memcache这种服务也挂了,重启的时候需要注意“预热”,并且很可能需要比较长的时间。秒杀和抢购的场景,流量往往是超乎系统的准备和想象的。这个时候过载保护是必要的。如果检测到系统满负载状态,拒绝请求也是一种保护措施。在前端设置过滤是最简单的方式,但是,这种做法是会被客户骂的,更合适的解决方案是将过载保护设置在CGI入口层,快速将客户的直接请求返回。

2、作弊的常见手段

秒杀和抢购收到了海量的请求,实际上水分是很大的。不少用户为了抢到商品,会使用刷票软件等类型的辅助工具,所以就会发送尽可能多的请求到服务器。还有一部分用户,自己制作强大的自动请求脚本,这些都是属于“作弊的手段”,不过有“进攻”就有“防守”。

2.1 、同一个账号,一次性发出多个请求

部分用户通过浏览器的插件或者其他工具,在秒杀开始的时间里,以自己的账号一次发送上百甚至更多的请求。这样的用户破坏了秒杀和抢购的公平性,这种请求在某些没有做数据安全处理的系统里,也可能造成另外一种破坏,导致某些判断条件被绕过。如一个简单的领取逻辑,先判断用户是否有参与记录,如果没有则领取成功,最后写入到参与记录中。这是个非常简单的逻辑,但是在高并发的场景下,存在深深的漏洞,多个并发请求通过负载均衡服务器,分配到内网的多台Web服务器,它们先向存储发送查询请求,然后在某个请求成功写入参与记录的时间差内,其他的请求获查询到的结果都是“没有参与记录”。这就存在逻辑判断被绕过的风险。

应对方案:在程序入口处,一个账号只允许接受1个请求,其他请求过滤,不仅解决了同一个账号发送N个请求的问题,还保证了后续的逻辑流程的安全。

2.2、多个账号,一次性发送多个请求

账号注册功能在发展早期几乎是没有限制的,很容易就可以注册很多个账号。因此也导致了出现了一些特殊的工作室,通过编写自动注册脚本,积累了一大批“僵尸账号”,数量庞大,几万甚至几十万的账号不等,专门做各种刷行为(这就是传说中的“僵尸粉“)。比如有转发抽奖的活动,如果使用几万个“僵尸号”去混进去转发,这样就可以大大提升中奖的概率,使用在秒杀和抢购也是同一个道理,比如iPhone官网的抢购,火车票黄牛党也是如此。

应对方案:这种场景可以通过检测指定机器IP请求频率就可以解决,如果发现某个IP请求频率很高,可以给它弹出一个验证码或者直接禁止它的请求:弹出验证码,目的就是分辨出真实用户。网站弹出的验证码,都是随机的样子,有时无法看清,这样做的原因,其实也是为了让验证码的图片不被轻易识别,因为强大的“自动脚本”可以通过图片识别里面的字符,然后让脚本自动填写验证码。现在有一些新方法效果会比较好,如给你一个简单问题让你回答,或者让你完成某些简单操作(例如百度贴吧的验证码),这个做法简单高效,效果也很好。

2.3、多个账号,不同IP发送不同请求

有进攻,就会有防守,这些“工作室”,发现你对单机IP请求频率有控制之后,他们也针对这种场景,想出了他们的“新进攻方案”,就是不断改变IP,这些随机IP服务怎么来的,有一些是某些机构自己占据一批独立IP,然后做成一个随机代理IP的服务,有偿提供给这些“工作室”使用。还有一些就是通过木马黑掉普通用户的电脑,这个木马也不破坏用户电脑的正常运作,只做一件事情,就是转发IP包。通过这种做法黑客就拿到了大量的独立IP,然后搭建为随机IP服务,赚了很多黑心钱。

应对方案: 这种情况通常只能通过设置业务门槛高来限制这种请求了,或者通过账号行为的”数据挖掘“来提前清理掉它们。僵尸账号也还是有一些共同特征的,例如账号很可能属于同一个号码段甚至是连号的,活跃度不高,等级低,资料不全等等。根据这些特点,适当设置参与门槛,例如限制参与秒杀的账号等级。通过这些业务手段,也是可以过滤掉一些僵尸号。

2.4、火车票的抢购 

看到这里,你是否明白为什么抢不到火车票,如果你只是老老实实地去抢票,真的很难。通过多账号的方式黄牛将很多车票的名额占据,部分牛逼的黄牛在处理验证码方面更是“技高一筹“,高级的黄牛刷票时,在识别验证码的时候使用真实的人,中间搭建一个展示验证码图片的中转软件服务,真人浏览图片并填写下真实验证码,返回给中转软件。对于这种方式,验证码的保护限制作用被废除了,目前也没有很好的解决方案。因为火车票是根据身份证实名制的,除比之外还有一个火车票的转让操作方式,就是先用买家的身份证开启一个抢票工具,持续发送请求,黄牛账号选择退票,然后黄牛买家成功通过自己的身份证购票成功,因为黄牛们的抢票工具也很强大,即使让我们看见有退票,我们也抢不过他们,最终黄牛顺利将火车票转移到买家的身份证下。

什么是服务器的高并发?解决方案:并没有很好的解决方案,唯一可以动心思的也许是对账号数据进行“数据挖掘”,这些黄牛账号也是有一些共同特征的,例如经常抢票和退票,节假日异常活跃等等。将它们分析出来,再做进一步处理和甄别。

3、高并发下的数据安全

多线程写入同一个文件的时候,会存现“线程安全”的问题(多个线程同时运行同一段代码,如果每次运行结果和单线程运行的结果是一样的,结果和预期相同,就是线程安全的)。如果是MySQL数据库,可以使用它自带的锁机制很好的解决问题,但是在大规模并发的场景中,是不推荐使用MySQL的。秒杀和抢购的场景中,还有另外一个问题,就是“超发”,如果在这方面控制不慎,会产生发送过多的情况,比如某些电商搞抢购活动,买家成功拍下后,商家却不承认订单有效,拒绝发货。问题也许并不一定是商家奸诈,而是系统技术层面存在超发风险导致的。

3.1、超发的原因

假设某个抢购场景中,一共只有100个商品,在最后一刻,我们已经消耗了99个商品,仅剩最后一个。这个时候,系统发来多个并发请求,这批请求读取到的商品余量都是99个,然后都通过了这一个余量判断,最终导致超发。这就导致了并发用户B也“抢购成功”,多让一个人获得了商品。这种场景在高并发的情况下非常容易出现。

3.2、悲观锁思路

悲观锁也就是在修改数据的时候,采用锁定状态,排斥外部请求的修改,遇到加锁的状态,就必须等待,虽然上述的方案的确解决了线程安全的问题,但是我们的场景是“高并发”,也就是说会很多这样的修改请求,每个请求都需要等待“锁”,某些线程可能永远都没有机会抢到这个“锁”,这种请求就会死在那里。同时这种请求会很多,瞬间增大系统的平均响应时间,结果是可用连接数被耗尽,系统陷入异常。

3.3、FIFO队列思路

直接将请求放入队列中的,采用FIFO(First Input First Output,先进先出),这样的话就不会导致某些请求永远获取不到锁。看到这里是不是有点强行将多线程变成单线程的感觉哈,现在解决了锁的问题,全部请求采用“先进先出”的队列方式来处理。那么新的问题来了,高并发的场景下,因为请求很多,很可能一瞬间将队列内存“撑爆”,然后系统又陷入到了异常状态。或者设计一个极大的内存队列,也是一种方案,系统处理完一个队列内请求的速度根本无法和疯狂涌入队列中的数目相比。也就是说队列内的请求会越积累越多,最终Web系统平均响应时候还是会大幅下降,系统还是陷入异常。

3.4、乐观锁思路

乐观锁是相对于“悲观锁”采用更为宽松的加锁机制,大都是采用带版本号(Version)更新。这个数据所有请求都有资格去修改,但会获得一个该数据的版本号,只有版本号符合的才能更新成功,其他的返回抢购失败。这样的话我们就不需要考虑队列的问题,不过它会增大CPU的计算开销。但是综合来说,这是一个比较好的解决方案。有很多软件和服务都“乐观锁”功能的支持,通过这个功能可以保证数据的安全。

4、随着互联网的用户越来越多,高并发的场景也变得越来越多,电商秒杀和抢购是两个比较典型的高并发场景,虽然遇到的挑战多,但是我们不怕,因为我们一直在努力。

原文地址:https://www.cnblogs.com/fan123yh/p/11053898.html

时间: 2024-11-13 08:04:02

服务器的高并发的相关文章

高并发系统设计与时间和空间的平衡

高可用上文我们已经讲过了,可当前互联网时代,怎么少的了高并发呢?高并发和高可用一样, 已经变成各个系统的标配了,如果你的系统QPS没有个大几千上万,都不好意思跟人打招呼,虽然可能每天的调用量不超过100. 高并发这个词,我个人感觉是从电商领域开始往外流传的,特别是电商领域双11那种藐视全球的流量,再把技术架构出来分享一把,现在搞得全互联网都在说高并发,而且你注意回忆一下所有你看到的高并发系统,往往都逃不开一个核心概念,那就是缓存+哈希,一切都是以这个概念和基础的,仿佛这就是高并发的核心技术了.

asp.net解决高并发的方案

那啥,最近见了一人叨叨叨的神侃如何处理高并发.居然聊到服务器矩阵.我当时还没回过神,过后细想,服务器矩阵我也知道口里说说,但是中小企业能玩得起?作为一个程序员很多时候只能用手头资源来制定优化方案.(人生哲理:要警惕夸夸其谈者) 我收集了下网上提供的处理方式列在这里.虽然我不会无聊到背下来去唬新人,但加深下映象,有个纲目还是好的. 两大点: 通过服务器处理高并发  调整服务器应用程序池中的最大连接数. 1. 调整IIS 7应用程序池队列长度 由原来的默认1000改为65535. IIS Manag

nginx 实现高并发和高负载

一.Nginx是如何实现高并发的 service nginx start之后,然后输入#ps -ef|grep nginx,会发现Nginx有一个master进程和若干个worker进程,这些worker进程是平等的,都是被master fork过来的.在master里面,先建立需要listen的socket(listenfd),然后再fork出多个worker进程.当用户进入nginx服务的时候,每个worker的listenfd变的可读,并且这些worker会抢一个叫accept_mutex

高并发图片(缩略图)处理中间层服务架构设计

互联网公司经常会有大量原始图片上传,而且一个原图会在页面以不同尺寸缩略图显示,一般有两种策略生成缩略图,一种在上传图片时,生成需要的多张不同缩略图,另一种是请求指定尺寸的图片时实时生存缩略图片,第一种方式有一定限制,就是需要提前知道所有尺寸的图片,做雍余存储,无形中增加大量文件数量,如果文件系统设计不好,还有可能形成大量文件碎片,而且会消耗大量存储空间,如果前端ui设计改变了图片大小,需要重新生成.而第二种方式更加灵活,但是更消耗cpu资源,属于cpu密集计算型 大吞吐量服务端架构设计要考虑四个

epoll高并发多路复用,基于epoll的高性能服务器

并发测试工具ab使用 linux命令安装这个工具:apt-get install apache2 windows中装好apache之后就会再带一个工具 windows命令使用方法 ab -n 200 -c 5 http://www.baidu.com/ 1000就是测试的数量 -c 10 就是开启的线程数 测试的地址 反回了一些测试信息,如 使用时间,每次要多久等信息. linux也是一样用的. epoll多路复用IO 高并发 epoll多路复用是专门用来处理高并发的,在linux多路复用中有多

基于tomcat响应处理模型实现的高并发web服务器

在上一篇博客中,一个简单的AIOweb处理例子,可以看到AIO异步处理,依赖操作系统完成IO操作的Proactor处理模型确实很强大,可以是实现高并发,高响应服务器的不错选择,但是在tomcat中的connector的处理模型还依旧是基于NIO的处理,当然,我认为这可能会在以后的版本进行改进,但另一方面,我更认为AIO的负载控制方面的处理可能是比较难的,因为AIO api并没有提供我们对分配线程组的处理,而只是提供一个线程组,交给操作系统去解决io处理上的问题,所以,这可能会给需要复杂处理的负载

支持高并发的IIS Web服务器常用设置

转一篇站长大人的文章 适用的IIS版本:IIS 7.0, IIS 7.5, IIS 8.0 适用的Windows版本:Windows Server 2008, Windows Server 2008 R2, Windows Server 2012 1.应用程序池(Application Pool)的设置:  General->Queue Length设置为65535(队列长度所支持的最大值) Process Model->Idle Time-out设置为0(不让应用程序池因为没有请求而回收)

第15章 高并发服务器编程(2)_I/O多路复用

3. I/O多路复用:select函数 3.1 I/O多路复用简介 (1)通信领域的时分多路复用 (2)I/O多路复用(I/O multiplexing) ①同一线程,通过"拨开关"方式,来同时处理多个I/O流,哪个IO准备就绪就把开关拨向它.(I/O多路复用类似于通信领域中的"时分复用") ②通过select/poll函数可以实现IO多路复用,他们采用轮询的方式来监视I/O.而epoll是对select/poll的加强,它是基于事件驱动,epoll_ctl注册事件

服务器维护中处理高并发导致的一些常见问题解决方案

这里还是按照场景来吧,毕竟场景是最能体验实用性的.首先说下服务器配置以及环境 阿里云ECS云主机,8G内存,4核的CPU,20M带宽,20G系统盘+200G数据盘,CentOS6.564位,安装的一件集成lnmp环境 场景:微信发红包 这个场景是很常见的,一般客户会在整点的时候进行一次微信公众号的广告推送,这儿时候服务器的并发大概在3000到5000左右.说起来这其实并不算是高并发,但是服务器还是崩了,大概需要等待5分钟之后才能恢复正常.这有点不应该啊,分析原因.查看CPU的利用率并不高,内存使