zoukankan      html  css  js  c++  java
  • 设计秒杀系统的一些思路

    设计一个秒杀系统可以很难也可以很容易。下面介绍两种思路

    一、随机抽取(简单粗暴)

    • 第一步:用户点击秒杀后,直接在前端随机丢弃一些请求,返回给抢单失败,另外请求一些进入后端系统。
    • 第二步:提前部署redis集群,存储参与用户的ID,这样redis只有存的压力。
    • 第三步:然后同步记录去重, 再随机抽100个参与用户。(从秒杀开始后一定时间段内提交请求的用户中抽取)

    其实也是公平的 而且应该比“凭手速”更公平 因为如果完全按到达服务器的时间算 有太多用户不可控但短期内不改变的因素会影响成功率 比如网速 设备性能

    二、经典设计

    总体思路:尽量将请求拦截在系统上游;读多写少的场景多使用缓存。 

     

    秒杀系统的普遍问题:

    1. 高并发
    2. 超卖
    3. 恶意请求
    4. 链接暴露
    5. 数据库

    一般解决思路:

    前端层:

        前段限流:按钮置灰,活动开始前,前端定时检测当前时间,到点了就取消置灰;js限制用户几秒之内只能点击一次

    网络层:

       cdn预热:一些秒杀相关的静态文件可以先推到cdn

       nginx:负载均很,临时加很多台秒杀服务器;拦截恶意请求(请求次数太夸张,对单个ip每秒访问次数加限制、加黑名单)

       网络宽带:临时提高宽带(云服务器)

    后端层:

        设计系统,总体把握一个单一原则,秒杀系统不影响其他系统的正常运行。

    缓存层:   

          redis部署:集群、主从同步、读写分离、哨兵,开启持久化(单一职责)

          redis预热:先把库存商品加载到redis,结束后再异步修改数据库

    业务层:

          高并发:服务设计单一职责,单独设计一个秒杀服务,有助于扩容。(单一职责)

          链接暴露:秒杀链接加盐,MD5之类的加密算法加密随机的字符串去做url,然后通过前端代码获取url后台校验才能通过。

          服务降级:用户抢到即为成功,订单具体处理异步去操作。

          削峰填谷:MQ(设置定长队列能强制避免超卖)。

    持久层:

          数据库:为了防止秒杀打挂数据库影响其他业务,单独设计一个秒杀表。(单一职责)

     一些补充:

    在争抢库存是,会利用到redis-Lua:

    Lua 脚本功能是 Reids在 2.6 版本的最大亮点, 通过内嵌对 Lua 环境的支持, Redis 解决了长久以来不能高效地处理 CAS (check-and-set)命令的缺点, 并且可以通过组合使用多个命令, 轻松实现以前很难实现或者不能高效实现的模式。

    使用Lua脚本的好处:

    • 减少网络开销。可以将多个请求通过脚本的形式一次发送,减少网络时延。
    • 原子操作。redis会将整个脚本作为一个整体执行,中间不会被其他命令插入。因此在编写脚本的过程中无需担心会出现竞态条件,无需使用事务。这个很关键
    • 复用。客户端发送的脚本会永久存在redis中,这样,其他客户端可以复用这一脚本而不需要使用代码完成相同的逻辑。

     写一个脚本把判断库存扣减库存的操作都写在一个脚本丢给Redis去做,那到0了后面的都Return False了是吧,一个失败了你修改一个开关,直接挡住所有的请求,然后再做后面的事情。

  • 相关阅读:
    Python 音视频方面资源大全
    MD5( 信息摘要算法)的概念原理及python代码的实现
    base64编解码学习及python代码实现
    操作系统下cache的几个概念
    scp 跨机远程拷贝
    VIM -小技巧汇总
    python中的进制转换
    linux目录跳转快捷方式——z武器
    ubuntu 16.04 清空log文件的方法
    【linux】crontab失效
  • 原文地址:https://www.cnblogs.com/kbian/p/12284963.html
Copyright © 2011-2022 走看看