程序员过关斩将--搞定秒杀,只需要这几步!!

灵魂拷问

  • 秒杀这种大并发的写场景,直接分库分表开干?

  • 应对秒杀活动的流量高峰很难吗?

  • 不要拿淘宝级别的秒杀忽悠我

秒杀活动特点

我敢说凡是做过电商的同学,都会遇到运营展开的秒杀,限时购等“高并发”的活动。市面上也有不少针对秒杀的解决方案,什么分库分表,缓存,消息队列呀,但凡能想到的技术“靓点”都基本会写上一段。我觉得应对秒杀这样的带有流量峰值的业务,还是要仔细分析业务的特性,以及根据自己系统的业务量来确定需要采用哪些技术“靓点”,假如:一个日活10万的系统,采用了分库分表,缓存,消息队列,限流,降级等等技术手段,虽然功能上达到了预期,但是其实资源上可能会有些浪费,技术上也许只需要一个限流手段就足够了。说这些不是想表达什么,我只是想说,那些上来就分库分表等“大手笔”的“优化”手段一定要根据实际业务去考察是否需要实施。

言归正传,秒杀这种业务场景其实特点很明显:

  • 带有短期流量峰值特性,即:短时间内会有大量的请求涌入

  • 请求的数据带有热点性,即:大量的请求同一数据

  • 请求的成功有效率低,即:大量的请求中可能只有少量请求会成功处理业务

  • 请求的流量峰值发生在下单之前,即:付款阶段很少存在流量峰值

静态资源

静态资源是指商品的图片,视频,音频,html页面等几乎不会变化的资源,这些资源的处理方式和缓存类似,尽量放在离用户最近的地方,比如:浏览器的本地缓存,当缓存过期的时候,优先推荐从CDN中获取,CDN是应对静态资源访问高峰的最简单粗暴,也是最有效的解决方案,如果没有CDN怎么办?那最少要把请求这些静态资源的服务器和后台业务服务器物理上分离,避免因为静态资源而影响正常的业务。比如:很早之前,我就喜欢每个项目单独一个存放图片,css,js的网站,这个网站的优势是无状态,可以做到傻瓜式横向扩展。

至于静态资源的缓存更新,我想你可以百度一下会有很多答案。

业务让步

如果负责秒杀活动的产品经理是一个优秀的产品经理的话,就不会设计出:用户点击秒杀马上给予是否下单成功,这样的系统。熟悉分布式的同学肯定会想到,想保证这样的数据一致性,在可用性上必然会有所牺牲。尤其是秒杀这样的业务,我觉得可用性要比一致性优先级要高,所以几乎所有的秒杀系统都会采用BASE理论来设计系统,一致性上采用最终一致性。在用户看来,点击秒杀按钮之后会弹出一个等待的提示,在技术上我们称之为:异步处理。异步处理对于用户最明显的感知就是不会马上得到结果,而是要等待一段时间。其实这样的设计也是在技术和业务之间的一个权衡,算是业务作出的让步。

至于秒杀之前需要输入验证码或者某些题的答案等手段,其实也可以算是业务上作出的一些让步。为什么说是让步呢?对于用户来说,最理想的秒杀场景是:一点秒杀按钮,马上给予结果,但是技术上难度太大了,所以嘛,互相让一步,大家都好过,对不对?

技术第一招:限流

对于秒杀出现的流量峰值,限流是最直接的削峰手段,被限制的请求可以直接返回,客户端提示请求中提示。可想而知,当10000/S的请求量被削成100/S的量,估计系统稍微优化一下就能抗住,至于限流的策略根据业务会有很多不同的方式,比如:

  • 针对同一个用户的请求次数限流,例如:每个用户每10秒只允许请求一次

  • 针对同一个IP的请求次数限流,例如:每个IP每10秒只允许请求一次

至于限流的算法,之前写过一篇文章来介绍,而且性能还不错哦

高并发优雅的做限流

第二招:消息队列

说到消息队列,每个程序员都不陌生,它相当于一个快速的数据容器,可以作为一个缓冲层来应对流量高峰。如果从它的使用场景上来看,它可以算是低速设备和高速设备之间的平衡者,使用消息队列来进行削峰是一个很明显的异步流程。

应用到秒杀的场景下,大量的请求会先进入消息队列,它不仅削平了流量的峰值,而且把秒杀下单的这个流程异步化,只要把请求都暂存入队列,消费端慢慢消费即可,但是这里要注意,如果消费的速度远远慢于消息的投递速度,可能会影响整个系统性能。

