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递归算法的详细示例分析
Feb 19 PHP
探讨PHP使用eAccelerator的API开发详解
Jun 09 PHP
360通用php防护代码(使用操作详解)
Jun 18 PHP
php图像处理函数大全(推荐收藏)
Jul 11 PHP
一个经典的PHP文件上传类分享
Nov 18 PHP
php中debug_backtrace、debug_print_backtrace和匿名函数用法实例
Dec 01 PHP
PHP关键特性之命名空间实例详解
May 06 PHP
PHP基于ORM方式操作MySQL数据库实例
Jun 21 PHP
php注册系统和使用Xajax即时验证用户名是否被占用
Aug 31 PHP
YII框架行为behaviors用法示例
Apr 26 PHP
PHP 文件写入和读取操作实例详解【必看篇】
Nov 04 PHP
基于PHP的登录和注册的功能的实现
Aug 06 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出现Cannot modify header information问题的解决方法大全
2008/04/09 PHP
延长phpmyadmin登录时间的方法
2011/02/06 PHP
php ci框架中加载css和js文件失败的解决方法
2014/03/03 PHP
Yii2中简单的场景使用介绍
2017/06/02 PHP
javascript 事件绑定问题
2011/01/01 Javascript
JS在textarea光标处插入文本的小例子
2013/03/22 Javascript
js跨域访问示例(客户端/服务端)
2014/05/19 Javascript
node.js中的console用法总结
2014/12/15 Javascript
javascript鼠标滑动评分控件完整实例
2015/05/13 Javascript
jquery京东商城双11焦点图多图广告特效代码分享
2015/09/06 Javascript
jquery+json实现动态商品内容展示的方法
2016/01/14 Javascript
JS简单实现无缝滚动效果实例
2016/08/24 Javascript
jQuery中的100个技巧汇总
2016/12/15 Javascript
JS实现仿百度文库评分功能
2017/01/12 Javascript
vue如何集成raphael.js中国地图的方法示例
2017/08/15 Javascript
基于Vue生产环境部署详解
2017/09/15 Javascript
JavaScript适配器模式详解
2017/10/19 Javascript
JS实现4位随机验证码
2020/10/19 Javascript
python opencv之分水岭算法示例
2018/02/24 Python
利用python的socket发送http(s)请求方法示例
2018/05/07 Python
解决python3 json数据包含中文的读写问题
2018/05/10 Python
django 删除数据库表后重新同步的方法
2018/05/27 Python
通过python顺序修改文件名字的方法
2018/07/11 Python
Python使用pickle模块实现序列化功能示例
2018/07/13 Python
python实现Excel文件转换为TXT文件
2019/04/28 Python
python global和nonlocal用法解析
2020/02/03 Python
Ariat英国官网:为世界顶级马术运动员制造最优质的鞋类和服装
2020/02/14 全球购物
公务员职务工作的自我评价
2013/11/01 职场文书
教师岗位职责
2013/11/17 职场文书
运动会通讯稿100字
2014/01/31 职场文书
单位作风建设剖析材料
2014/10/11 职场文书
党员对十八届四中全会的期盼思想汇报范文
2014/10/17 职场文书
个人年终总结结尾
2015/03/06 职场文书
酒店客房服务员岗位职责
2015/04/09 职场文书
浅谈Python中的函数(def)及参数传递操作
2021/05/25 Python
索尼ICF-5900W收音机测评
2022/04/24 无线电