怎么解决高并发的后台秒杀问题

怎么解决高并发的后台秒杀问题,第1张

秒杀一般是电商或者网上一些活动的场景,这种秒杀一般存在着后台拥挤,服务器承受不了大量的客户端导致奔溃是经常的事情,我们今天来介绍一下解决高并发的后台秒杀问题。

我们遇到的秒杀一般是在电商网站举行一些活动或者节假日在12306网站上抢票时遇到,这些都给我们带来了很多的苦恼,而对于电商网站中一些稀缺或者特价商品,电商网站一般会在约定时间点对其进行限量销售,因为这些商品的特殊性,会吸引大量用户前来抢购,并且会在约定的时间点同时在秒杀页面进行抢购。因为狼多肉少的原因,导致服务器拥挤,大量的客户无功而返。

解决这个一般有五步,第一步限流:鉴于只有少部分用户能够秒杀成功,所以要限制大部分流量,只允许少部分流量进入服务后端。

第二步削峰:对于秒杀系统瞬时会有大量用户涌入,以外卖为例,大量的外卖会在中午产生,商家推出满减活动更是火热。所以在抢购一开始会有很高的瞬间峰值。高峰值流量是压垮系统很重要的原因,所以如何把瞬间的高流量变成一段时间平稳的流量也是设计秒杀系统很重要的思路。实现削峰的常用的方法有利用缓存和消息中间件等技术。

第三步异步处理:秒杀系统是一个高并发系统,采用异步处理模式可以极大地提高系统并发量,其实异步处理就是削峰的一种实现方式。

第四步内存缓存:秒杀系统最大的瓶颈一般都是数据库读写,由于数据库读写属于磁盘IO,性能很低,如果能够把部分数据或业务逻辑转移到内存缓存,效率会有极大地提升。充分利用缓存,利用缓存可极大提高系统读写速度。

最后一步可拓展:当然如果我们想支持更多用户,更大的并发,最好就将系统设计成弹性可拓展的,如果流量来了,拓展机器就好了。像淘宝、京东等双十一活动时会增加大量机器应对交易高峰。消息队列可以削峰,将拦截大量并发请求,这也是一个异步处理过程,后台业务根据自己的处理能力,从消息队列中主动的拉取请求消息进行业务处理。

可以采用Redis 最简单的key-value数据结构,用一个原子类型的变量值(AtomicInteger)作为key,把用户id作为value,库存数量便是原子变量的最大值。对于每个用户的秒杀,我们使用RPUSH key value插入秒杀请求, 当插入的秒杀请求数达到上限时,停止所有后续插入。然后我们可以在台启动多个工作线程,使用LPOP key读取秒杀成功者的用户id,然后再操作数据库做最终的下订单减库存操作。

Java开发高并发的处理方法:

最基础的地方做起,优化我们写的代码,减少必要的资源浪费

避免频繁的使用new对象,对于整个应用只需要存在一个实例的类,我们可以使用单例模式。对于String连接操作,使用      StringBuffer或StringBuilder,对于工具类可以通过静态方法来访问。

避免使用错误的方式,尽量不用instanceof做条件判断。使用java中效率高的类,比如ArrayList比Vector性能好。

服务器分离

对于web服务器来说,是最消耗资源的,于是我们有必要把与页面进行分离,我们把放到独立的服务器。这样的架构可以降低提供页面访问请求的服务器系统压力,并且可以保证系统不会因为的问题而崩溃。在服务器上,我们可以对不同的配置进行优化。

缓存

具体接触过的缓存机制是hibernate的缓存机制。为了避免每次都向数据库中取得数据,我们把用户常常访问到的数据放到内存中,甚至缓存十分大的时候我们可以把内存中的缓存放到硬盘中。还有高级的分布式缓存数据库使用,都可以增加系统的抗压力。

分批传送

在做某项目的时候,一次传递的参数太多,而且数据库规定一次最多传递的参数最多是三万条,当时有五万条记录,那怎么传送呢?最终是分批传送,电梯里一次乘不下那么多的人,会报超重的bug,那就分批把人送上去。