除了削峰之外,我始终认为消息队列的最大作用是系统解耦,它把下单和支付解耦,下单和支付业务可以随着自身系统的承载量来单独扩容。

第三招:缓存

为什么要加入缓存这个选项呢?别忘了,除了大量的用户下单这个写操作之外,还有更大量的用户请求下单结果这个读操作。当用户点击秒杀按钮之后,系统会弹出等待的提示框,很多系统是不停的去轮训用户的下单结果,我之前也写过缓存的文章,曾经提到过缓存最大的作用是提供读操作的快速响应。整个秒杀系统可以这样做:

  • 用户点击下单按钮,请求经过限流组件,如果成功,则进入下单环节(这里可以进入消息队列,异步下单)

  • 服务端无论是采用redis缓存,还是其他缓存组件,存放着下单成功的用户信息(也可以包括订单信息)

  • 客户端采用轮训的方式去查询缓存,如果查询到信息说明下单成功,进入支付环节,未查询到则说明下单还未成功

  • 服务端下单成功,往缓存中写入数据,当用户下次再次查询的时候会提示下单成功。

虽然过程很简单,但是其实整个过程中有很多细节需要注意,比如:缓存的过期时间怎么设置?能否引入下单中的状态?怎么保证缓存数据和数据库数据的一致性?

谈了千百遍的缓存数据的一致性问题

除了以上的信息数据缓存,商品的信息数据也可以放在缓存中,由于读的请求量比较大,可以考虑采用缓存副本的方式来提高整体的吞吐量。

写在最后

其实很多系统应用上消息队列+限流之后,针对秒杀业务已经足够了,其余的分库分表等方案可以根据自己的业务量来确定。每个系统在满足功能性的需求下,也在满足非功能性需求的前提下越简单越好,不是每个系统都需要淘宝的架构。

END

更多精彩文章

  • ????分布式大并发系列

  • ????架构设计系列

  • ????趣学算法和数据结构系列

  • ????设计模式系列

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/307205.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

吴恩达DeepLearningCourse4-卷积神经网络

部分内容参考之前的笔记 PyTorch深度学习实践 文章目录第一周:卷积神经网络边缘检测Padding、Stride三维卷积卷积神经网络中的一层池化层第二周:深度卷积网络实例探究残差网络1x1卷积Inception模块和网络卷积神经网络的迁移学习第三周:目标检…

那些鼓吹国内首个.NET 5框架的,该醒醒了!

前两天看过园子里有篇【国内首个 .NET 5 框架 XX 斩获 XXX stars,XXX 发布】,一顿羡慕嫉妒恨啊。我这.net core 3.1才上手没几天,还没用热乎呢,你这.NET 5的框架都出来了。我好难啊!不过难归难咱也得跟上啊。于是一个天高云淡的的…

吴恩达DeepLearningCourse5-序列模型

