写点什么

秒杀系统的架构解决之道

  • 2017-04-17
  • 本文字数:4221 字

    阅读完需:约 14 分钟

本文将会从三个方面来分别探讨如何设计应用架构以更好的支持“秒杀”类需求,包括秒杀带来的问题和挑战、产品架构解决之道、流量控制解决方案。

秒杀场景下带来的海量用户所造成的流量突增对系统冲击力可想而知,瞬时流量之高一方面造成的读写冲突,数据库锁会非常严重,另一方面应用服务器能否撑住也是一个问题。同时由于秒杀业务一般是各种活动带来,需要快速上下线,这在开发上也会提出更高的标准,快速支持需求而不出错。从系统上讲我们要做到高可用和高并发;从开发效率上我们要做到敏捷开发以支持产品快速迭代。接下来让我们从产品架构和流量控制这两个方面来讨论并解决这个问题。如果把解决秒杀问题看成一种武林秘籍,则产品架构是内功,流量控制是招法,上乘内力搭配制胜招法则无往而不利。

内功:产品架构解决之道

向一站式架构说"NO"

上图是一个典型的一站式架构,未经过良好的设计的系统随着时间的推移逐渐会转换成上图这样,一方面是产品业务的压力,另一方面也是先天的设计不足。一站式架构存在很多问题。

首先就是不易扩展,难以维护。随着业务的发展,对系统进行扩容难以避免,而一站式架构的可扩展性却令人堪忧,对其扩容则相当于对系统中的所有功能进行扩容,从代码确认到测试再到环境都是一项艰巨的任务。一站式架构中的扩容往往建立在“既然什么都没改,则运行应该正常”的假设之上,而扩容迁移中的各种 BUG 则隐藏在这种假设之中。系统所需的各种权限也随着规模而不断增多,连接的各种组件也越来越多,由此带来的维护性问题也会持续加重。

其次是代码难以理解,开发质量得不到保证。随着系统规模的扩大,即便是最初经过良好设计的代码,经过人员迭代,需求压力,也难免会逐渐走向混乱。渐渐的,各种跨层调用,不合适的封装,有副作用的函数等都会出现在代码中,这些设计侵入到代码中的每个角落,每个人都能见,而每个人都会选择性忽略,因为错综复杂的调用难以调整,也很难找到人员来进行整体测试。而这些都是 BUG 产生的温床。

最后在一站式架构下项目的可靠性是无法得到保证的,由于业务调整而修改一处逻辑,往往会影响到代码中很多功能的逻辑,而这些额外受到影响的功能则通常不会得到测试,只是在假定这些都是正常的,而这种假定也通常正确,直接潜在的问题爆发。该出错的总会出错,墨菲定律往往这时候是最有效的。

综上可以看出一站式架构设计与敏捷开发格格不入,持续开发,持续集成,持续部署也就只能变成空谈了。

微服务架构

上图是优化后的微服务架构,将整个系统拆分成订单、推送、折扣、产品、个人信息等各个微服务,每个服务都有自己的数据库和缓存等,并且不会互相交叉。各服务之间使用消息队列、RPC 调用等传输数据。目前大部分系统设计可能处于一站式架构和微服务架构之间,即上层应用可能已经服务化,但是数据库层面还是使用同一个库。但个人以为系统应该朝完全微服务化努力,隔离数据库层面的共用,以获得更高的系统可靠性。

微服务架构下的系统更加容易进行扩展,可以只针对需要扩容的系统来进行扩容,例如订单量增大,可以只扩容订单服务,而对于其他服务例如个人信息、折扣中心等都都不进行调整,这样一方面减少了系统扩容而对整体稳定性带来的变化,即只需测试新环境中的订单服务即可,随着微服务拆分的越细,这种优势也就越大。

