如果观看抽奖或秒杀系统的请求监控曲线,你就会发现这类系统在活动开放的时间段内会出现一个波峰,而在活动未开放时,系统的请求量、机器负载一般都是比较平稳的。为了节省机器资源,我们不可能时时都提供最大化的资源能力来支持短时间的高峰请求。所以需要使用一些技术手段,来削弱瞬时的请求高峰,让系统吞吐量在高峰请求下保持可控。

​​

最近在做一个小型的抽奖系统,用户中奖之后需要调用转账接口进行虚拟金的转账。转账接口有频控的逻辑,因此不能把抽奖瞬间的大量请求都发往转账系统,必须对请求进行削峰。削峰的方式有很多种,下面就来简单地聊一下。

请求排队

削峰最常用的一种方式是请求排队。瞬时的请求量太大,那么就把这些请求先排队存起来,再依据系统所能提供的消费能力按需消费。在量小的时候,抽奖与发货这两个动作可以是同步的(如下左图),这是一种紧耦合系统,SVR B的处理能力必须跟得上SVR A的处理能力。当SVR A 与SVR B 存在处理能力差异时,可以引入消息队列,把对服务的同步调用转化成对队列的异步消费。

​​

可以用来作为队列的工具有很多,典型的如Message Queue消息队列,也可以利用数据库Mysql或是Redis来实现分布式队列,跟进业务场景来自行进行选择。例如,我在实现抽奖系统的时候,使用的是Mysql,原因是SVR A已经把用户的抽奖信息落地到的数据库,那么SVR B就可以利用Mysql作为一个队列,来达到按能力消费的需求。

Mysql

用户中奖的时候,SVR A 会将用户中奖信息写到数据库中。SVR B按照自己的消费能力,从数据库中把数据select出来执行转账的逻辑。数据库表中的每一行记录,都可以看作是一个等待被消费的消息。如何保证消息按序(正序或倒序)消费?可以利用update_time 来标记消息入队时间,设定update_time字段:

update_time timestamp NOT NULL ON UPDATE CURRENT_TIMESTAMP  DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间'

必须使用一个字段来标记某行记录的消费状态。消费过的消息不必再select出来处理。另外,在有多个消息消费者的时候(比如有多个线程来消费数据库中的这些中奖信息时),需要保证消息不会重复被消费。可以使用二段式提交的方式来保证。以字段present_flag来表示消费状态,present_flag有三个取值:
0:中奖,未转账
1:一阶段提交(即准备转账)
2:二阶段提交(转账完成)

对于SVR B ,需要进行如下的操作:
步骤一:将数据库中present_flag 为0 的记录按序捞取出来,这里可以批量拉取,比如一次拉取100条记录
步骤二:按序处理每笔中奖记录的转账逻辑,调用转账接口之前,将present_flag设置为1,sql中的条件是present_flag为0;
步骤三:执行转账逻辑
步骤四:转账成功,将present_flag设置为2,sql中条件是present_flag为1。

这样即使同一行记录被多个消费者拉取出来,也能保证只有一个能够成功执行步骤三。转账失败(消费失败)
的记录如何处理?可以使用一个定时脚本将present_flag为1的update成present_flag为0,再次进行消费。

通过这种异步消费的方式,来保证中奖记录慢慢被消费完。这种方式在极端的情况下,比如刚刚执行完步骤三
机器就挂掉了,那么可能会出现重复消费的情况。根据业务对重复消费的容忍度来进行选择。

Redis

Redis的list数据结构提供了BLPOP和BRPOP,表示列表的阻塞式弹出。BLPOP的BRPOP的区别仅仅在取元素的位置不同。使用方式为:

BRPOP key timeout

当给定的列表内没有任何元素可供弹出的时候,连接将被阻塞,直到等待超时或发现可弹出的元素为止,超时参数 timeout 接受一个以秒为单位的数字作为值。超时参数设为 0 表示阻塞时间可以无限期延长。相同的key可以被多个客户端同时阻塞,不同的客户端会被放进一个队列中,按照【先阻塞先服务】的顺序为key执行BRPOP 命令。利用这个特点,可以来实现一个轻量级的消息队列服务。

消息队列组件

例如kafka、ActiveMQ、RabbitMQ、ZeroMQ、Kafka、MetaMQ、RocketMQ等消息队列,本就是为异步化消息消费、应用解耦、流量消费而设计。业务根据需求加以选型即可。

转载于:https://www.cnblogs.com/QG-whz/p/9943282.html

