秒杀场景的设计思路和方案

简介: 秒杀场景的设计思路和方案

本文主要介绍秒杀场景下的系统设计思路和方案。

秒杀活动和其他正常的业务活动相比,具有瞬时流量巨大的特征,所以需要和其他业务进行隔离,并且也需要更多的资源投入才能支撑这样大流量的业务,还需要考虑请求失败情况的处理方案。

进行秒杀设计的重点问题和设计原则有:

  1. 需要进行隔离设计,包括业务隔离、系统隔离、数据隔离;
  2. 需要进行前置的负债均衡和限流处理;
  3. 提前对热点数据进行处理;
  4. 需要考虑失败兜底策略和数据一致性的问题;

一、业务说明

用户视角的业务流程:

运营视角的业务流程:

二、系统架构设计

下图从一次用户秒杀请求来分析会涉及到的部分。

由于秒杀请求流量巨大,须有一般会在服务前端前置Nginx服务器,一个作用是用来做负载均衡,一个作用是用来做反向代理,可以用来实现静态资源服务器。

下一个阶段就来到了web网关服务,这个阶段可以实现常见的认证和鉴权功能,同时也可以进行流量筛选,通过设置黑白名单,可以过滤一部分流量。

下一个节点就是秒杀的业务服务,通常秒杀业务不会是一个服务实例能支撑的,所以在设计的时候要考虑到后续的弹性扩缩容,需要无状态设计。

最后的业务一定是请求到自己业务的数据库或者请求外部服务,针对自己的内部服务,一般会涉及数据库+缓存的支撑或者写入消息中间件进行异步处理,也可能设计服务内的RPC调用,针对外部服务,可能会涉及到HTTP调用。

常见的架构设计:

三、数据隔离策略

由于秒杀业务和普通业务大有不同,为避免其瞬时流量影响到普通业务,所以需要将其进行隔离包括。一般情况下可以从业务、系统、数据层面进行考虑。

业务隔离

为和普通业务区分开,针对秒杀业务一般会有单独的入口也详情页面,对于运营人员来说,也会由单独的秒杀业务提报平台。通过不同的入口来隔离秒杀业务和普通业务。

系统隔离

秒杀业务自身服务需要单独部署,并根据业务流量具有弹性扩缩容的能力,根据实际情况决定是否需要对涉及到的服务也做单独拎出来支持秒杀业务。

数据隔离

主要针对的数据库服务,秒杀是一个多读多写的场景,如果不和其他业务进行数据库层面的隔离,那可能会影响到正常的业务。

四、不同阶段的处理方案

1.秒杀前的处理

预约

从业务角度考虑,在秒杀之前可以引入预约制度,只有预约后的用户才能进行秒杀,这样在进入秒杀前就能拦截一大半的流量,本身用来进行秒杀的商品不会太多,虽然说秒杀的业务价值是广告营销,但吸引一千倍还是一万倍的用户来秒杀其实区别不大。

热点数据预热

秒杀的商品一般固定,其商品详情信息一般也固定,针对秒杀时候的多读情况,可以先进行热点数据的预热,在开启秒杀活动前,将商品详情信息读入到redis中,这样在进行秒杀的时候不至于对数据库造成太大的压力。

2.秒杀中的处理

验证码和限购

在进入秒杀阶段了,流量会在瞬间增长,所以从业务角度来说,可以将这些流量分散开来,避免对服务产生较大的冲击,监控流量过大,可以加入验证码校验这种策略,将流量后移和平滑,可以选择Happy-Captcha进行验证码校验,代码实现如下:

<dependency>
    <groupId>com.ramostear</groupId>
    <artifactId>Happy-Captcha</artifactId>
    <version>1.0.1</version>
</dependency>
---------------------------
@RestController
@RequestMapping("/happy-captcha")
public class HappyCaptchaController {
    @GetMapping("/generator")
//    @TokenCheck(required = false)
    public void generatorCode(HttpServletRequest request, HttpServletResponse response){
        HappyCaptcha.require(request, response)
                .style(CaptchaStyle.ANIM)//设置动画
                .type(CaptchaType.ARITHMETIC_ZH)//设置算数验证码
                .build().finish();
    }
    @GetMapping("/verify")
//    @TokenCheck(required = false)
    public String verify(@RequestParam String verifyCode, HttpServletRequest request){
        Boolean aBoolean=HappyCaptcha.verification(request, verifyCode,true);
        if(aBoolean){
            HappyCaptcha.remove(request);
            return "通过";
        }
        return "不通过";
    }
}

除了可以在秒杀之前设置预约环境,还可以没每个用户、每个区域、每个时间点还有每个IP等设置限购,通过这正方式也可以减少秒杀时候用户重复请求。

消息队列异步处理

在技术层面,可以通过消息队列来削减秒杀时候海量请求对系统和数据库造成的压力,先请求到消息队列,通过消息队列的排队和限流机制,来减轻后端的压力,比如在用户下订单的操作上,可以先将订单处理的任务放到消息队列中,再通知下游的多线程来处理。

负载均衡和限流

处理大流量场景单服务实例肯定能是不行的,在秒杀这种情况需要多服务共同支撑,所以选择哪个服务实例处理就需要用到负载均衡,一般会使用负载均衡服务器Nginx在进入系统前进行分流,减轻单实例的压力。

