高并发核心编程SpringCloud+Nginx秒杀实战,秒杀系统的系统架构

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介: 秒杀系统的系统架构本节分多个维度介绍crazy-springcloud开发脚手架的架构,包括分层架构、限流架构、分布式锁架构、削峰的架构。秒杀的分层架构从分层的角度来说,秒杀系统架构可以分成3层,大致如下:(1)客户端:负责内容提速和交互控制。(2)接入层:负责认证、负载均衡、限流。(3)业务层:负责保障秒杀数据的一致性。

秒杀系统的系统架构

本节分多个维度介绍crazy-springcloud开发脚手架的架构,包括分层架构、限流架构、分布式锁架构、削峰的架构。

秒杀的分层架构

从分层的角度来说,秒杀系统架构可以分成3层,大致如下:

(1)客户端:负责内容提速和交互控制。

(2)接入层:负责认证、负载均衡、限流。

(3)业务层:负责保障秒杀数据的一致性。

1.客户端负责内容提速和交互控制

客户端需要完成秒杀商品的静态化展示。无论是在桌面浏览器还是在移动端App展示秒杀商品,秒杀商品的图片和文字元素都需要尽可能静态化,尽量减少动态元素。这样就可以通过CDN来提速和抗峰值。

另外,在客户端这一层的用户交互上需要具备一定的控制用户行为和禁止重复秒杀的能力。比如,当用户提交秒杀请求之后,可以将秒杀按钮置灰,禁止重复提交。

2.接入层负责认证、负载均衡、限流

秒杀系统的特点是并发量极大,但实际的优惠商品有限,秒杀成功的请求数量很少,如果不在接入层进行拦截,大量请求就会造成数据库连接耗尽、服务端线程耗尽,导致整体雪崩。因此,必须在接入层进行用户认证、负载均衡、接口限流。

对于总流量较小的系统,可以在内部网关(如Zuul)完成用户认证、负载均衡、接口限流的功能,具体的分层架构如图10-2所示。

网络异常,图片无法展示
|

图10-2 在内部网关(如Zuul)完成认证、负载均衡、接口限流

对于总流量较大的系统会有一层甚至多层外部网关,因此限流的职责会从内部网关剥离到外部网关,内部网关(如Zuul)仍然具备权限认证、负载均衡的能力,具体的分层架构如图10-3所示。

网络异常,图片无法展示
|

图10-3 外部网关与内部网关相结合完成权限认证、负载均衡、接口限 流

3.业务层负责保障数据一致性

秒杀的业务逻辑主要是下订单和减库存,都是数据库操作。大家都知道,数据库层只能承担“能力范围内”的访问请求,既是非常脆弱的一层,又是需要进行事务保护的一层。在业务层还需要防止超出库存的秒杀(超卖和少卖),为了安全起见,可以使用分布式锁对秒杀的数据库操作进行保护。

秒杀的限流架构

前面提到,秒杀系统中的秒杀商品总是有限的。除此之外,服务节点的处理能力、数据库的处理能力也是有限的,因此需要根据系统的负载能力进行秒杀限流。

总体来说,在接入层可以进行两个级别的限流策略:应用级别的限流和接口级别的限流。

什么是应用级别的限流策略呢?对于整个应用系统来说,一定会有一个QPS的极限值,如果超了极限值,整个应用就会不响应或响应得非常慢。因此,需要在整个应用的维度做好应用级别的限流配置。应用级别的限流应该配置在最顶层的反向代理,具体如图10-4所示。

网络异常,图片无法展示
|

图10-4 应用级别的限流

应用级别的流量限制可以通过Nginx的limit_req_zone和limit_req两个指令完成。假定要配置Nginx虚拟主机的限流规则为单IP限制为每秒1次请求,整个应用限制为每秒10次请求,那么具体的配置如下:

limit_req_zone $binary_remote_addr zone=perip:10m rate=1r/s;
limit_req_zone $server_name zone=perserver:1m rate=10r/s;
server {
 ...
 limit_req zone=perip burst=5;
 limit_req zone=perserver burst=10;
}

什么是接口级别的限流策略呢?单个接口可能会有突发访问情况,可能会由于突发访问量太大造成系统崩溃,典型的就是本章所介绍的秒杀类接口。接口级别的限流就是配置单个接口的请求速率,是细粒度的限流。

接口级别的限流也可以通过Nginx的limit_req_zone和limit_req两个指令配合完成,对获取秒杀令牌的接口,同时进行用户Id和商品Id限流的配置如下:

limit_req_zone $arg_goodId zone=pergood:10m rate=100r/s;
limit_req_zone $arg_userId zone=peruser:1m rate=1r/s;
server {
 #lua:获取秒杀token令牌
 location = /seckill-provider/api/seckill/redis/token/v2 {
 limit_req zone=peruser burst=5;
 limit_req zone=pergood burst=10;
 #获取秒杀token lua脚本
 content_by_lua_file luaScript/module/seckill/getToken.lua;
 }
}