终于在八月末学完了这门课程,这个月虽然为此不停地忙碌,但每天都在进步也是一种乐趣。 吴恩达教授的课程循序渐进,适合初学者,非常感谢他的辛苦付出。 文章目录第一周:循环序列模型循环神经网络(RNN&#…

IdentityServer4系列 | 客户端凭证模式

一、前言从上一篇关于 快速搭建简易项目中,通过手动或者官方模板的方式简易的实现了我们的IdentityServer授权服务器搭建,并做了相应的配置和UI配置,实现了获取Token方式。而其中我们也注意到了三点就是,有哪些用户(users)可以通过…

数据结构 - 链表

准备重启尘封一年的博客作为学习笔记,看看自己能坚持多久。 最近会记录做过的算法题,语言描述只用于会意,仅供参考。 文章目录0.从尾到头获取链表的值(不是反转链表)1.寻找/删除单链表倒数第k个节点3.寻找单链表的中点…

[读书笔记] 《修炼之道:.NET 开发要点精讲》

《修炼之道:.NET 开发要点精讲》目录《修炼之道:.NET 开发要点精讲》第 1 章 另辟蹊径:解读.NET1.7 本章思考 > 位置 465第 2 章 高屋建瓴:梳理编程约定2.2 方法与线程的关系 > 位置 5192.7 线程安全 > 位置 5952.8 调用与回调 > 位置 6612.…

数据结构 - 概述

存储方式 数据结构的存储方式只有顺序存储(对应数组)、链式存储(对应链表)两种。所有上层的数据结构,如树、堆、栈等,存储方式均属于以上两种。顺序存储的优势是支持随机访问,缺点是需要连续的…

ASP.NET Core 使用 gRPC 初探

(RPC通讯示意图)为什么突然说到gRPC呢,其实以前就想说一说这个东西,也想尝试使用一下,一直没有机会,一直看我公众号的小伙伴肯定都知道,这几天一直在录制一个《eShopOnContainer微服务架构》系列…

源码都没调试过,怎么能说熟悉 redis 呢?

一:背景 1. 讲故事记得在很久之前给初学的朋友们录制 redis 视频课程,当时结合了不少源码进行解读,自以为讲的还算可以,但还是有一个非常核心的点没被分享到,那就是源码级调试, 对,读源码还远远…

算法 - DFS/BFS

写DFS函数的时候首先确定当前位置是否已经加入路径 DFS函数大概率会传递“位置信息”,根据位置信息获取下一步的选择,(大部分是在循环中)选择、执行、回退 在哪做选择,就在哪退出选择,参考题9 def DFS()…

你想象中的Task后续,很简单?

【导读】前不久,写过一篇关于Task的简短文章,通过评论和转载得到好评,刚好我昨晚又写了一篇实现简单的消息队列也提到了Task,难道不应该是看具体执行什么操作,再考虑最佳方案?本文我们再次通过简短内容谈谈…

算法 - 动态规划

动态规划是一种自底向上的算法,通常用于解决最大、最小等最值问题。 能使用动态规划解决的问题,一定具备: 重叠子问题:和暴力搜索不同,需要记录子问题的解,避免重复求解(剪枝)最优…

5G在工业互联网应用的机遇与挑战

移动通讯经过十年一代的发展,已经从1G发展到了5G,峰值速率实现十年千倍的增长,1G到4G是面向个人的,而5G是面向产业互联网和智慧城市服务。5G是一个颠覆性的技术,低时延(每秒钟下载一部高清电影)…

算法 - 前缀和

记录在做hot100时遇到的前缀和的题目。 目前见过的题目,都是前缀和结合其它的方法一起使用:用于求取一段连续路径的和(最大值/最小值/目标出现次数)。 需要注意的是,前缀和的判定方法是node2.val-node1.val target&am…

[C#.NET 拾遗补漏]10:理解 volatile 关键字

要理解 C# 中的 volatile 关键字,就要先知道编译器背后的一个基本优化原理。比如对于下面这段代码:public class Example {public int x;public void DoWork(){x 5;var y x 10;Debug.WriteLine("x " x ", y " y);} }在 Releas…

跟我一起学.NetCore之MediatR好像有点火

前言随着微服务的流行,而DDD(领域驱动设计)也光速般兴起,CRQS(Command Query Responsibility Seperation--命令查询职责分离)、领域事件名词是不是经常在耳边环绕,而MediatR组件经常用来对其技术的落地,凭这,小伙伴们说…

数据结构 - 单调栈、单调队列

单调栈:每日温度 请根据每日 气温 列表 temperatures ,请计算在每一天需要等几天才会有更高的温度。如果气温在这之后都不会升高,请在该位置用 0 来代替单调栈基本只处理NGE问题(Next GreaterElement)。对序列中每个元…

不想写脚本清理 mongodb 中的垃圾数据,ttlIndex 能帮到你!

mongodb一直都在不断的更新,不断的发展,那些非常好玩也非常实用的功能都逐步加入到了mongodb中,这不就有了本篇对ttlindex的介绍,刚好我们的生产业务场景中就有一个案例。。。一:案例分析 生产的推荐系统要给用户发送短…

数据结构 - 最小堆最大堆

可以在O(nlogn)的时间复杂度内完成排序典型的用法是,寻找 第k个/前k个 最大/最小元素,k个有序序列合并 1.合并K个升序链表(最小堆实现) 或许可以改进成每次堆只存放K个元素? # Definition for singly-linked list. …

python程序启动其他python程序,如何使用Python启动应用程序的实例?

I am creating a Python script where it does a bunch of tasks and one of those tasks is to launch and open an instance of Excel. What is the ideal way of accomplishing that in my script?解决方案While the Popen answers are reasonable for the general case, I…