基于redis+lua实现高并发场景下的秒杀限流解决方案

转自:https://blog.csdn.net/zzaric/article/details/80641786

应用场景如下:

公司内有多个业务系统,由于业务系统内有向用户发送消息的服务,所以通过统一消息系统对外暴露微服务接口供外部业务系统调用,所有公司内业务系统的消息(短信,APP,微信)推送都由统一消息系统去推送,短信推送需要走外部短信通道商去发送短信,APP和微信走内部系统的push服务器,但是不管是短信通道商还是内部push服务器都会有每秒上限的控制。在这假设n/s条。

以下是统一消息系统内部的具体的限流方案:

时间限流队列如下:

1.统一消息中心接受消息m条,假定这m个待推送消息的推送时间为t1。

2.因为时间限流队列的长度是n条,现在有m条要进时间限流队列,所以队列里必须要有n-m个长度才能保证新进来的m条待发送消息才能进入队列。

3.所以判定队列里第n-m对应的时间点要比这m条待发送消息的发送时间小于1个单位秒时,即 t1-t2>1s,才能保证n/s条的速率。

4.通过第3部t1-t2>1s?判断是否满足新来的m条待发送消息的发送时间是否比时间限流队列第n-m条对应的时间大于1个单位秒时,如果大于1个单位秒时,说明t1时间对应的上一秒对应的n条消息都已经发送,这时通过lpush命令循环将m条待发送消息推入时间限流队列。如有没有主线程睡眠1/10个秒时,轮询执行步骤一,直至m套待发送消息对应的发送时间t1进入至时间限流队列。

5.执行时间滑动窗口步骤,截取redis队列0 - n的长度数据,如图所示。

原文地址:https://www.cnblogs.com/taozi32/p/10419851.html

时间: 2024-10-31 07:30:51

基于redis+lua实现高并发场景下的秒杀限流解决方案的相关文章

高并发场景下缓存+数据库双写不一致问题分析与解决方案设计

Redis是企业级系统高并发.高可用架构中非常重要的一个环节.Redis主要解决了关系型数据库并发量低的问题,有助于缓解关系型数据库在高并发场景下的压力,提高系统的吞吐量(具体Redis是如何提高系统的性能.吞吐量,后面会专门讲). 而我们在Redis的实际使用过程中,难免会遇到缓存与数据库双写时数据不一致的问题,这也是我们必须要考虑的问题.如果还有同学不了解这个问题,可以搬小板凳来听听啦. 一.数据库+缓存双写不一致问题引入 要讲数据库+缓存双写不一致的问题,就需要先讲一下这个问题是怎么发生的

高并发场景下锁

如何确保一个方法,或者一块代码在高并发情况下,同一时间只能被一个线程执行,单体应用可以使用并发处理相关的 API 进行控制,但单体应用架构演变为分布式微服务架构后,跨进程的实例部署,显然就没办法通过应用层锁的机制来控制并发了.那么锁都有哪些类型,为什么要使用锁,锁的使用场景有哪些?今天我们来聊一聊高并发场景下锁的使用技巧. 锁类别 不同的应用场景对锁的要求各不相同,我们先来看下锁都有哪些类别,这些锁之间有什么区别. 悲观锁(synchronize) Java 中的重量级锁 synchronize

缓存在高并发场景下的常见问题

缓存一致性问题 当数据时效性要求很高时,需要保证缓存中的数据与数据库中的保持一致,而且需要保证缓存节点和副本中的数据也保持一致,不能出现差异现象.这就比较依赖缓存的过期和更新策略.一般会在数据发生更改的时,主动更新缓存中的数据或者移除对应的缓存. 缓存并发问题 缓存过期后将尝试从后端数据库获取数据,这是一个看似合理的流程.但是,在高并发场景下,有可能多个请求并发的去从数据库获取数据,对后端数据库造成极大的冲击,甚至导致 “雪崩”现象.此外,当某个缓存key在被更新时,同时也可能被大量请求在获取,

【转】记录PHP、MySQL在高并发场景下产生的一次事故

看了一篇网友日志,感觉工作中值得借鉴,原文如下: 事故描述 在一次项目中,上线了一新功能之后,陆陆续续的有客服向我们反应,有用户的个别道具数量高达42亿,但是当时一直没有到证据表示这是,确实存在,并且直觉告诉我们,这是不可能的,就一直没有在意,直到后来真的发现了一个用户确实是42亿,当时我们整个公司都震惊了,如果有大量用户是这样的情况,公司要亏损几十万,我们的老大告诉我们,肯定是什么地方数据溢出的,最后我们一帮人,疯了似的查代码,发现…… 如果按照正常的程序逻辑走下去,代码是完全没问题,但是我发

高并发场景下秒杀项目静态锁的使用疑问

题:高并发场景下秒杀项目静态锁的使用疑问场景:我们有一个秒杀平台,可以提供所有接入公司创建的秒杀活动,简单描述如下:1.秒杀10袋洗衣粉,开始时间12:00(项目ID:A001)2.秒杀iPhone5,开始时间12:00(项目ID:A002)3.秒杀水杯,开始时间12:00(项目ID:A003)... ...(项目ID:A004-A009)10.秒杀ThinkPad,开始时间12:00(项目ID:A010) 例如上面,同时有十个秒杀,都是12:00整开始,每个秒杀之间没有任何关系. 按照我之前的

高并发场景下System.currentTimeMillis()的性能问题的优化

前言 System.currentTimeMillis()的调用比new一个普通对象要耗时的多(具体耗时高出多少我也不知道,不过听说在100倍左右),然而该方法又是一个常用方法,有时不得不使用,比如生成wokerId.打印日志什么的,在高并发情形下肯定存在性能问题的,但怎么做才好呢? System.currentTimeMillis()之所以慢是因为去跟系统打了一次交道.那什么快?内存!如果该方法从内存直接取数,那不就美滋滋了. 代码实现 package com.nyvi.support.uti

高并发场景下System.currentTimeMillis()的性能问题的优化 以及SnowFlakeIdWorker高性能ID生成器

package xxx; import java.sql.Timestamp; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicLong; /** * 高并发场景下System.currentTimeMillis()的性能问题的优化 * <p><p> * System.currentTimeMillis()的调用比new一个普通对象要耗时的多(具体耗时高出多少我还没测试过,有人说是100

高并发场景下的缓存有哪些常见的问题?

一.缓存一致性问题 当数据时效性要求很高时,需要保证缓存中的数据与数据库中的保持一致,而且需要保证缓存节点和副本中的数据也保持一致,不能出现差异现象. 这就比较依赖缓存的过期和更新策略.一般会在数据发生更改的时,主动更新缓存中的数据或者移除对应的缓存. 二.缓存并发问题 缓存过期后将尝试从后端数据库获取数据,这是一个看似合理的流程.但是,在高并发场景下,有可能多个请求并发的去从数据库获取数据,对后端数据库造成极大的冲击,甚至导致 "雪崩"现象. 此外,当某个缓存key在被更新时,同时也

高并发场景下请求合并的实践

前言 项目中一般会请求第三方的接口,也会对外提供接口,可能是RPC,也可能是HTTP等方式.在对外提供接口时,有必要提供相应的批量接口,好的批量实现能够提升性能. 高并发场景中,调用批量接口相比调用非批量接口有更大的性能优势.但有时候,请求更多的是单个接口,不能够直接调用批量接口,如果这个接口是高频接口,对其做请求合并就很有必要了.比如电影网站的获取电影详情接口,APP的一次请求是单个接口调用,用户量少的时候请求也不多,完全没问题:但同一时刻往往有大量用户访问电影详情,是个高并发的高频接口,如果