使用redis做一个简单的限流

发布于:2024-10-24 编辑:匿名 来源:网络

背景 在最近的一个项目中,需要限制一个用户在两个小时内只能访问3次,所以我简单地使用了redis来实现一个限流方案。二。

设计与实现 1.方法定义代码语言:txt复制 //RateLimiter redis实现限流器 //userId限流用户id //funcName需要是限流方法 //窗口周期,单位秒 //限制窗口Size func RateLimiter(redisClient *redis.Client, userId string, funcName string, period int64,limit int64) (ok bool) 二、实现方案 1、SortedSet+pipeline 利用redis的SortedSet数据结构实现。实现逻辑如下: 代码语言:txt copy func RateLimiter(redisClient *redis.Client, userId string, funcName string, period int64, limit int64) bool {pipeline := redisClient.Pipeline()defer pipeline.Close()key := "rate_limit:" + userId + ":" + funcName // 步骤1.获取当前微秒数 currMs := time.Now().UnixNano() / 10e3// step2.将微妙数字放入redis pipeline.ZAdd(key, redis.Z{Score: float64(currMs), Member: currMs})// step3.删除窗口外的memberpipeline.ZRemRangeByScore(key, "0", strconv.FormatInt(currMs-10e6*period, 10))//step4。

设置窗口过期时间 pipeline.Expire(key, time.Duration(period)*time.Second)// step5.计算窗口pipeline中的成员数量。ZCard(key)//提交命令cmder, err := pipeline.Exec()if err != nil {fmt.Errorf(err.Error())return false}//获取当前窗口成员个数 currentCount, err := cmder[3].(*redis.IntCmd).Result()if err != nil {fmt.Errorf(err.Error())return false}return currentCount <= limit}这种方法有一个问题,就是无论用户请求数是否达到限制,都会执行插入操作。

极端场景会导致redis内存过大。主要是因为管道不能依赖前面的命令来返回结果。

所以我决定用lua来做一轮改造。2.使用SortedSet+lua脚本完善实现逻辑,与之前基本相同。

它只是在插入之前判断窗口是否已满。如果满了,直接返回false。

实现逻辑如下: 代码语言:txt copy // 生成lua脚本 func createScript() *redis.Script {script := redis.NewScript(`local key = KEYS[1]local cur_ms = ARGV[1]local period = tonumber(ARGV[2]) 或 0local limit = tonumber(ARGV[ 3]) 或 0local t1 = redis.call('ZREMRANGEBYSCORE', key, 0, cur_ms-(10e6*period))local t2 = redis.call( 'EXPIRE',key, period)local cur_count = redis.call('ZCARD',key)if tonumber(cur_count) < limit thenlocal t3 = redis.call('ZADD',key,cur_ms,cur_ms)return trueendreturn false`) return script}// RateLimiter redis 实现限流器 // userId 限制 Streaming 用户 id // funcName 限流方法 // 窗口周期,单位为秒 // 限制窗口大小 func RateLimiter2(client *redis.Client, userId string , funcName string, period int64, limit int64) bool {script: = createScript()sha, err := script.Load(client).Result()if err != nil {fmt.Print(err.Error())} key := "rate_limit:" + userId + ":" + funcName// step1 获取当前时刻的微妙数字 currMs := time.Now().UnixNano() / 10e3ret := client.EvalSha(sha, []string{key,}, currMs, period, limit)//步骤2。获取执行结果后的结果, err := ret.Result()if err != nil {fmt.Printf("执行Redis失败: %v", err.Error())return false} else {fmt.Printf(" userid: %s, funcName:%s, result: %d", userId, funcName, result)}if result == int64(1) {return true}return false}三.测试使用goconvey对已经编写好的模块进行单元测试,测试组件功能是否正常。

