电商秒杀系统设计

业务流程 

 系统架构

系统挑战

  1. 高并发:秒杀活动会在短时间内吸引大量用户,系统需要能够处理高峰时期的大量并发请求

  2. 库存同步:在秒杀中,面临的一个严重系统挑战是如何确保在数以万计的用户同时抢购有限的商品时,如何正确、实时地扣减库存,以防止超卖现象。

  3. 防止恶意抢购和刷单:防止恶意用户或机器人利用脚本进行快速抢购,挤压正常用户的抢购机会,甚至在秒杀商品数量有限的情况下进行恶意抢购和放空。

  4. 系统性能和扩展性:系统需要能够抗住短时间内的高并发压力,同时随着用户数量的增长和业务的发展,系统的可扩展性也是一个挑战。

流量分层

秒杀系统中流量巨大,总体来说是读多写少的场景,那就需求设计一套高效的流量管控方案,流量最终呈现是个倒三角的模型

CDN加速

静态资源加速通过将网站的静态资源(如图片、CSS文件、JavaScript脚本等)缓存到遍布全球的服务器中,以实现资源就近访问,加快资源加载速度,提高用户访问体验的一种技术。这种方式特别适用于处理高流量的网站,可以显著减少服务器的压力,提高网站的性能。

秒杀按钮实时刷新

用户怕提前进入到活动页面,此时的秒杀按钮是置灰不可点击的,只有到了秒杀时间点,秒杀按钮才允许点击。在当时很多用户是迫不及待的,大家都会通过不停刷新页面来争取第一时间去点击秒杀按钮。

这里就是通过JS文件来控制的,在活动页面中加入一个JS文件引用,该JS文件中包含秒杀开始标志为否,当秒杀开始的时候生成一个新的JS文件(文件名保持不变,只是内容不一样),更新秒杀开始标志为是,加入下单页面的URL及随机数参数(这个随机数只会产生一个,即所有人看到的URL都是同一个,服务器端可以用redis这种分布式缓存服务器来保存随机数),并被用户浏览器加载,控制秒杀商品页面的展示。这个JS文件的加载可以加上随机版本号(例如xx.js?v=35623823),这样就不会被浏览器、CDN和反向代理服务器缓存。这个JS文件非常小,即使每次浏览器刷新都访问JS文件服务器也不会对服务器集群和网络带宽造成太大压力。

网关限流:利用网关作为流量入口,对到达的请求进行统一的限流控制。这种方法可以防止后端服务因流量过大而压垮,确保系统的稳定性和可用性。服务端限流算法icon-default.png?t=N7T8https://blog.csdn.net/weixin_35973945/article/details/124248976

服务端流量控制

应用独立部署,分散流量,避免不合适的流量影响主体业务。秒杀业务属于读多写少的场景,所以可以通过Redis、本地缓存减少从DB中查询数据。

预扣库存流程

  1. 库存加载:在秒杀活动开始前,将秒杀商品的库存数量加载到Redis中。

  2. 接收请求:用户发送秒杀请求后,请求首先到达应用服务器。

  3. 预扣减操作:应用服务器通过Redis的减操作(例如使用DECR命令)对商品的库存数进行预扣减。

  4. 库存检查:减操作前,要检查Redis中的库存数量,如果足够,则继续执行减操作,否则直接返回“库存不足”。

    • 如果库存不足,秒杀结束,返回失败信息。
    • 如果库存足够,则预扣减成功。
  5. 生成订单:库存预扣减成功后,生成订单信息,通常会放入消息队列中异步处理,以进一步提高响应速度。

  6. 异步处理订单:订单服务消费消息队列,处理订单数据,并同步库存数据到数据库。

注意事项

  • 数据一致性:虽然使用Redis可以减轻数据库的压力,但是需要考虑应用服务器、Redis和数据库之间数据的一致性问题。通常可以通过设置合理的过期时间、监听库存变化、定时同步等手段来确保。

  • 失败恢复:如果在减库存之后的某个步骤失败了(如订单创建失败),需要有一套策略来处理这种情况,比如可以返还预扣减的库存等。

  • 过载保护:即使使用Redis,系统也可能因为请求过多而过载。因此,还需要结合限流、熔断等策略来保护系统。

  • 安全问题:防止恶意用户通过刷单等手段扰乱秒杀活动的公平性。

  • 冷热数据处理:在活动结束后,需要将不再变化的数据(如成功的订单信息)从高速缓存中移到稳定存储中去。

数据库层流量控制

对于请求到数据中的流量,写入的流量就是真正下单成功的流量和需要扣减库存的动作,可以通过MQ进行异步写入避免DB的瞬时压力过大

在设计秒杀系统时,数据库是整个系统能否顺利运行的关键。秒杀系统面临的最大挑战是在短时间内处理大量请求,这直接导致数据库面临巨大的压力。因此,数据库的优化是保证秒杀系统能够高效、稳定运行的重要环节。下面是一些数据库优化的策略:

1. 索引优化

  • 为经常查询的列创建索引,减少查询时间。
  • 避免使用非索引列进行查询,特别是在WHEREJOIN等操作中。
  • 定期检查和优化索引,避免索引过多导致的维护成本增加。

2. 读写分离

  • 使用主从复制机制,将查询和更新操作分离。所有的写请求都发送到主服务器,读请求则分散到多个从服务器,减轻主数据库的压力。

3. 分库分表

  • 当单一表数据量极大时,通过水平分割(Sharding)将数据拆分到多个数据库或表中,可以有效提高查询性能和并发处理能力。
  • 考虑使用中间件如Shardingsphere、MyCAT等来管理分库分表,简化开发。

4. 缓存策略

  • 利用Redis等内存数据库缓存经常访问的数据,减少对数据库的直接访问次数。
  • 设置合理的缓存过期时间,防止数据长时间不一致。

5. 异步处理

  • 利用消息队列减少数据库的写操作。比如用户下单操作,可以先将请求发送到消息队列中,然后异步处理这些请求,减少数据库瞬时写操作的压力。

6. SQL优化

  • 避免使用SELECT *,只查询必要的列,减少网络传输量。
  • 尽量避免在SQL中使用复杂的逻辑和运算,尤其是对大量数据的计算和排序。
  • 使用批处理来处理大量数据的插入,更新操作,减少单条记录操作的频率。

7. 使用合适的隔离级别

  • 根据业务需求选择合适的事务隔离级别,避免不必要的锁带来的性能影响。在一些场景下,可以适当降低隔离级别,减少锁的竞争。

8. 数据库参数调优

  • 根据系统的实际运行情况,对数据库的配置参数进行调优,比如连接池大小、缓冲区大小等。

9. 定期做数据库维护

  • 定期对数据库进行维护,如更新统计信息、重建索引、清理碎片等,保持数据库性能。
  • 29
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值