还有一次在考试系统中,如果那么多的考试人员同时提交到数据库中,数据库的压力增大,有时会被down掉,当时采用的方法是使用ajax异步传输,没有等待考生点击提交按钮的时候,就把考生的答案自动提交,这样也避免了突然断电考生前面做过的题出现丢失的现象。

DB优化

在数据库设计的时候就要考虑到后期的维护,数据库三范式是我们设计数据库索要遵循的原则。

索引的建立:建立索引要适当,如果一个表经常用来被查询,对于增加和修改很少被用到,我们就可以为这个表建立索引,因为对于增加和修改和删除操作时,我们对索引的维护要大大超过索引给我们带来的效率。

表字段的类型选择要恰当。包括字段的长度、类型等,要根据实际存储的数据进行选择,长度不要过长,否则会影响效率。

外键要慎用,因为主键代表这一张表,而外键代表一群表,对表之间进行了关联,在删除修改等需要我们关联。

在数据库操作上。 尽量使用prepareStatement,少用Statement,因为PrepareStatement是进行预编译的。

connection设置为readOnly,Connection是对书库连接,属于重量级,我们使用即可。

连接池的使用,我们可以修改数据库默认的连接数。

一、什么是高并发

高并发(High Concurrency)是互联网分布式系统架构设计中必须考虑的因素之一,它通常是指,通过设计保证系统能够同时并行处理很多请求。

高并发相关常用的一些指标有响应时间(Response Time),吞吐量(Throughput),每秒查询率QPS(Query Per Second),并发用户数等。

响应时间:系统对请求做出响应的时间。例如系统处理一个HTTP请求需要200ms,这个200ms就是系统的响应时间。

吞吐量:单位时间内处理的请求数量。

QPS:每秒响应请求数。在互联网领域,这个指标和吞吐量区分的没有这么明显。

并发用户数:同时承载正常使用系统功能的用户数量。例如一个即时通讯系统,同时在线量一定程度上代表了系统的并发用户数。

二、如何提升系统的并发能力

互联网分布式架构设计,提高系统并发能力的方式,方法论上主要有两种:垂直扩展(Scale Up)与水平扩展(Scale Out)。

垂直扩展:提升单机处理能力。垂直扩展的方式又有两种:

(1)增强单机硬件性能,例如:增加CPU核数如32核,升级更好的网卡如万兆,升级更好的硬盘如SSD,扩充硬盘容量如2T,扩充系统内存如128G;

(2)提升单机架构性能,例如:使用Cache来减少IO次数,使用异步来增加单服务吞吐量,使用无锁数据结构来减少响应时间;

在互联网业务发展非常迅猛的早期,如果预算不是问题,强烈建议使用“增强单机硬件性能”的方式提升系统并发能力,因为这个阶段,公司的战略往往是发展业务抢时间,而“增强单机硬件性能”往往是最快的方法。

不管是提升单机硬件性能,还是提升单机架构性能,都有一个致命的不足:单机性能总是有极限的。所以互联网分布式架构设计高并发终极解决方案还是水平扩展。

水平扩展:只要增加服务器数量,就能线性扩充系统性能。水平扩展对系统架构设计是有要求的,如何在架构各层进行可水平扩展的设计,以及互联网公司架构各层常见的水平扩展实践,是本文重点讨论的内容。

三、常见的互联网分层架构

常见互联网分布式架构如上,分为:

(1)客户端层:典型调用方是浏览器browser或者手机应用APP

(2)反向代理层:系统入口,反向代理

(3)站点应用层:实现核心应用逻辑,返回html或者json

(4)服务层:如果实现了服务化,就有这一层

(5)数据-缓存层:缓存加速访问存储

(6)数据-数据库层:数据库固化数据存储

整个系统各层次的水平扩展,又分别是如何实施的呢?

四、分层水平扩展架构实践

反向代理层的水平扩展

