热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

电商系统设计艺术——秒杀业务设计

一、秒杀场景人多货少,只有少量的人能够抢购成功。高并发,秒杀业务在开始之前流量比较平稳,开始后流量会直线性的上升。持续时间短࿰

一、秒杀场景


  1. 人多货少,只有少量的人能够抢购成功。
  2. 高并发,秒杀业务在开始之前流量比较平稳,开始后流量会直线性的上升。
  3. 持续时间短,秒杀开始随着库存的减少流量会以瀑布式的下降,这个过程持续时间很短,一般为秒级。

二、常见问题


  • 系统崩溃,导致系统崩溃的原因比较复杂,常见的有以下几点:

          1、mysql操作时间长,优化表结构设计,合理建立索引,优化sql语句。通过调整尽量让sql语句的执行时间下降到30毫秒之内。至于如何优化sql操作感兴趣的可以关注我,以后会讲。

          2、频繁的操作mysql,在秒杀场景中,高频率的操作mysql是大忌,使用缓存或队列来减少mysql的压力。

          3、代码逻辑写的不合理或是业务本身导致,原则上尽量把可能造成较高性能消耗的逻辑靠后执行(下面系统 瓶颈会列出性能排序),通过层层验证阻断来减少消耗性能的逻辑执行,可重复利用的数据重复利用,减少性能低效的函数或第三方库使用。如果说是业务本身导致那基本无解,找负责人好好谈谈吧。

          4、文本操作过于频繁,常见于日志的写入、配置文件的读取。php作为一门脚本语言处理能力比较低,每次执行都需要进行解析释放等很多不必要重复的环节导致消化性能,利用swoole会好一些,但依然不建议使用PHP开发。对于日志写入这个不管用什么语言都会遇到相同的问题,可以利用延迟写入或异步写入来解决。

           5、带宽达到上限,这是一个经常会被忽视的细节,并发一上来总感觉慢,不知道为啥慢,看服务器的状态也抖很正常,其实很有可能是宽带跑满了。每一个用户的请求都会占用一定的宽带,所以尽量减少输入输出的大小,除此之外只能提高带宽来解决。


  • 库存超卖,在秒杀场景中库存超卖是很常见的问题,一般采用锁或原子操作来控制库存。
  • 机器人刷单攻击,对于火爆的单品很可能会被羊毛党进行刷单,在做防护的同时也需要强大自身防止服务器雪崩。

三、常见的系统瓶颈

对于系统瓶颈我们要先有一个处理速度上的基本认知,在程序开发的过程中我们劲量使用速度快的方式来处理,比如能用redis的别用mysql,能不夸机房请求的别夸机房,能内网的千万别外网,要合理的利用资源。

1、数据读写操作:程序自身数据读写>redis>mysql>磁盘

2、网络操作:本机>局域内网>跨机房>外网

四、正片

服务器层面的架构设计这里就不多做介绍了,感兴趣的可以看下这篇文章:电商系统设计艺术——高并发架构搭建

我们来看下应对秒杀场景都需要做哪些事

1、单独部署,这点基本上是必须要做的,秒杀场景往往突发流量会很高导致压垮服务器,如果未进行单独部署的话会导致其他业务也会受影响,单独部署可以有效的解决此问题,同时也更方便维护。

2、页面静态化,同时利用CDN或NGINX缓存可有效减少部分用户对后端业务的请求,将请求拦截在上游,同时前端页面还需要做到防止重复提交。

3、缓存应用,缓存是一个神器可以说,他能在很多层面来减少服务器的负担,常见的有利用缓存来减少数据库的操作。

4、限流、降级、熔断、隔离。秒杀只有少部分人可以抢购成功,限流可以挡住一大部分的流量。至于降级、熔断、隔离,这一系列的操作主要是为了保证服务的稳定性。虽然前段已经做了防重复提交手段,但是挡不住恶意用户利用机器人刷接口,这时候后端同样也需要做防重复提交的机制,IP锁,用户锁,口令等都可以,但是各有各的优缺点,结合实际场景使用,

5、削峰填谷,其实就是消息队列,如MQ,利用消息队列的特性来讲流量进行平滑过渡。

6、异步,在程序设计中能采用异步的地方就采用异步的形式,如:日志写入,下单等。

7、分布式负载,这个不用多说了吧,单机肯定是扛不住的,需要分布部署到多台机器上来分摊压力。

8、可伸缩,一是指业务的可扩展性,二是指方便服务器进行弹性伸缩操作以便合理利用服务器资源。

搞完后差不多就是上面的这种结构图,有了基本的结构我们在具体的看下如何扣减库存来保证不超卖同时又保证性能高效。

扣库存的方式分为三大类,支付减库存、下单减库存、预扣库存。

1、下单减库存:

这种方式在扣库存的过程中如果采用一定的限制条件是不会出现超卖的情况:update set num = num - 1 where = num>0,这里需要特别注意WHERE条件,如果在num-1小于0的情况下是不会更新成功的,这就保证了不会出现超卖的情况,弊端就是这种sql在执行效率上比较抵效,而且需要频繁的去操作sql显然不适用秒杀场景。

2、支付减库存:

 这种情况存在很多的弊端,从下面列举的弊端来看显然更加不适合秒杀场景。

     1)会存在大量的垃圾订单(无法支付的订单)占用资源。

     2)会造成下单后无法支付或支付后无法正常修改库存导致超卖,这是一个很严重的问题,老板被整破产都有可能~

