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 相关文章推荐
PHPlet在Windows下的安装
Oct 09 PHP
WindowsXP中快速配置Apache+PHP5+Mysql
Jun 05 PHP
PHP 事务处理数据实现代码
May 13 PHP
php发送html格式文本邮件的方法
Jun 10 PHP
PHP附件下载中文名称乱码的解决方法
Dec 17 PHP
php单链表实现代码分享
Jul 04 PHP
PHP编程实现阳历转换为阴历的方法实例
Aug 08 PHP
PHP实现广度优先搜索算法(BFS,Broad First Search)详解
Sep 16 PHP
三个思路解决laravel上传文件报错:413 Request Entity Too Large问题
Nov 13 PHP
作为PHP程序员你要知道的另外一种日志
Jul 30 PHP
PHP上传图片到数据库并显示的实例代码
Dec 20 PHP
php封装的page分页类完整实例代码
Feb 01 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
PHP4之COOKIE支持详解
2006/10/09 PHP
PHP 在线翻译函数代码
2009/05/07 PHP
php 过滤危险html代码
2009/06/29 PHP
linux下编译安装memcached服务
2014/08/03 PHP
php rsa加密解密使用详解
2015/01/14 PHP
PHP 前加at符合@的作用解析
2015/07/31 PHP
php如何控制用户对图片的访问 PHP禁止图片盗链
2016/03/25 PHP
YII框架http缓存操作示例
2019/04/29 PHP
PHP实现简单登录界面
2019/10/23 PHP
yepnope.js 异步加载资源文件
2011/09/08 Javascript
javascript获取鼠标位置部分的实例代码(兼容IE,FF)
2013/08/05 Javascript
利用javaScript实现点击输入框弹出窗体选择信息
2013/12/11 Javascript
通过JS来动态的修改url,实现对url的增删查改
2014/09/01 Javascript
node.js中的fs.fchmodSync方法使用说明
2014/12/16 Javascript
JavaScript中字符串(string)转json的2种方法
2015/06/25 Javascript
javascript 广告移动特效的实现代码
2016/06/25 Javascript
js 轮播效果实例分享
2016/12/28 Javascript
微信小程序 引入es6 promise
2017/04/12 Javascript
微信小程序 检查接口状态实例详解
2017/06/23 Javascript
javascript基于牛顿迭代法实现求浮点数的平方根【递归原理】
2017/09/28 Javascript
nodejs微信扫码支付功能实现
2018/02/17 NodeJs
原生JS实现顶部导航栏显示按钮+搜索框功能
2019/12/25 Javascript
详尽讲述用Python的Django框架测试驱动开发的教程
2015/04/22 Python
Python实现PS图像调整颜色梯度效果示例
2018/01/25 Python
详解Python中的type和object
2018/08/15 Python
pytorch下使用LSTM神经网络写诗实例
2020/01/14 Python
Tensorflow:转置函数 transpose的使用详解
2020/02/11 Python
Python使用struct处理二进制(pack和unpack用法)
2020/11/12 Python
小天鹅官方商城:LittleSwan
2017/06/16 全球购物
红色康乃馨酒店:Red Carnation Hotels
2017/06/22 全球购物
阿迪达斯英国官方网站:adidas英国
2019/08/13 全球购物
五年级学生期末评语
2014/12/26 职场文书
六一领导慰问欢迎词
2015/01/26 职场文书
预备党员考察意见范文
2015/06/01 职场文书
关于幸福的感言
2015/08/03 职场文书
Django 如何实现文件上传下载
2021/04/08 Python