反向代理层的水平扩展,是通过“DNS轮询”实现的:dns-server对于一个域名配置了多个解析ip,每次DNS解析请求来访问dns-server,会轮询返回这些ip。

当nginx成为瓶颈的时候,只要增加服务器数量,新增nginx服务的部署,增加一个外网ip,就能扩展反向代理层的性能,做到理论上的无限高并发。

站点层的水平扩展

站点层的水平扩展,是通过“nginx”实现的。通过修改nginxconf,可以设置多个web后端。

当web后端成为瓶颈的时候,只要增加服务器数量,新增web服务的部署,在nginx配置中配置上新的web后端,就能扩展站点层的性能,做到理论上的无限高并发。

服务层的水平扩展

服务层的水平扩展,是通过“服务连接池”实现的。

站点层通过RPC-client调用下游的服务层RPC-server时,RPC-client中的连接池会建立与下游服务多个连接,当服务成为瓶颈的时候,只要增加服务器数量,新增服务部署,在RPC-client处建立新的下游服务连接,就能扩展服务层性能,做到理论上的无限高并发。如果需要优雅的进行服务层自动扩容,这里可能需要配置中心里服务自动发现功能的支持。

数据层的水平扩展

在数据量很大的情况下,数据层(缓存,数据库)涉及数据的水平扩展,将原本存储在一台服务器上的数据(缓存,数据库)水平拆分到不同服务器上去,以达到扩充系统性能的目的。

互联网数据层常见的水平拆分方式有这么几种,以数据库为例:

按照范围水平拆分

每一个数据服务,存储一定范围的数据,上图为例:

这个方案的好处是:

(1)规则简单,service只需判断一下uid范围就能路由到对应的存储服务;

(2)数据均衡性较好;

(3)比较容易扩展,可以随时加一个uid[2kw,3kw]的数据服务;

不足是:

(1)请求的负载不一定均衡,一般来说,新注册的用户会比老用户更活跃,大range的服务请求压力会更大;

按照哈希水平拆分

每一个数据库,存储某个key值hash后的部分数据,上图为例:

这个方案的好处是:

(1)规则简单,service只需对uid进行hash能路由到对应的存储服务;

(2)数据均衡性较好;

(3)请求均匀性较好;

不足是:

(1)不容易扩展,扩展一个数据服务,hash方法改变时候,可能需要进行数据迁移;

这里需要注意的是,通过水平拆分来扩充系统性能,与主从同步读写分离来扩充数据库性能的方式有本质的不同。

通过水平拆分扩展数据库性能:

(1)每个服务器上存储的数据量是总量的1/n,所以单机的性能也会有提升;

(2)n个服务器上的数据没有交集,那个服务器上数据的并集是数据的全集;

(3)数据水平拆分到了n个服务器上,理论上读性能扩充了n倍,写性能也扩充了n倍(其实远不止n倍,因为单机的数据量变为了原来的1/n);

通过主从同步读写分离扩展数据库性能:

(1)每个服务器上存储的数据量是和总量相同;

(2)n个服务器上的数据都一样,都是全集;

(3)理论上读性能扩充了n倍,写仍然是单点,写性能不变;

缓存层的水平拆分和数据库层的水平拆分类似,也是以范围拆分和哈希拆分的方式居多,就不再展开。

五、总结

高并发(High Concurrency)是互联网分布式系统架构设计中必须考虑的因素之一,它通常是指,通过设计保证系统能够同时并行处理很多请求。

提高系统并发能力的方式,方法论上主要有两种:垂直扩展(Scale Up)与水平扩展(Scale Out)。前者垂直扩展可以通过提升单机硬件性能,或者提升单机架构性能,来提高并发性,但单机性能总是有极限的,互联网分布式架构设计高并发终极解决方案还是后者:水平扩展。

互联网分层架构中,各层次水平扩展的实践又有所不同:

(1)反向代理层可以通过“DNS轮询”的方式来进行水平扩展;

(2)站点层可以通过nginx来进行水平扩展;

(3)服务层可以通过服务连接池来进行水平扩展;

(4)数据库可以按照数据范围,或者数据哈希的方式来进行水平扩展;