在这种微服务架构下,开发人员可以更加集中精力,将重点放到少量的代码和明确的业务上,这样能够产出更加优雅的代码和良好的设计,在代码优化调整中,也不会由于到处调用而畏手畏脚。每个微服务可以安排 2-3 人的小组专门维护,这样也会减少一个微服务内部的沟通成本,而进一步提高生产力。每个微服务小组可以独立工作,无需过多协调即可实践新功能或想法。

随着技术的不断发展,项目所用的技术架构总会过时,在系统技术革新上,对于传统的一站式架构,甚至是之前提到的服务化架构在应用新技术上都会遇到不小的困难,牵一发动全身,技术改革往往除了推倒重来而没有其他办法。对于微服务架构,由于系统的完全拆分,公共组件依赖只剩下异步的消息队列,在新技术应用这方面则有了天然优势。微服务基于组件开发设计,提供了在开发过程中技术选型的最大灵活性,甚至是编程语言的变化都可以进行尝试。

最后要提到的,就是系统稳定性和可用性方面的考虑。在业务需求的持续推动下,持续部署不可避免,在线系统随时都需要进行上线。随着业务的增长、系统的复杂,系统部署时造成问题的潜在可能性会大大提高。而微服务在这方面极大的提高了系统的可靠性。由于微服务的划分,故障天然被隔离,某个服务的故障,不会造成系统的整体瘫痪。而发布的时间由于只需要发布更新相关的服务而大大缩短,这也提高了整体系统的稳定性。当面临问题需要回滚时,也只需要回滚更新相关服务即可,而这在一站式架构中将会是一个灾难。

良好的架构可以更好的支持快速迭代。高内聚的设计将开发人员精力集中到相对集中的领域以设计更优雅的代码实现。随着技术的演进,项目架构也可以跟着一起迭代升级。也可以更好的支持持续集成、持续部署。总之,微服务可以渗透到开发中的每个领域为业务迭代提供更好的支持。微服务这方面建议可以参考 Spring Cloud 和 Docker。

招法:流量控制解决方案

内功的修炼固然重要,不过并非一朝一夕可成,是需要长期的努力和不断的沉淀。在武学中固然有高神内力,同时也存在一些致胜招法,一旦练成即可功力猛进,下来就让我们看一下支持秒杀业务中的一些致胜招法:流量控制解决方案。

流量控制解决总览

如上图所示,在项目的整个架构中,流量要做到逐层减少。在每层中都可以使用一些方法来减少流量。

前端流量控制

前端流量控制,页面可以设计为动静分离,将尽可能多的数据使用 CDN 进行缓存,以减少到自己服务器上的流量。同时可以加入验证问题,拉长用户下单时间并防止刷单。对较核心逻辑担心用户破译验证方式,可以再增加服务器端的用户 ID 访问限制,例如同一用户 5s 内只能触发 1 次相关操作等。

反向代理流量控制

反向代理(Nginx)流量控制,很多页面或者接口响应数据都可以进行静态化处理,应用侧(Tomcat)可以定时生成这些资源,发到内容分发服务上,内容分发服务可以将这些静态化资源分发到所有的反向代理上。这些数据可以根据需要按照一定时间间隔进行更新。同时,也可以利用 Nginx 中的缓存配置功能,对热点接口进行缓存。

借助 Nginx 中 Nginx-lua 插件的功能,一些简单逻辑在 Nginx 中直接实现会比较容易,使用恰当,能够大幅减少到应用服务器的请求。例如倒计时,取系统当前时间等逻辑就非常适合在 Nginx 中使用 Lua 实现。对于存在缓存中的商品数量等信息也可由 Nginx 直接访问缓存返回,而不将请求再转发给应用服务器。

访问数据分析流量控制

在秒杀中,令人头疼的问题不只是正常流量突增。由于秒杀活动一般都带有优惠性质,恶意访问也会增多,对于恶意请求在 Nginx 层也可以做很多工作,进行一次拦截。Nginx 配置中有限制用户访问频率的配置可以根据需要进行配置。同时,也可以使用 nginx-lua 完成一些简单的封禁逻辑,例如调用接口可以封掉指定 IP 或者 UA 的访问请求。之后利用日志分析程序,对访问日志进行分析,将需要封掉的 IP 或者 UA 等信息调用 Nginx 上提供的接口进行封杀。

