教育行业A股IPO第一股(股票代码003032)
全国咨询/投诉热线:400-618-4000
高并发是互联网应用的一大特色,也是互联网应用不可避免的问题;比如淘宝双11、京东618、12306春节火车票,促销、秒杀等等。
QPS:每秒响应请求数。在互联网领域,这个指标和吞吐量区分的没有这么明显。
并发用户数:同时承载正常使用系统功能的用户数量。例如一个即时通讯系统,同时在线量一定程度上代表了系统的并发用户数。
此种场景就是非常有特点的高并发场景,如果不对流量进行合理管控,肆意放任大流量冲击系统,那么将导致一系列的问题出现,比如一些可用的连接资源被耗尽、分布式缓存的容量被撑爆、数据库吞吐量降低,最终必然会导致系统产生雪崩效应。
一般来说,大型互联网站通常采用的做法是通过扩容、动静分离、缓存、服务降级及限流五种常规手段来保护系统的稳定运行。
1.限流
在讨论为什么需要限流之前,我们先聊一聊生活中那些随处可见的限流场景。
上面两张图片就展示了地铁拥挤的场景,如果这所有的人全部涌入站台,那么会造成更多的人无法上车,所以采取了管制之后,我们可以让人们通过地面和站厅层的双重排队等待,减轻站台的压力,保证每一位乘客最终都能顺利的上车。
在电商系统的秒杀中,也会有大批量的用户同时涌入,鉴于只有少部分用户能够秒杀成功,所以要限制大部分流量,只允许少部分流量进入服务后端。
例如tomcat的配置:
其中最后两个参数意义如下:
maxThreads:tomcat起动的最大线程数,即同时处理的任务个数,默认值为200
acceptCount:当tomcat起动的线程数达到最大时,接受排队的请求个数,默认值为100
这两个值如何起作用,请看下面三种情况
情况1:接受一个请求,此时tomcat起动的线程数没有到达maxThreads,tomcat会起动一个线程来处理此请求。
情况2:接受一个请求,此时tomcat起动的线程数已经到达maxThreads,tomcat会把此请求放入等待队列,等待空闲线程。
情况3:接受一个请求,此时tomcat起动的线程数已经到达maxThreads,等待队列中的请求个数也达到了acceptCount,此时tomcat会直接拒绝此次请求,返回connectionrefused。
2.页面静态化
首先我们可以使用Freemarker对页面进行静态化,让用户减少跟后端服务器之间的交互。这样就能降低服务器的压力,如果条件允许我们可以采用CDN加速。
Freemarker的原理如下图,模板+数据通过Freemarker可以生成静态页面。
CDN是将源站内容分发至最接近用户的节点,使用户可就近取得所需内容,提高用户访问的响应速度和成功率。
例如下图:北京网民会自动访问到离自己最近并且速度最快的服务器的资源。
3.引入Redis
限流和静态化都是为了减轻服务器后端的压力,但是最终用户的请求还是会落到服务器中,为了增加用户的体验度,我们也应加快相应速度。后端代码和数据库之间的交互会降低相应速度,所以我们可以采用Redis来进行数据的高速读取。
Redis是一款极其优秀的内存级别的NoSql数据库,单线程下读写速度能达到5w/s。所以我们在很多情况下都能利用Redis去解决高速读取的问题。
特别是库存量的超卖现象,我们可以在开始秒杀的时候,把总的库存量存入Redis中,每当用户来抢购时,利用String类型的decr方法去减一,如果减一成功就视认为抢够成功,并把用户和商品信息存入Redis的订单条目中,当最终抢购结束时,我们再一并把Redis的订单信息存入到数据库中。
代码参考:
代码参考:#设置总的待抢购数量为1000000setamount1000000;#抢购数量减一decramount#把用户信息存入到抢购成功的集合中,由商品ID命名来区分lpush用户ID商品ID
通过上述3种方案可以解决大部分场景下的秒杀问题,当然高并发下也会出现更多的意外的状况,那么我们可以针对自己的业务,资源的调度进行更多方位的尝试,找到最适合自己的解决方案。