各层实施水平扩展后,能够通过增加服务器数量的方式来提升系统的性能,做到理论上的性能无限。

1、提供HTML静态访问

web界面上最快的访问速度是什么?当然是最原始的HTML文件访问,对于其他语言 比如 jsp ,asp,php等等,他们首先要通过服务器解析成html之后在返回给访问者,如果我们能提供全部是htm来的页面,那么就能大大的降低服务器和数据库资源的利用和提高网站的并发,所以我们尽可能使我们的网站上的页面采用静态页面来实现,这个最简单的方法其实也是最有效的方法。当然实现这种方式大家比较了解的就是信息发布系统CMS,信息发布系统可以实现最简单的信息录入自动生成静态页面,还能具备频道管理、权限管理、自动抓取等功能,对于一个大型网站来说,拥有一套高效、可管理的CMS是必不可少的。

在后续的文章中我们会单独的使用jsp + servlet实现一个简单的信息发布系统

2、使用独立的服务器

为什么要把单独设置一个服务器?对于Web服务器来说,消耗的服务器资源是最多的,如果能把所有的资源放到一个单独的服务器中进行处理的话,可以降低提供页面访问请求的服务器系统压力,从而能进一步的提高web程序的并发所以在有条件的情况下最好能把放置到一个单独的服务器中

3、配置多台数据库服务器,多个数据库集群

集群(Cluster)技术是使用特定的连接方式,将价格相对较低的硬件设备结合起来,同时也能提供高性能相当的任务处理能力。

越是大型高并发的应用,数据库的压力就会越大,如果数据库操作很频繁,数据库的瓶颈很快就能显现出来,这时一台数据库将很快无法满足应用,于是我们需要使用数据库集群。

数据库集群就是使用多个数据库服务器分担请求的压力,达到快速响应的目的

4、使用缓存

所谓的缓存就是把数据咱是放置到内存中,前台在请求的时候直接从内存中读取数据,而不需要去查询数据库或者读取文件等,这样就能做到最快的响应。网站架构和网站开发中的缓存是非常重要的。

目前有很多开源的缓冲实现方案,APC,File,SQLite,Memcache等等各种类库实现着不同的缓存方式,只有通过了解他们的实现方式,根据具体应用具体选择,才会使缓存系统发挥出最大的性能。

对于java开发来说,大名顶顶的 分布式缓存系统Memcache 可能是最好的选择,他提供一个基于Socket的访问方式,使得该缓存系统支持远程读写访问。尽管这个缓存的内容可能是存在内存中,也可能是存在文件内。

电子商务网站高负载,简单可以分为前端和后台:

前端主要是(应该没有文件下载吧),因为是电子商务网站,少不了大量的,用户集中的情况下,网页加载就会变的极其缓慢。

解决思路:1、压缩,使产品图不失真的情况下尽可能的减少体积,节省宽带。2、增大服务器带宽。3、优化网页代码,尽量采用异步加载方式。4、CDN

后台则是数据处理和数据库负载,电子商务网站后台除了庞大的用户数据要处理意外,还有大量订单,和结算数据。

解决思路:增大数据库服务器配置。

高并发,是所有访问量大的网站都会遇到的问题,并发数是指同一时刻,服务器能接受多少次同时访问,比如服务器配置并发数为200,则这一刻只能允许200个用户同时访问,超过并发数,轻则用户打不开网站,严重的则是服务器宕机。

解决思路:1、CDN。2、增加服务器配置

注:CDN是现在网站普遍使用的加速方案,对减轻服务器负载,避免高并发,缓解恶意攻击都有很好的效果,其主要原理就是将服务器上的数据分发给多个服务器,用户访问的是CDN服务器,从而减轻和保护了网站服务器,也就是常说的云服务器。

DABAN RP主题是一个优秀的主题,极致后台体验,无插件,集成会员系统
网站模板库 » 怎么解决高并发的后台秒杀问题

0条评论

发表评论

提供最优质的资源集合

立即查看 了解详情