代码语言:txt复制包examplesimport("github.com/go-redis/redis""time"//引入go sell库。

使用redis做一个简单的限流

站长声明

版权声明:本文内容由互联网用户自发贡献,本站不拥有所有权,不承担相关法律责任。如果发现本站有涉嫌抄袭的内容,欢迎发送邮件 举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。

标签:

相关文章

  • 如果我敢买几百万辆量产的飞行汽车,你敢让我飞吗?

    如果我敢买几百万辆量产的飞行汽车,你敢让我飞吗?

    自从年约翰、埃默里、哈里曼成为第一个申请“飞行汽车”专利的人以来,专家每隔一段时间就会跳出来说“飞行汽车的时代即将到来”。 多年来,“飞行汽车”一度成为“愚弄”的代名词。 近年来,从硅谷开始,包括科技公司、飞机公司、汽车公司在内的数百家公司都在尝试量产“飞行

    06-21

  • 联电:八寸产能需求旺盛

    联电:八寸产能需求旺盛

    联华电子表示,由于中国大陆无线通讯及电脑周边市场带来的商机,公司苏州8寸工厂——河间科技,秩序良好。 据悉,河间目前的月产能已从今年的6.4万件增至年底的7.7万件。 从目前8英寸晶圆代工市场的产能来看,5G相关的电源管理IC和金属氧化物半场效应晶体管(MOSFET)等功率半

    06-06

  • 中华医学联合会完成A轮融资,由北京同仁堂传承创新基金公司

    中华医学联合会完成A轮融资,由北京同仁堂传承创新基金公司

    投资界(ID:pedaily)领投 据2月6日消息,北京中华医学联合会健康科技有限公司(以下简称“中华医学联合会”)如:中华医学会医学联合会或公司)近期完成A轮融资。 本轮融资由北京同仁堂传承创新基金公司领投。 募集资金将用于推动公司中医药临床处方转化体系的完善和优化,

    06-17

  • 优格资本携手小米科技等互联网10巨头成立优格创业投资基金

    优格资本携手小米科技等互联网10巨头成立优格创业投资基金

    随着移动互联网的发展,资本市场也在发生着巨大的变化。 传统投资理念正在被颠覆,产业资源的重要性日益凸显。 在这个“大众创业、万众创新”的时代,对于那些有潜力或者已经崭露头角的创新创业者来说,融资或许并不困难。 难的是如何获得好的产业资源?如何对接大渠道、大平

    06-18

  • 成都市人才贷、成果贷、研发贷发放仪式正式启动

    成都市人才贷、成果贷、研发贷发放仪式正式启动

    成为头条新闻 2月26日,由成都市人才工作领导小组办公室、成都市科委主办的“成都市人才贷、成果贷、研发贷”活动隆重举行和科技局。 “贷款发放仪式”在成都正式启动,承办方担任成都生产力促进中心。 据介绍,“科技创新贷”是成都科技园向全市科技型中小微企业,特别是入驻

    06-18

  • 首次发布 -创腾科技完成千万级A轮融资,服务超过1200家客户

    首次发布 -创腾科技完成千万级A轮融资,服务超过1200家客户

    投资社区(ID:pedaily)9月13日消息,近日,中国流程制造行业研发智能引擎创腾科技宣布完成数千万人民币A轮融资,本轮融资由诚资本领投,皓月资本担任本轮融资独家投资方。 本轮融资将帮助创腾科技加快产品研发和团队建设,进一步拓展市场,深化行业数字化渗透。 创腾科技主

    06-17

  • 全球玩具品牌“StarPony”完成超千万美元融资,eWTP领投

    全球玩具品牌“StarPony”完成超千万美元融资,eWTP领投

    投资社区(ID:pedaily)据5月20日消息,全球玩具品牌StarPony近期完成超千万美元轮融资融资。 投资后估值超过1亿美元。 本轮融资由eWTP领投,老股东险峰K2VC跟投。 据了解,本轮募集资金将主要用于人才招募、产品研发、品牌建设等方面。 StarPony成立于2019年8月,专注于儿童

    06-18

  • 长江存储国家存储基地二期工程开工

    长江存储国家存储基地二期工程开工

    6月20日,长江存储实施的国家存储基地二期工程(土建)在武汉东湖高新区开工。 湖北省委书记、省人大常委会主任应勇宣布项目(土建)开工。 湖北省委副书记、省长王晓东致辞。 清华紫光集团董事长、长江存储董事长赵卫国介绍了该项目的相关情况。 长江存储国家存储器基地项目

    06-06

  • 共建全球薪资支付体系,新泰软件获开泰银行开泰银行A+轮战略投资

    共建全球薪资支付体系,新泰软件获开泰银行开泰银行A+轮战略投资

    投资界(微信ID:pedaily)消息,新泰软件正式宣布获得开泰银行开泰银行A+轮战略投资。 围绕原有工业互联网生态和服务场景,我们与开泰银行携手布局“一带一路”,构建全球薪酬支付体系。 同时,我们设立了第一期规模超过10亿元的稳岗稳工资防疫基金。 据悉,鑫泰软此前曾获得

    06-18

  • 《广州科技创新母基金管理办法(征求意见稿)》

    《广州科技创新母基金管理办法(征求意见稿)》

    广州市科学技术局关于向社会公开征求广州市科技创新基金基金管理办法意见的通知:为充分发挥广州市科技创新基金的作用资金,引导社会资本推动科技成果产业化,促进科技、金融、产业融合发展,按照《政府投资基金暂行管理办法》(财育〔〕号)等相关文件精神, 《广州市科技创

    06-18

  • PHP开发者大会看房地产O2O:技术将成为变革的重要驱动力

    PHP开发者大会看房地产O2O:技术将成为变革的重要驱动力

    PHP全球开发者大会于5月14日在北京召开。 作为使用最广泛的开源多用途脚本语言,它吸收了与结合C语言、Java和Perl的特点,全球70%以上的互联网网站都采用PHP作为主要开发语言。 据统计,中国拥有全球最多的PHP开发者,包括BAT巨头在内的80%以上的中国互联网公司都使用PHP进行

    06-17

  • 北美亚洲生鲜电商Weee!已完成C轮融资,由DST Global领投

    北美亚洲生鲜电商Weee!已完成C轮融资,由DST Global领投

    据投资界8月18日消息,其是美国规模最大、发展最快的亚洲生鲜电商公司,总部位于旧金山湾区弗里蒙特地区,加利福尼亚州。 电商呀!宣布完成C轮融资。 本轮融资由知名投资机构DST Global领投。 本轮融资也使得Weee!的融资总额超过1亿美元。 据悉,DST Global的本轮融资将进一

    06-18