针对于限流处理,这个Nginx也能够实现,这个只是在网关层面的实现,在后面的业务处理中也可以处理,比如通过线程池的排队和消息队列的排队处理等。

可靠性处理

在设计秒杀过程,需要考虑数据一致性的问题,需要进行幂等性设计,防范重复下单导致的数据不一致。

同时需要考虑分布式事务的问题,当出现下单失败的情况,由于订单数据、商品数据、支付数据存在不同的库中,需要同时回滚。

3、秒杀后的处理

主要涉及一些兜底处理方案,包括但流量过大进行的降级和熔断等。

针对秒杀场景,由于价格便宜,肯定会有很多黑产账户来抢购,所以怎么识别正常用户就需要进行风控系统处理。

4.常见问题


TODO

  • 可以写的更详细,针对常见问题进行说明;


相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
目录
相关文章
|
负载均衡 前端开发 算法
聊聊高并发应用中电商秒杀场景的方案实现
聊聊高并发应用中电商秒杀场景的方案实现
874 0
|
缓存 负载均衡 Dubbo
Sentinel 集群限流设计原理
Sentinel 集群限流设计原理
Sentinel 集群限流设计原理
|
11月前
|
缓存 NoSQL 算法
高并发秒杀系统实战(Redis+Lua分布式锁防超卖与库存扣减优化)
秒杀系统面临瞬时高并发、资源竞争和数据一致性挑战。传统方案如数据库锁或应用层锁存在性能瓶颈或分布式问题,而基于Redis的分布式锁与Lua脚本原子操作成为高效解决方案。通过Redis的`SETNX`实现分布式锁,结合Lua脚本完成库存扣减,确保操作原子性并大幅提升性能(QPS从120提升至8,200)。此外,分段库存策略、多级限流及服务降级机制进一步优化系统稳定性。最佳实践包括分层防控、黄金扣减法则与容灾设计,强调根据业务特性灵活组合技术手段以应对高并发场景。
3016 7
|
存储 Prometheus Cloud Native
分布式系统架构6:链路追踪
本文深入探讨了分布式系统中的链路追踪理论,涵盖追踪与跨度的概念、追踪系统的模块划分及数据收集的三种方式。链路追踪旨在解决复杂分布式系统中请求流转路径不清晰的问题,帮助快速定位故障和性能瓶颈。文中介绍了基于日志、服务探针和边车代理的数据收集方法,并简述了OpenTracing、OpenCensus和OpenTelemetry等链路追踪协议的发展历程及其特点。通过理解这些概念,可以更好地掌握开源链路追踪框架的使用。
1536 41
|
消息中间件 NoSQL 架构师
招行面试:亿级秒杀,超卖问题+少卖问题,如何解决?(图解+秒懂+史上最全)
45岁资深架构师尼恩在读者交流群中分享了如何系统化解决高并发下的库存抢购超卖少买问题,特别是针对一线互联网企业的面试题。文章详细解析了秒杀系统的四个阶段(扣库预扣、库存扣减、支付回调、库存补偿),并通过Redis分布式锁和Java代码示例展示了如何防止超卖。此外,还介绍了使用RocketMQ延迟消息和xxl-job定时任务解决少卖问题的方法。尼恩强调,掌握这些技术不仅能提升面试表现,还能增强实际项目中的高并发处理能力。相关答案已收入《尼恩Java面试宝典PDF》V175版本,供后续参考。
|
存储 NoSQL 算法
分布式唯一 ID 的 7 种生成方案
在互联网的业务系统中,涉及到各种各样的ID,如在支付系统中就会有支付ID、退款ID等。那一般生成ID都有哪些解决方案呢?特别是在复杂的分布式系统业务场景中,我们应该采用哪种适合自己的解决方案是十分重要的。下面我们一一来列举一下,不一定全部适合,这些解决方案仅供你参考,或许对你有用。
分布式唯一 ID 的 7 种生成方案
|
NoSQL Java API
微服务——SpringBoot使用归纳——Spring Boot 中集成Redis——Spring Boot 集成 Redis
本文介绍了在Spring Boot中集成Redis的方法,包括依赖导入、Redis配置及常用API的使用。通过导入`spring-boot-starter-data-redis`依赖和配置`application.yml`文件,可轻松实现Redis集成。文中详细讲解了StringRedisTemplate的使用,适用于字符串操作,并结合FastJSON将实体类转换为JSON存储。还展示了Redis的string、hash和list类型的操作示例。最后总结了Redis在缓存和高并发场景中的应用价值,并提供课程源代码下载链接。
2720 0
|
消息中间件 中间件 Kafka
分布式事务最全详解 ,看这篇就够了!
本文详解分布式事务的一致性及实战解决方案,包括CAP理论、BASE理论及2PC、TCC、消息队列等常见方案,助你深入理解分布式系统的核心技术。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
分布式事务最全详解 ,看这篇就够了!
|
SQL 缓存 监控
MySQL慢查询:慢SQL定位、日志分析与优化方案,真心不错!
MySQL慢查询:慢SQL定位、日志分析与优化方案,真心不错!
MySQL慢查询:慢SQL定位、日志分析与优化方案,真心不错!

热门文章

最新文章