以上定义了两个限流规则:pergood和peruser:pergood规则根据请求参数的goodId值进行限流,同一个goodId值的限速为每秒100次请求;peruser规则根据请求参数的userId值进行限流,同一个userId值的限速为每秒1次请求。

但是,Nginx的限流指令只能在同一块内存区域有效,而在生产场景中秒杀的外部网关往往是采用多节点部署的,所以这就需要用到分布式限流组件。高性能的分布式限流组件可以使用Redis+Lua来开发,京东的抢购就是使用Redis+Lua完成限流的,并且无论是Nginx外部网关还是Zuul内部网关,都可以使用Redis+Lua限流组件。

理论上,接入层的限流有多个维度:

(1)用户维度的限流:在某一时间段内只允许用户提交一次请求,比如可以采取客户端IP或者用户ID作为限流的key。

(2)商品维度的限流:对于同一个抢购商品,在某个时间段内只允许一定数量的请求进入,可以采取秒杀商品ID作为限流的key。

无论是哪个维度的限流,只要掌握其中的一个,其他维度的限流在技术实现上都是差不多的。本书的秒杀练习使用的是接口级别的限流策略,在获取秒杀令牌的REST接口时,针对每个秒杀商品的ID配置限流策略,限制每个商品ID每秒内允许通过的请求次数。

如果大家对进行用户维度的限流感兴趣,可以自行修改配置进行尝试。

秒杀的分布式锁架构

前面提到了超卖或少卖问题:比如10万次请求同时发起秒杀请求,正常需要进行10万次库存扣减,但是由于某种原因,往往会造成多减库存或者少减库存,这就会出现超卖或少卖问题。

解决超卖或者少卖问题有效的办法之一就是利用分布式锁将对同一个商品的并行数据库操作予以串行化。秒杀场景的分布式锁应该具备如下条件:

(1)一个方法在同一时间只能被一个机器的一个线程执行。

(2)高可用地获取锁与释放锁。

(3)高性能地获取锁与释放锁。

(4)具备可重入特性。

(5)具备锁失效机制,防止死锁。

(6)具备非阻塞锁特性,即没有获取到锁将直接返回获取锁失败。

常用的分布式锁有两种:ZooKeeper分布式锁和Redis分布式锁。如果使用ZooKeeper分布式锁来保护秒杀的数据库操作,那么它的架构图大致如图10-5所示。

网络异常,图片无法展示
|

图10-5 使用ZooKeeper分布式锁来保护秒杀的数据库操作

实际上,除了提供分布式锁外,ZooKeeper还能提供高可靠的分布式计数器、高可靠的分布式ID生成器的基础能力。ZooKeeper分布式计数器、分布式锁、分布式ID生成器等基础知识也是大家必须系统地学习和掌握的知识,但是不属于在本书介绍的内容,如果对这一块不了解,可翻阅本书姊妹篇《Netty、Redis、ZooKeeper高并发实战》。

ZooKeeper分布式锁虽然高可靠,但是性能不高,不能满足秒杀场景分布式锁的第3个条件(高性能地获取锁与释放锁),所以在秒杀的场景建议使用Redis分布式锁来保护秒杀的数据库操作。

秒杀的削峰架构

通过接入网关的限流能够拦截无效的刷单请求和超出预期的那部分请求,但是,当秒杀的订单量很大时,比如有100万商品需要参与秒杀,这时后端服务层和数据库的并发请求压力至少为100万。这种请求下,需要使用消息队列进行削峰。

削峰从本质上来说就是更多地延缓用户请求,以及层层过滤用户的访问需求,遵从“最后落地到数据库的请求数要尽量少”的原则。通过消息队列可以大大地缓冲瞬时流量,把同步的直接调用转换成异步的间接推送,中间通过一个队列在入口承接瞬时的流量洪峰,在出口平滑地将消息推送出去。消息队列就像“水库”一样,拦蓄上游的洪水,削减进入下游河道的洪峰流量,从而达到减免洪水灾害的目的。使用消息队列对秒杀进行削峰的架构如图10-6所示。

网络异常,图片无法展示
|

图10-6 使用消息队列对秒杀进行削峰

对于秒杀消息的入队可以直接在内部网关完成。内部网关在完成用户的权限验证、秒杀令牌的有效性验证之后,将秒杀消息发往消息队列即可。秒杀服务通过消息队列的订阅完成秒杀消息的消费。常用消息队列系统:Kafka、RocketMQ、ActiveMQ、RabbitMQ、ZeroMQ、MetaMQ等。本书的内容主要聚焦在Spring Cloud和Nginx,对消息队列这里不做过多的介绍,使用消息队列进行削峰的秒杀实现版本可参见后续的疯狂创客圈社群博客。

