侧边栏壁纸
博主头像
再见理想博主等级

只争朝夕,不负韶华

  • 累计撰写 112 篇文章
  • 累计创建 64 个标签
  • 累计收到 4 条评论

目 录CONTENT

文章目录

秒杀系统架构浅析

再见理想
2022-05-29 / 0 评论 / 0 点赞 / 402 阅读 / 1,844 字

一,秒杀系统该考虑的问题

  • 超卖问题
  • 高并发
  • 恶意请求
  • 连接暴露
  • 数据库

每秒上万甚至十几万的 QPS(每秒请求数)直接打到数据库,基本上都要把库打挂掉,而且你服务不单单是做秒杀的还涉及其他的业务,你没做降级、限流、熔断啥的,别的一起挂,可能全站崩溃404。

二,秒杀系统的设计和技术方案

资源静态化

秒杀一般都是特定的商品还有页面模板,现在一般都是前后端分离的,页面一般都是不会经过后端的,但是前端也要自己的服务器,把能提前放入cdn服务器的东西都放进去,减少真正秒杀时候服务器的压力。

秒杀链接加盐

上面说了链接要是提前暴露出去可能有人直接访问url就提前秒杀了,那又有小伙伴要说了我做个时间校验就好了呀。我知道url了,那我通过程序不断获取最新的北京时间,可以达到毫秒级别的,我就在00毫秒的时候请求,我敢说绝对比你人工点的成功率大太多了,而且我可以一毫秒发送N次请求,搞不好你卖100个产品我全拿了。

这种情况怎么避免?

把URL动态化,就连写代码的人都不知道,你就通过MD5之类的摘要算法加密随机的字符串去做url,然后通过前端代码获取url后台校验才能通过。

步骤:

1,在进行秒杀之前,先请求一个服务端地址,/getmiaoshaPath 这个地址,用来获取秒杀地址,传参为 商品id,在服务端生成随机数(MD5)作为 pathId 存入缓存,(缓存过期时间60s),然后将这个随机数返回给前端。

2,获得该pathid,后 前端在用这个pathid拼接在Url上作为参数,去请求domiaosha服务。

3,获得该pathid,后 前端在用这个pathid拼接在Url上作为参数,去请求domiaosha服务

限流

前端限流

没到秒杀前,一般按钮都是置灰,定时去请求后端服务器,获取最新的北京时间,到时间点再给按钮可用状态。按钮可以点击之后,每点击一次也置灰几秒,不让用户一直点击请求。

后端限流

Nginx:一台Nginx能承受几万并发。一台Tomcat能承受几百并发,那就在秒杀期间多租机器。

网关:过滤掉非人为的恶意请求。

风控

前面的所有措施还是拦不住很多羊毛党,因为他们是专业的团队,他们可以注册很多账号来薅你的羊毛,而且不用机器请求,就用群控,操作几乎跟真实用户一模一样。

这个时候就需要风控同学的介入了,在请求到达后端之前,风控可以根据账号行为分析出这个账号机器人的概率大不大,我现在负责公司的某些特殊系统,每个用户的行为都是会送到我们大数据团队进行分析处理,给你打上对应标签的。

我们通过风管分析出来这个用户是真实用户的概率没有其他用户概率大,那就认为他是机器了,丢弃他的请求。

之前的限流我们放进来10000个请求,但是我们真正的库存只有1000个,那我们就算出最有可能是真实用户的1000人进行秒杀,丢弃其他请求,因为秒杀本来就是黑盒操作的,用户层面是无感知的,这样设计能让真实的用户买到东西,还可以减少自己被薅羊毛的概率。风控可以说是流量进入的最后一道门槛了。

服务职责

设计个能抗住高并发的系统,我觉得还是得单一职责。给秒杀也开个服务,我们把秒杀的代码业务逻辑放一起。单一职责的好处就是就算秒杀没抗住,秒杀库崩了,服务挂了,也不会影响到其他的服务。(高可用)

Redis集群

之前不是说单机的Redis顶不住嘛,那简单搞个Redis集群,主从同步、读写分离,还搞点哨兵,保证高可用!

库存预热

开始秒杀前把商品的库存加载到Redis中去,让整个流程都在Redis里面去做,然后等秒杀结束了,再异步的去修改库存就好了。

但是用了Redis就有一个问题了,我们上面说了我们采用主从,就是我们会去读取库存然后再判断然后有库存才去减库存,正常情况没问题,但是高并发的情况问题就很大了。

就比如现在库存只剩下1个了,我们高并发嘛,4个服务器一起查询了发现都是还有1个,那大家都觉得是自己抢到了,就都去扣库存,那结果就变成了-3,是的只有一个是真的抢到了,别的都是超卖的。咋办?

Redis本身是支持事务的,而且他有很多原子命令的,还可以用LUA,用管道,乐观锁也支持。

限流&降级&熔断&隔离

消息队列(削峰填谷)

数据库

应该单独设计一个秒杀数据库,防止因为秒杀活动的高并发访问拖垮整个网站。这里只需要四张表,一张是秒杀订单表,一张是秒杀货品表,商品表:可以关联goods_id查到具体的商品信息,还有用户表:根据用户user_id可以查询到用户信息。

分布式事务

分布式事务大家想的是一定要成功什么的那就不对了,还是那句话,几个请求丢了就丢了,要保证时效和服务的可用可靠。所以TCC和最终一致性其实不是很适合,TCC开发成本很大,所有接口都要写三次,因为涉及TCC的三个阶段。最终一致性基本上都是靠轮训的操作去保证一个操作一定成功,那时效性就大打折扣了。

大家觉得不那么可靠的两段式(2PC)和三段式(3PC)就派上用场了,他们不一定能保证数据最终一致,但是效率上还算ok。

三,架构图

0

评论区