秒杀系统总体方案目标与架构设计
在前面的文章中,梳理了秒杀系统的需求和业务流程,并对秒杀系统的技术流程进行了总体梳理,不管是从业务角度出发,还是从技术角度出发,都大致了解了秒杀系统的执行流程。从业务和技术角度了解秒杀系统的执行流程后,接下来,就要制定方案目标和总体架构设计了。
一、前言
相信很多小伙伴都有多这样的体会,接到需求后,如果不做全面的需求分析、系统分析和架构设计,一上来就干代码,往往在开发中途就会发现代码不太符合需求,或者突然发现有更好的实现方式,大部分时候,已经来不及将代码推倒重来,只能在原有代码的基础上苦苦支撑。最终,原本设想的高并发、高性能、高可用和高可扩展的代码,却变成了一坨 “屎山”。
二、本章诉求
作为系统架构师和研发人员,在充分了解了系统需求、业务流程和技术流程后,就需要为系统设定方案目标,制定技术方案选型,对系统进行总体架构设计和分层架构设计。从全局视角充分理解秒杀系统的方案目标、技术选型、总体架构和分层架构,以指导后续秒杀系统的具体实现。
三、方案目标
在进行技术选型和总体架构设计之前,需要明确一个事项,就是系统无论采用何种方案,采用何种架构设计都需要明确这种方案的业务目标、技术目标和架构目标,并在研发过程中不断评估系统的总体性能表现,发现系统瓶颈并不断进行优化。
总体上,无论采用何种方案实现秒杀系统,都要实现如下方案目标。
- 业务目标:满足用户故事中的各类场景。
- 技术目标:秒杀商品详情页接口:10W+QPS,秒杀接口:1W+TPS。
- 架构目标:高并发、高性能、高可用、可监控、可预警、可伸缩。
四、技术选型
在技术选型上,除了采用 SpringBoot 等基础框架外,也会采用容器化方案。为了尽量降低技术门槛,在整个秒杀系统的技术选型中,主要采用市面上比较主流的技术框架和方案,具体技术选型如下所示。
- 开发框架:SpringBoot。
- 缓存:Redis + 本地缓存。
- 数据库:MySQL。
- 业务网关:SpringCloud Gateway。
- 持久层框架:MyBatis。
- 服务配置与注册发现:Nacos。
- 容器:Docker。
- 容器化管理:Swarm、Portainer。
- 监控:Prometheus、Grafana。
- 系统限流:Nginx+Lua、Sentinel。
- 消息中间件:RocketMQ。
- 单元测试:Junit。
- 压测工具:JMeter。
五、一般系统架构设计
如果是按照一般系统的架构设计方案来设计秒杀系统的话,相信大部分小伙伴会将秒杀系统的架构设计成如图 6-1 所示。

这种架构设计也是比较常见的,在这种架构设计中,Nginx 只做负载均衡和反向代理,研发人员更多的是关注 Web 服务层和基础服务层的开发。虽然这种架构设计在一般的系统中没什么问题,但是放到秒杀系统中,会存在很多问题。
(1)Web 服务性能问题
Nginx 只提供负载均衡与反向代理的功能,大部分流量会直接进入 Web 服务层,Web 服务层一般会采用 Tomcat 作为服务器。了解 Tomcat 的小伙伴都知道,Tomcat 是通过线程池来处理请求。如果大部分流量都直接涌入 Tomcat 的话,Tomcat 就会瞬间接收大量的请求,如果 Tomcat 线程池中的线程设置的比较小,很容易导致 Tomcat 线程池中的线程不够用,继而 Tomcat 中线程池的等待队列会被占满,后续的请求会被拒绝,并且 Tomcat 会持续高负载运行,最终导致系统卡顿 。如果 Tomcat 线程池中的线程数设置的过大,很容易将 CPU 打满,到时机器卡死,即使没有卡死,当 Tomcat 中线程池的等待队列被占满后,后面的请求也会被拒绝掉,总体上的表现就是性能很差,并且会有很多请求被拒绝掉。
(2)拉取资源填充数据性能问题
这种架构设计无论是将静态资源放在 Nginx 中,还是放到 Web 服务层,对会表现的比较卡顿。因为大量请求涌入 Web 服务层,会大量的调用相关的接口,导致 Web 服务层变得卡顿,后续请求进入系统后,加载静态资源,例如静态页面后,静态页面会调用接口获取数据,由于接口此时变得非常卡顿,就会导致静态资源上的数据加载缓慢,直接表现就是页面无法正常加载,拉取资源填充数据性能很差。
六、秒杀系统总体架构设计
可以在一般系统架构设计的基础上,进行优化设计,来满足秒杀业务场景的需求,优化后的秒杀系统屏蔽掉技术细节的架构设计如图 6-2 所示。