本文给大家讲解的内容是高并发核心编程,Spring Cloud+Nginx秒杀实战,秒杀系统的系统架构

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
打赏
0
0
0
0
436
分享
相关文章
Python 高级编程与实战:深入理解设计模式与软件架构
本文深入探讨了Python中的设计模式与软件架构,涵盖单例、工厂、观察者模式及MVC、微服务架构,并通过实战项目如插件系统和Web应用帮助读者掌握这些技术。文章提供了代码示例,便于理解和实践。最后推荐了进一步学习的资源,助力提升Python编程技能。
Python 高级编程与实战:构建微服务架构
本文深入探讨了 Python 中的微服务架构,介绍了 Flask、FastAPI 和 Nameko 三个常用框架,并通过实战项目帮助读者掌握这些技术。每个框架都提供了构建微服务的示例代码,包括简单的 API 接口实现。通过学习本文,读者将能够使用 Python 构建高效、独立的微服务。
Android实战经验之Kotlin中快速实现MVI架构
MVI架构通过单向数据流和不可变状态,提供了一种清晰、可预测的状态管理方式。在Kotlin中实现MVI架构,不仅提高了代码的可维护性和可测试性,还能更好地应对复杂的UI交互和状态管理。通过本文的介绍,希望开发者能够掌握MVI架构的核心思想,并在实际项目中灵活应用。
56 8
Nginx常用基本配置总结:从入门到实战的全方位指南
Nginx常用基本配置总结:从入门到实战的全方位指南
599 0
布谷直播系统源码开发实战:从架构设计到性能优化
作为山东布谷科技的一名技术研发人员,我参与了多个直播系统平台从0到1的开发和搭建,也见证了直播行业从萌芽到爆发的全过程。今天,我想从研发角度,分享一些直播系统软件开发的经验和心得,希望能对大家有所帮助。
Jeesite5:Star24k,Spring Boot 3.3+Vue3实战开源项目,架构深度拆解!让企业级项目开发效率提升300%的秘密武器
Jeesite5 是一个基于 Spring Boot 3.3 和 Vue3 的企业级快速开发平台,集成了众多优秀开源项目,如 MyBatis Plus、Bootstrap、JQuery 等。它提供了模块化设计、权限管理、多数据库支持、代码生成器和国际化等功能,极大地提高了企业级项目的开发效率。Jeesite5 广泛应用于企业管理系统、电商平台、客户关系管理和知识管理等领域。通过其强大的功能和灵活性,Jeesite5 成为了企业级开发的首选框架之一。访问 [Gitee 页面](https://gitee.com/thinkgem/jeesite5) 获取更多信息。
Jeesite5:Star24k,Spring Boot 3.3+Vue3实战开源项目,架构深度拆解!让企业级项目开发效率提升300%的秘密武器
Git进阶笔记系列(01)Git核心架构原理 | 常用命令实战集合
通过本文,读者可以深入了解Git的核心概念和实际操作技巧,提升版本管理能力。
基于HarmonyOS 5.0(NEXT)与SpringCloud架构的跨平台应用开发与服务集成研究【实战】
本次的.HarmonyOS Next ,ArkTS语言,HarmonyOS的元服务和DevEco Studio 开发工具,为开发者提供了构建现代化、轻量化、高性能应用的便捷方式。这些技术和工具将帮助开发者更好地适应未来的智能设备和服务提供方式。
100 8
基于HarmonyOS 5.0(NEXT)与SpringCloud架构的跨平台应用开发与服务集成研究【实战】
本地消息表事务:10Wqps 高并发分布式事务的 终极方案,大厂架构师的 必备方案
45岁资深架构师尼恩分享了一篇关于分布式事务的文章,详细解析了如何在10Wqps高并发场景下实现分布式事务。文章从传统单体架构到微服务架构下分布式事务的需求背景出发,介绍了Seata这一开源分布式事务解决方案及其AT和TCC两种模式。随后,文章深入探讨了经典ebay本地消息表方案,以及如何使用RocketMQ消息队列替代数据库表来提高性能和可靠性。尼恩还分享了如何结合延迟消息进行事务数据的定时对账,确保最终一致性。最后,尼恩强调了高端面试中需要准备“高大上”的答案,并提供了多个技术领域的深度学习资料,帮助读者提升技术水平,顺利通过面试。
本地消息表事务:10Wqps 高并发分布式事务的 终极方案,大厂架构师的 必备方案
高并发场景秒杀抢购超卖Bug实战重现
在电商平台的秒杀活动中,高并发场景下的抢购超卖Bug是一个常见且棘手的问题。一旦处理不当,不仅会引发用户投诉,还会对商家的信誉和利益造成严重损害。本文将详细介绍秒杀抢购超卖Bug的背景历史、业务场景、底层原理以及Java代码实现,旨在帮助开发者更好地理解和解决这一问题。
141 12

热门文章

最新文章