php使用lua+redis实现限流,计数器模式,令牌桶模式


Posted in PHP onApril 04, 2019

lua 优点

减少网络开销: 不使用 Lua 的代码需要向 Redis 发送多次请求, 而脚本只需一次即可, 减少网络传输;

原子操作: Redis 将整个脚本作为一个原子执行, 无需担心并发, 也就无需事务;

复用: 脚本会永久保存 Redis 中, 其他客户端可继续使用.

计数器模式:

利用lua脚本一次性完成处理达到原子性,通过INCR自增计数,判断是否达到限定值,达到限定值则返回限流,添加key过期时间应该范围过度

$lua = '
        local i = redis.call("INCR", KEYS[1]) 
        if i > 10 then
          return "wait"
        else
          if i == 1
          then
            redis.call("expire", KEYS[1], KEYS[2])
          end
          return redis.call("get", KEYS[3])
        end
      ';

laravel 请求代码:

Redis::eval($lua, 3, sprintf(RedisKey::API_LIMIT, $key, $callService['service']), 60, $cache_key);

令牌桶模式

每次请求在桶内拿取一个令牌,有令牌则通过,否则返回,并且按照算法一定的慢慢把令牌放入桶内

$lua = '
        local data = redis.call("get", KEYS[2])
        if data then
        
          local dataJson = cjson.decode(data)
          local newNum = math.min(KEYS[3], math.floor(((dataJson["limitVal"] - 1) + (KEYS[3]/KEYS[5]) * (KEYS[4] - dataJson["limitTime"]))))
          
          if newNum > 0 then
          
            local paramsJson = cjson.encode({limitVal=newNum,limitTime=KEYS[4]})
            redis.call("set", KEYS[2], paramsJson)
            return redis.call("get", KEYS[1])
          
          end
           return "wait"
        end
        
        local paramsJson = cjson.encode({limitVal=KEYS[3],limitTime=KEYS[4]})
        redis.call("set", KEYS[2], paramsJson)
        return redis.call("get", KEYS[1])
      ';
      
      // 1. lua脚本, 2 KEYS数量, 3 查找数据key, 4 限制key, 5 桶内数量, 6 时间戳, 7 过期时间
      Redis::eval(1,2,3,4,5,6,7参数);

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

PHP 相关文章推荐
php 来访国内外IP判断代码并实现页面跳转
Dec 18 PHP
破解图片防盗链的代码(asp/php)测试通过
Jul 02 PHP
PHP fgetcsv 定义和用法(附windows与linux下兼容问题)
May 29 PHP
通过PHP的内置函数,通过DES算法对数据加密和解密
Jun 21 PHP
利用PHP扩展vld查看PHP opcode操作步骤
Mar 04 PHP
laravel安装和配置教程
Oct 29 PHP
php实现用于验证所有类型的信用卡类
Mar 24 PHP
PHP判断用户是否已经登录(跳转到不同页面或者执行不同动作)
Sep 22 PHP
php自定义排序uasort函数示例【二维数组按指定键值排序】
Jun 19 PHP
PHP实现微信提现功能(微信商城)
Nov 21 PHP
PHP数组array类常见操作示例
May 15 PHP
php使用自带dom扩展进行元素匹配的原理解析
May 29 PHP
PHP设计模式之策略模式原理与用法实例分析
Apr 04 #PHP
Laravel路由研究之domain解决多域名问题的方法示例
Apr 04 #PHP
PHP设计模式之观察者模式定义与用法分析
Apr 04 #PHP
PHP示例演示发送邮件给某个邮箱
Apr 03 #PHP
PHP whois查询类定义与用法示例
Apr 03 #PHP
ThinkPHP3.2.3框架实现的空模块、空控制器、空操作,跳转到错误404页面图文详解
Apr 03 #PHP
PHP反射实际应用示例
Apr 03 #PHP
You might like
PHP利用APC模块实现文件上传进度条的方法
2015/01/26 PHP
PHP5.3以上版本安装ZendOptimizer扩展
2015/03/27 PHP
Yii视图CGridView列表用法实例分析
2016/07/12 PHP
将HTML自动转为JS代码
2006/06/26 Javascript
DLL+ ActiveX控件+WEB页面调用例子
2010/08/07 Javascript
js实现不提交表单获取单选按钮值的方法
2015/08/21 Javascript
jquery实现图片放大镜功能
2015/11/23 Javascript
基于JS实现省市联动效果代码分享
2016/06/06 Javascript
jQuery的ajax中使用FormData实现页面无刷新上传功能
2017/01/16 Javascript
简单实现jQuery弹幕效果
2017/05/06 jQuery
关于使用axios的一些心得技巧分享
2017/07/02 Javascript
JS实现图片手风琴效果
2020/04/17 Javascript
Javascript 严格模式use strict详解
2017/09/16 Javascript
详解js的视频和音频采集
2018/08/09 Javascript
对angular2中的ngfor和ngif指令嵌套实例讲解
2018/09/12 Javascript
微信小程序实现同一页面取值的方法分析
2019/04/30 Javascript
JS浮点数运算结果不精确的Bug解决
2019/08/01 Javascript
Javascript执行上下文顺序的深入讲解
2020/11/04 Javascript
[40:55]Liquid vs LGD 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
跟老齐学Python之深入变量和引用对象
2014/09/24 Python
Python实现优先级队列结构的方法详解
2016/06/02 Python
速记Python布尔值
2017/11/09 Python
Linux下python3.7.0安装教程
2018/07/30 Python
python GUI库图形界面开发之PyQt5输入对话框QInputDialog详细使用方法与实例
2020/02/27 Python
django之从html页面表单获取输入的数据实例
2020/03/16 Python
python+selenium 简易地疫情信息自动打卡签到功能的实现代码
2020/08/22 Python
英国顶级珠宝品牌之家:John Greed
2018/06/09 全球购物
怀旧收藏品和经典纪念品:Betty’s Attic
2018/08/29 全球购物
精细化工应届生求职信
2013/11/17 职场文书
班级体育活动总结
2014/07/05 职场文书
法人委托书范本格式
2014/09/15 职场文书
晚会闭幕词
2015/01/28 职场文书
教师年终个人总结
2015/02/11 职场文书
2015年为民办实事工作总结
2015/05/26 职场文书
山楂树之恋观后感
2015/06/11 职场文书
复制别人的成功真的会成功吗?
2019/10/17 职场文书