应用服务器流量控制

经过之前的处理,能够到达应用服务器的流量已经少了很多。对于秒杀活动这类的需求,可以准备专门的活动服务器,专门处理相关逻辑。可以使用不同域名进行分流,或者按照一定 URL 规则在反向代理服务器上进行分流。同时,对于到数据库进行操作的请求可以使用阻塞队减少到数据库的访问以减少行锁等。对于明显超出处理范围的请求可以直接返回秒杀已经结束。例如商品总量 300,剩余量 100,每台应用服务器上待处理的值超过总量的值则可以直接返回秒杀结束。剩余量可以存入缓存服务中,剩余量可以不那么精确,确保缓存中的剩余量 >= 实际剩余量即可。超出剩余量的请求也可以直接返回秒杀结束。

缓存存储多点部署以提高系统的整体可用性,避免缓存问题导致系统出错的情况。Redis 会是一个目前比较好的选择,主从自动切换等功能可以更好的增强系统整体可用性。对于使用单点 Memcached 等系统,建议可以配置 Keepalived,使得发生机器故障时,IP 可以自动转移到另外一台健康 Memcached 服务器上,虽然数据不可恢复,但是缓存组件依然可用。宕机的组件对系统造成的影响往往是不可预料的,尤其是在未良好设计的系统中,整体架构中应任一组件完全宕机的可能性。

对于秒杀活动需求,可能是一系列的活动,相关逻辑可以判断是否可以做到一个专门活动库中,并进行读写分离设计。有条件的情况下,数据库中间件会完成其中一部分工作。在没有相关条件的时候,即使没有数据库中间件,相关逻辑也可以直接在代码中实现。

对于数据库行锁问题,如有需要可以进一步优化,例如上图,将行锁问题通过拆分具体商品,增加分配 ID 标志,去掉行锁。这个变动的缺点是可能对现有业务逻辑影响较大。不过优点也很明显,在数据库层面消除了行锁。

流量控制总结

一图胜千言,以上讨论的流量控制总结方案可以总结到一张图上:

总结

结合微服务架构,我们最终的架构图可以是这样的:

以上供大家参考。

技术选型简介

平台应用构建技术选型如下,供大家参考:

  • 反向代理层 Nginx 推荐使用阿里开源的 Tengine,Tengine 中增强了 Nginx 中的很多功能并简化了配置。
  • 在虚拟化方面,可以按照物理机 -> 虚拟机 ->Docker 三层架构来实现虚拟化,在物理机上按照应用实例、缓存实例、消息队列实例等建立虚拟机,再分别在虚拟机上启动不同实例的 Docker。
  • 在应用构建方面,推荐使用 Spring Cloud 解决方案(由于历史原因,目前还保留部分 Dubbo 接口)。
  • 消息队列选型目前比较广泛,这里推荐一下阿里开源的 RocketMQ,目前已经捐赠给 Apache。我们内部也针对 RocketMQ 开发了一套易用 client,当然也在开源计划之中,相信不久就会和大家见面。目前我们系统每分钟接口请求量高峰在几十万左右,系统整体支撑再多的访问量相信也没有问题,各层、各服务根据需要都可以进行横向扩容以支撑更高的访问量。

参考资料

2017-04-17 17:018309

评论

发布
暂无评论
发现更多内容

软件定义世界 开源共筑未来 首届“开放原子开源大赛”火热进行中

开放原子开源基金会

Java 开源 程序员 开发者 算法

Nodejs项目yarn和node启动的区别

JavaScript node.js typescript YARN prisma

从信息量角度看人类智能与机器智能

Baihai IDP

人工智能 程序员 AI LLM 白海科技

数据中台的学习与总结 主赛道:技术人的 2023 总结

Echo_Wish