对比图 6-1 和 6-2 可以看出,在屏蔽掉技术实现细节的前提下,在秒杀系统的架构设计中,会将静态资源放到 CDN。并且对业务校验和流量管控进行前置化,放大 Nginx 的职责。使得 Nginx 不仅具备反向代理和负载均衡的功能,还能实现限流、黑白名单、流量管控、业务校验等,并且在 Nginx 层面也能实现直接查询商品数据返回给客户端。
也就是说,在这种架构模式下,充分利用 Nginx 的高并发、高吞吐的能力,尽量将大部分刷单流量和无效请求拦截在 Nginx 层,使得进入系统的流量是真正的有效流量,这样会大大减轻业务系统的压力。
除了在 Nginx 中实现限流、黑白名单、流量控制、业务校验等功能外,为了进一步保证下游系统的安全,在 Web 服务层也可以实现限流、降级、流控、业务校验、服务降级等流量管控措施。
经过一系列的流量处理措施,进入基础服务层面的流量已经相对比较小和可控了。那么问题来了:这种架构设计还有进一步优化的空间吗?
七、秒杀系统容器化架构设计
为了进一步增强秒杀系统的性能、可用性和弹性伸缩性,可以对秒杀系统的架构设计进行进一步优化,采用容器化架构设计,如图 6-3 所示。

由图 6-3 可以看出, 对秒杀系统进行容器化架构设计优化之后,总体上会分成客户端、流量入口、系统网关、应用服务、容器化和基础支撑服务等。
(1)客户端
客户端主要包括 PC、H5、APP 和小程序,可以将 PC 和 H5 等静态资源发布到 CDN 服务器,来加速静态资源的加载速度。
(2)流量入口
主要由 Nginx 负责流量的入口,此处同样会放大 Nginx 的职责,除了常规的反向代理和负载均衡外,Nginx 还会提供限流、黑白名单、流量控制、业务校验和商品数据查询等功能。也就是说,在 Nginx 层会做一些业务逻辑处理。
(3)系统网关
系统网关层除了做路由功能外,还提供限流、熔断、鉴权与安全的功能,可以使用 SpringCloud Gateway 结合 Sentinal 实现。
(4)应用服务
在应用服务层,除了做业务开发外,需要考虑本地缓存、分布式缓存、缓存数据一致性,这里缓存数据一致性包括本地缓存与分布式缓存,缓存与数据库数据的一致性问题。同时,在应用服务层采用动静分离的模式,将动态资源与静态资源进行隔离,并进行业务校验与业务隔离,在数据的序列化与反序列化上进行优化。同时在业务处理层面,尽量做到数据精简和简化相关的计算逻辑。
(5)容器化
在容器化层面,会通过 Docker、Swarm 和 Portainer 实现,其中,会基于 Swarm 和 Portainer 对容器化进行管理。
(6)基础支撑服务
基础支撑服务层主要是由一些基础的中间件实现,包括:MySQL 数据库、Redis 缓存、RocketMQ 消息队列、Prometheus 监控和 Portainer 容器管理等基础中间件实现,基础支撑服务会对整个秒杀系统提供最基础的数据、传输、监控和容器管理等服务。
(7)其他功能实现
除了上述分层架构外,对于建设秒杀系统来说,还要考虑异常监控、服务注册与发现、可视化、服务降级与兜底数据、服务限流、服务容灾、容量规划与扩缩容和全链路压测等。