2021-02-02 分类: 网站建设
说到“秒杀”,恐怕大多数人想到的就是“双 11”,“促销”,“买买买”等火爆的场面吧。
图片来自 Pexels
大家为了打折商品蜂拥而至,造成
技术隔离架构图
前面有了准备工作,那么从技术上需要有以下几个方面的考虑:
秒杀系统前端设计简图
代理层设计
说完了秒杀系统的前端设计,请求自然地来到了代理层。由于用户的请求量大,我们需要用负载均衡加上服务器集群,来面对如此空前的压力。
代理层三大功能简图
在这一层是可以做缓存,过滤和限流的:
主要想表达的意思是,可以将一些变化不频繁的数据,提到代理层来缓存,提高响应的效率。
同时,还可以根据风控系统返回的信息,过滤一些疑似机器人或者恶意请求。例如:从固定 IP 过来的,频率过高的请求。最重要的就是在这一层,可以识别来自秒杀系统的请求。
如果是带有秒杀系统的参数,就要把请求路由到秒杀系统的服务器集群。这样才能和正常的业务系统分割开来。
阀值的设置可以是动态调整的。例如:集群服务器中有 10 个服务器,其中一台由于压力过大挂掉了。
此时就需要调整代理层的流量阀值,将能够处理的请求流量减少,保护后端的应用服务器。
当服务器恢复以后,又可以将阀值调回原位。可以通过 Nginx+Lua 合作完成,Lua 从服务注册中心读取服务健康状态,动态调整流量。
应用层设计
“秒杀系统”秒杀的是什么?无非是商品。对于系统来说就是商品的库存,购买的商品一旦超过了库存就不能再卖了。
防止超卖
超过了库存还可以卖给用户,这就是“超卖”,也是系统设计需要避免的。为了承受大流量的访问,我们用了水平扩展的服务,但是对于他们消费的资源“库存”来说,却只有一个。
为了提高效率,会将这个库存信息放到缓存中。以流行的 Redis 为例,用它存放库存信息,由多个线程来访问就会出现资源争夺的情况。也就是分布式程序争夺唯一资源,为了解决这个问题我们需要实现分布式锁。
假设这里有多个应用响应用户的订单请求,他们同时会去访问 Redis 中存放的库存信息,每接受用户一次请求,都会从 Redis 的库存中减去 1 个商品库存量。
当任何一个进程访问 Redis 中的库存资源时,其他进程是不能访问的,所以这里需要考虑锁的情况(乐观,悲观)。
Redis 缓存承载库存变量
如果锁长期没有释放,需要考虑锁的过期时间,需要设置两个超时时间:
订单处理流程
这里的“扣减服务”完成了最简单的扣减库存工作,并没有和其他项目服务打交道,更没有访问数据库。
订单流程示意图
后面的流程相对比较复杂,我们先看图,根据图示来讲解:
注意,这里可以加入类似 ZooKeeper 这样的服务调度来帮助,协调服务调度和任务分配。
一旦发现不一致,会去做重试操作。如果重试依旧不成功,会重写信息到缓存,让用户知道失败原因。
虽然,这个信息和最终结果有偏差,但是在秒杀的场景,要求高性能是前提,结果的一致性,可以后期补偿。
数据库设计
讲完了秒杀的处理流程,来谈谈数据库设计要注意的点。
数据估算
前面说了秒杀场景需要注意隔离,这里的隔离包括“业务隔离”。就是说我们在秒杀之前,需要通过业务的手段,例如:热场活动,问卷调查,历史数据分析。通过他们去估算这次秒杀可能需要存储的数据量。
这里有两部分的数据需要考虑:
前者不言而喻是给业务系统用的。后者,是用来分析和后续处理问题订单用的,秒杀完毕以后还可以用来复盘。
分表分库
对于这些数据的存放,需要分情况讨论,例如,MySQL 单表推荐的存储量是 500W 条记录(经验数字)。
如果估算的时候超过了这个数据,建议做分表。如果服务的连接数较多,建议进行分库的操作。
数据隔离
由于大量的数据操作是插入,有少部分的修改操作。如果使用关系型数据来存储,建议用专门的表来存放,不建议使用业务系统正在使用的表。
这个开头提到了,数据隔离是必须的,一旦秒杀系统挂了,不会影响到正常业务系统,这个风险意识要有。表的设计除了 ID 以外,最好不要设置其他主键,保证能够快速地插入。
数据合并
由于是用的专用表存储,在秒杀活动完毕以后,需要将其和现有的数据做合并。其实,交易已经完成,合并的目的也就是查询。
这个合并需要根据具体情况来分析,如果对于那些“只读”的数据,对于做了读写分离的公司,可以导入到专门负责读的数据库或者 NoSQL 数据库中。
压力测试
构建了秒杀系统,一定会面临上线,那么在上线之前压力测试是必不可少的。
我们做压力测试的目的是检验系统崩溃的边缘在哪里?系统的极限在哪里?
这样才能合理地设置流量的上限,为了保证系统的稳定性,多余的流量需要被抛弃。
压力测试的方法
合理的测试方法可以帮助我们对系统有深入的了解,这里介绍两种压力测试的方法:
正压力测试。每次秒杀活动都会计划,使用多少服务器资源,承受多少的请求量。
可以在这个请求量上面不断加压,直到系统接近崩溃或者真正崩溃。简单的说就是做加法。
正压力测试示意图
负压力测试。在系统正常运行的情况下,逐步减少支撑系统的资源(服务器),看什么时候系统无法支撑正常的业务请求。
例如:在系统正常运行的情况下,逐步减少服务器或者微服务的数量,观察业务请求的情况。说白了就是做减法。
负压力测试示意图
压力测试的步骤
测试步骤
有了测试方法的加持,我们来看看需要遵循哪些测试步骤。下面的操作偏套路化,大家在其他系统的压力测试也可以这么做,给大家做个参考。
第一,确定测试目标。与性能测试不同的是,压力测试的目标是,什么时候系统会接近崩溃。比如:需要支撑 500W 访问量。
第二,确定关键功能。压力测试其实是有重点的,根据 2/8 原则,系统中 20% 的功能被使用的是最多的,我们可以针对这些核心功能进行压力测试。例如:下单,库存扣减。
关注核心服务
第三,确定负载。这个和关键服务的思路一致,不是每个服务都有高负载的,我们的测试其实是要关注那些负载量大的服务,或者是一段时间内系统中某些服务的负载有波动。这些都是测试目标。
第四,选择环境,建议搭建和生产环境一模一样的环境进行测试。
第五,确定监视点,实际上就是对关注的参数进行监视,例如 CPU 负载,内存使用率,系统吞吐量等等。
第六,产生负载,这里需要从生产环境去获取一些真实的数据作为负载数据源,这部分数据源根据目标系统的承受要求由脚本驱动,对系统进行冲击。
建议使用往期秒杀系统的数据,或者实际生产系统的数据进行测试。
第七,执行测试,这里主要是根据目标系统,关键组件,用负载进行测试,返回监视点的数据。
建议团队可以对测试定一个计划,模拟不同的网络环境,硬件条件进行有规律的测试。
第八,分析数据,针对测试的目的,对关键服务的压力测试数据进行分析得知该服务的承受上限在哪里。
对一段时间内有负载波动或者大负载的服务进行数据分析,得出服务改造的方向。
总结
秒杀系统的特点,并发量大,资源有限,操作相对简单,访问的都是热点数据。因此,我们需要把它从业务,技术,数据上做隔离,保证不影响到现有的系统。
因此,架构设计需要分几层来考虑,从客户请求到数据库存储,到最后上线前的压力测试。
简易的思维导图送给大家
思考顺序如下,客户端→代理层→应用层→数据库→压力测试:
客户端 90% 静态 HTML+10% 动态 JS;配合 CDN 做好缓存工作。
接入层专注于过滤和限流。
应用层利用缓存+队列+分布式处理好订单。
做好数据的预估,隔离,合并。
上线之前记得进行压力测试。
新闻名称:这一次,彻底弄懂“秒杀系统”
本文来源:https://www.cdcxhl.com/news/98718.html
成都网站建设公司_创新互联,为您提供服务器托管、企业网站制作、外贸网站建设、做网站、App开发、全网营销推广
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联
猜你还喜欢下面的内容