大数据 数据中台 年度总结 2023 2023年

抖音关键词商品列表API:电商行业的成功之道及实时数据获取的魔力

Noah

如何做到人均告警减少90%?B站新一代告警平台的设计与实践

TakinTalks稳定性社区

TiCDC核心原理解析

TiDB 社区干货传送门

性能调优 管理与运维 应用适配 TiCDC 源码解读

【12 月 23 日 上海线下活动预告】 数据库运维有话聊,谈谈你了解的灾备实践

TiDB 社区干货传送门

TiDB 优化器逻辑优化之 OR 表达式条件消除

TiDB 社区干货传送门

性能调优 TiDB 源码解读

华为云CodeArts Check常见问答汇总

华为云PaaS服务小智

华为云

欧睿 × 和鲸:联合打造 AI 中台赋能企业数字化转型,大幅提升模型产品研发效率

ModelWhale

人工智能 数据分析 数字化转型 企业 数智化

前方高能!2023开放原子开发者大会亮点攻略,一触即发

开放原子开源基金会

Java 开源 程序员 开发者 算法

KaiwuDB 连续三年荣获开源中国“优秀开源技术团队”

KaiwuDB

KaiwuDB 优秀开源技术团队

解放生产力!苏哒智能加入飞桨技术伙伴计划,用大模型革新企业办公工具

飞桨PaddlePaddle

人工智能 深度学习 办公 伙伴赋能

紫光展锐T820与飞桨完成I级兼容性测试 助推端侧AI融合创新

飞桨PaddlePaddle

人工智能 机器学习 程序员 硬件

【嵌入式Qt开发入门】在Ubuntu下编写C++教程。

百度搜索:蓝易云

c++ Linux ubuntu 云服务器 qt

网易游戏与华为达成鸿蒙合作

最新动态

观测云产品更新 | 智能监控、数据访问、指标分析等优化

观测云

智能监控 指标 数据访问

10倍提升-TiCDC性能调优实践

TiDB 社区干货传送门

迁移 性能调优 管理与运维 故障排查/诊断 备份 & 恢复

通过 Sysbench 在低配置低数据基础上分别压测 MySQL 和 TiDB,实际结果 TiDB 出乎我的想象。

TiDB 社区干货传送门

版本测评 性能测评 数据库架构设计 6.x 实践

Null-Aware 问题对 TiDB 优化器的影响(OOM)

TiDB 社区干货传送门

性能调优 管理与运维 故障排查/诊断 TiDB 源码解读 6.x 实践

闪闪发光的“她”· Ladies in Tech |相聚女性开发者论坛

开放原子开源基金会

Java 开源 程序员 开发者 算法

MySQL运维5-Mycat配置

EquatorCoco

MySQL 标签 配置化

关于响应式布局,你需要了解的知识点

EquatorCoco

响应式 页面布局 布局

掌握接口 RPC 测试:构建高效远程调用接口

Apifox

程序员 微服务 后端 RPC 接口测试

tidb这种把数据库放入docker是否是个好主意。

TiDB 社区干货传送门

数据库架构设计

义乌购商品详情数据接口|义乌购商品数据接口|义乌购API接口

tbapi

义乌购商品详情数据接口 义乌购数据接口 义乌API接口

关键词搜索淘宝商品列表数据接口|淘宝商品列表接口|淘宝API接口申请指南

tbapi

淘宝电商 淘宝API接口 淘宝商品列表数据接口 关键词搜索淘宝商品接口、

VSCode+GDB+Qemu调试ARM64 linux内核教程。

百度搜索:蓝易云

Linux vscode gdb 云服务器 qemu

诚邀报名 | 内核Hacker与Mogul邀您共论操作系统技术创新与发展

开放原子开源基金会

Java 开源 程序员 开发者 算法

抖音商品详情API接口在电商行业中的重要性及实时数据获取实现

Noah

秒杀系统的架构解决之道_语言 & 开发_胡因可_InfoQ精选文章