3、预扣库存:

 我们讲库存预先存入redis里,当用户下单后利用redis的原子特性预先去扣减redis里的库存量,当扣减成功后在去异步生成订单,这样可有效减少对数据库的直接操作同时又避免了超卖情况的发生,这么看来预扣库存更加适合的秒杀场景。

可以看到不管使用哪种扣库存的方式都会有一个超时取消订单的模块,当用户下单后不支付在超过一定的时间范围后会自动取消订单保证不少卖。

 

 


推荐阅读
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 基于事件驱动的并发编程及其消息通信机制的同步与异步、阻塞与非阻塞、IO模型的分类
    本文介绍了基于事件驱动的并发编程中的消息通信机制,包括同步和异步的概念及其区别,阻塞和非阻塞的状态,以及IO模型的分类。同步阻塞IO、同步非阻塞IO、异步阻塞IO和异步非阻塞IO等不同的IO模型被详细解释。这些概念和模型对于理解并发编程中的消息通信和IO操作具有重要意义。 ... [详细]
  • 一句话解决高并发的核心原则
    本文介绍了解决高并发的核心原则,即将用户访问请求尽量往前推,避免访问CDN、静态服务器、动态服务器、数据库和存储,从而实现高性能、高并发、高可扩展的网站架构。同时提到了Google的成功案例,以及适用于千万级别PV站和亿级PV网站的架构层次。 ... [详细]
  • 本文介绍了Redis中RDB文件和AOF文件的保存和还原机制。RDB文件用于保存和还原Redis服务器所有数据库中的键值对数据,SAVE命令和BGSAVE命令分别用于阻塞服务器和由子进程执行保存操作。同时执行SAVE命令和BGSAVE命令,以及同时执行两个BGSAVE命令都会产生竞争条件。服务器会保存所有用save选项设置的保存条件,当满足任意一个保存条件时,服务器会自动执行BGSAVE命令。此外,还介绍了RDB文件和AOF文件在操作方面的冲突以及同时执行大量磁盘写入操作的不良影响。 ... [详细]
  • 本文介绍了操作系统的定义和功能,包括操作系统的本质、用户界面以及系统调用的分类。同时还介绍了进程和线程的区别,包括进程和线程的定义和作用。 ... [详细]
  • 一次上线事故,30岁+的程序员踩坑经验之谈
    本文主要介绍了一位30岁+的程序员在一次上线事故中踩坑的经验之谈。文章提到了在双十一活动期间,作为一个在线医疗项目,他们进行了优惠折扣活动的升级改造。然而,在上线前的最后一天,由于大量数据请求,导致部分接口出现问题。作者通过部署两台opentsdb来解决问题,但读数据的opentsdb仍然经常假死。作者只能查询最近24小时的数据。这次事故给他带来了很多教训和经验。 ... [详细]
  • MySQL数据库锁机制及其应用(数据库锁的概念)
    本文介绍了MySQL数据库锁机制及其应用。数据库锁是计算机协调多个进程或线程并发访问某一资源的机制,在数据库中,数据是一种供许多用户共享的资源,如何保证数据并发访问的一致性和有效性是数据库必须解决的问题。MySQL的锁机制相对简单,不同的存储引擎支持不同的锁机制,主要包括表级锁、行级锁和页面锁。本文详细介绍了MySQL表级锁的锁模式和特点,以及行级锁和页面锁的特点和应用场景。同时还讨论了锁冲突对数据库并发访问性能的影响。 ... [详细]
  • Redis API
    安装启动最简启动命令行输入验证动态参数启动配置文件启动常用配置通用命令keysbdsize计算key的总数exists判断是否存在delkeyvalue删除指定的keyvalue成 ... [详细]
  • 云原生应用最佳开发实践之十二原则(12factor)
    目录简介一、基准代码二、依赖三、配置四、后端配置五、构建、发布、运行六、进程七、端口绑定八、并发九、易处理十、开发与线上环境等价十一、日志十二、进程管理当 ... [详细]
  • Windows下配置PHP5.6的方法及注意事项
    本文介绍了在Windows系统下配置PHP5.6的步骤及注意事项,包括下载PHP5.6、解压并配置IIS、添加模块映射、测试等。同时提供了一些常见问题的解决方法,如下载缺失的msvcr110.dll文件等。通过本文的指导,读者可以轻松地在Windows系统下配置PHP5.6,并解决一些常见的配置问题。 ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • Redis底层数据结构之压缩列表的介绍及实现原理
    本文介绍了Redis底层数据结构之压缩列表的概念、实现原理以及使用场景。压缩列表是Redis为了节约内存而开发的一种顺序数据结构,由特殊编码的连续内存块组成。文章详细解释了压缩列表的构成和各个属性的含义,以及如何通过指针来计算表尾节点的地址。压缩列表适用于列表键和哈希键中只包含少量小整数值和短字符串的情况。通过使用压缩列表,可以有效减少内存占用,提升Redis的性能。 ... [详细]
  • 在工作了一年多后,我对现在的工作感到厌倦,没有激情,于是决定转行做程序猿。我在学校开了一个某宝店,通过自己摸索和努力,每个月挣够了零花钱和伙食费。我决定往互联网方向靠,不喜欢面对面和人沟通,而虚拟世界中的开发工作让我感到兴奋。我开始学习Java,感到困惑和怀疑自己的智商,但一篇鸡汤文激发了我学习Python的兴趣,我感到智商找回来了。我相信没有梦想的人和咸鱼没有什么区别。 ... [详细]
author-avatar
金子祺_475
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有