抽奖系统的流量削峰方案相关推荐

  1. 怎样来实现流量削峰方案

    流量削峰的由来 主要是还是来自于互联网的业务场景,例如,马上即将开始的春节火车票抢购,大量的用户需要同一时间去抢购:以及大家熟知的阿里双11秒杀, 短时间上亿的用户涌入,瞬间流量巨大(高并发),比如: ...

  2. 消息中间件系列(六):什么是流量削峰?如何解决秒杀业务的削峰场景

    流量削峰的由来 主要是还是来自于互联网的业务场景,例如,马上即将开始的春节火车票抢购,大量的用户需要同一时间去抢购:以及大家熟知的阿里双11秒杀, 短时间上亿的用户涌入,瞬间流量巨大(高并发),比如: ...

  3. 高并发架构系列:什么是流量削峰?如何解决秒杀业务的削峰场景

    流量削峰的由来 主要是还是来自于互联网的业务场景,例如,马上即将开始的春节火车票抢购,大量的用户需要同一时间去抢购:以及大家熟知的阿里双11秒杀, 短时间上亿的用户涌入,瞬间流量巨大(高并发),比如: ...

  4. 秒杀系统流量削峰,这事应该怎么做?

    如果你看过秒杀系统的流量监控图的话,你会发现它是一条直线,就在秒杀开始那一秒是一条很 直很直的线,这是因为秒杀请求在时间上高度集中于某一特定的时间点.这样一来,就会导致一 个特别高的流量峰值,它对资源 ...

  5. 秒杀系统流量削峰这事应该怎么做?为什么要削峰呢?

    点击上方"朱小厮的博客",选择"设为星标" 回复"1024"获取独家整理的学习资料 如果你看过秒杀系统的流量监控图的话,你会发现它是一条直线 ...

  6. java 最少使用(lru)置换算法_一篇文章学会如何基于LRU-K算法设计本地缓存实现流量削峰...

    专注于Java领域优质技术号,欢迎关注 作者:一个Java菜鸟 1.背景介绍 1.1.现象 QPS突然增长2倍以上(45w~60w每分钟) 将产生下面一些问题: 1)响应接口响应时长增加了5倍(qps ...

  7. 【商城秒杀项目】-- 流量削峰应该怎么做

    如果你看过秒杀系统的流量监控图的话,你会发现它是一条直线,在秒杀开始那一秒是一条很直很直的线,这是因为秒杀请求在时间上高度集中于某一特定的时间点.这样一来,就会导致一个特别高的流量峰值,它对资源的消耗 ...

  8. Java峰值和削峰_架构设计之流量削峰

    前言 针对于秒杀场景来说,流量往往在一个特定时间点有个高度集中的流量洪峰,这个瞬时对于资源的消耗是很大的,这时往往对于服务的稳定性带来了极大的挑战,如果按照流量洪峰预估系统资源,则可能存在极大的资源浪 ...

  9. 秒杀系统常用的削峰方法

    概述 在面试被问到系统设计这块时候,秒杀系统经常是一个热门考点.今天我们就讨论一下其中的重要一点:如何进行秒杀系统的流量销锋? 如果你看过秒杀系统的流量监控图的话,你会发现它是一条直线,就在秒杀开始那 ...

最新文章

  1. 自动驾驶真的会来得那么快吗:关于自动驾驶的7个疑问
  2. MapReduce编程系列 — 2:计算平均分
  3. css背景渐变的技巧与方法
  4. (转) oc static extern 和const
  5. mysql inception web_基于Inception搭建MySQL SQL审核平台Yearing
  6. Patrick Wyatt:代码没问题 程序却有bug?
  7. MyBatis映射文件3(参数处理Map)
  8. 测试工具|(本来不想分享的)安卓系统Ping IP工具
  9. FANUC机器人模拟仿真软件ROBOGUIDE的基本操作介绍(图文)
  10. linux操作系统中ssh的默认端口号,sshd服务的默认端口号
  11. 电脑重装系统不小心格式化了恢复文件教程
  12. c语言输出0.000000或乱码,深究
  13. Windows 7/Vista 桌面快捷方式小箭头变成黑块,如何恢复?
  14. 葫芦娃系列棋牌服务器在哪里,葫芦娃—【关服】葫芦娃关服公告
  15. 【七】【vlc-android】vlc的decoder控制层传输数据与ffmpeg音频解码模块decoder层进行解码的数据交互流程源码分析
  16. odoo中的消息通知
  17. 用Cat.1+GPS+蓝牙+RFID实现工卡式室内室外定位器
  18. 多线程的实现与多线程的同步机制-让你轻松掌握多线程编程
  19. RocksDB基本架构与原理介绍
  20. 操作系统-AOSOA

热门文章

  1. mysql innodb 死锁_mysql innodb 死锁分析
  2. Python3——类
  3. TRACE (VC)
  4. springboot 上传文件_基于SpringBoot的文件上传
  5. 机器学习导论 与数学分析
  6. js 弹出层的点击事件影响到底层的点击事件_聊一聊 Node.js 错误处理
  7. python一键清屏_python添加清屏功能
  8. LeetCode 网易-1. 分割环(前缀和 + 哈希)
  9. LeetCode 732. 我的日程安排表 III(差分思想)
  10. LeetCode 1167. 连接棒材的最低费用(优先队列+贪心)