• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

thinkphp6: 用redis+lua做限流(php 8.1.1 / thinkphp v6.0.10LTS )

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

一,系统配置

.env 中配置redis

[REDIS0]
TYPE = redis
HOST = 127.0.0.1
PORT = 6379
PASSWORD =

说明:刘宏缔的架构森林是一个专注架构的博客,地址:https://www.cnblogs.com/architectforest

         对应的源码可以访问这里获取: https://github.com/liuhongdi/
         或: https://gitee.com/liuhongdi

说明:作者:刘宏缔 邮箱: [email protected]

二,编写php代码

1,controller/Goods.php
class Goods  extends BaseController
{
    /**
     * 商品详情
     *
     * @return \think\Response
     */
    public function Detail(){
 
        $rate = new RedisLuaRate();
        $res = $rate->setRate();
 
        $log = new BusinessLog("admin");
        $log->log("rate res:".$res.":");
 
        if ($res == "1") {
            return Result::Success("成功");
        } else {
            return Result::Error("1","超出访问频率限制");
        }
    }
}
说明:此处仅做演示,实际应用时应该把这个拦截限流的功能放到middleware中
 
2,lib/util/RedisLuaRate.php
<?php
namespace app\lib\util;
 
class RedisLuaRate {
    function setRate() {
        $lua = <<<SCRIPT
local key = KEYS[1];
local limit = tonumber(KEYS[2])
local length = tonumber(KEYS[3])
--redis.log(redis.LOG_NOTICE,' length: '..length)
local current = redis.call('GET', key)
if current == false then
   --redis.log(redis.LOG_NOTICE,key..' is nil ')
   redis.call('SET', key,1)
   redis.call('EXPIRE',key,length)
   --redis.log(redis.LOG_NOTICE,' set expire end')
   return '1'
else
   --redis.log(redis.LOG_NOTICE,key..' value: '..current)
   local num_current = tonumber(current)
   if num_current+1 > limit then
       return '0'
   else
       redis.call('INCRBY',key,1)
       return '1'
   end
end
SCRIPT;
 
        $redis = new \Redis();
        $redis->connect(env('redis0.host', '127.0.0.1'),env('redis0.port', '6379'));
        $redis->select(0);
        $key = "ip".request()->ip();
        $sequence = $redis->eval($lua, [$key,3,1], 3);
 
        $luaError = $redis->getLastError();
        if (isset($luaError)) {
           // print_r($luaError);
        }
 
        return $sequence;
    }
}

说明: eval函数的第3个参数为KEYS个数。 phpredis依据此值将KEYS和ARGV做区分

三,测试效果

1,用ab做并发测试:
liuhongdi@lhdpc:/data/php/admapi/app$ ab -c 10 -n 10 http://192.168.219.6:8000/goods/detail?goodsid=12323
This is ApacheBench, Version 2.3 <$Revision: 1879490 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
 
Benchmarking 192.168.219.6 (be patient).....done
 
 
Server Software:        nginx/1.18.0
Server Hostname:        192.168.219.6
Server Port:            8000
 
Document Path:          /goods/detail?goodsid=12323
Document Length:        37 bytes
 
Concurrency Level:      10
Time taken for tests:   0.059 seconds
Complete requests:      10
Failed requests:        7
   (Connect: 0, Receive: 0, Length: 7, Exceptions: 0)
Total transferred:      2276 bytes
HTML transferred:       496 bytes
Requests per second:    169.79 [#/sec] (mean)
Time per request:       58.897 [ms] (mean)
Time per request:       5.890 [ms] (mean, across all concurrent requests)
Transfer rate:          37.74 [Kbytes/sec] received
 
Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    1   0.5      1       2
Processing:    12   26  11.0     25      44
Waiting:       11   26  11.2     25      44
Total:         13   27  10.9     26      45
 
Percentage of the requests served within a certain time (ms)
  50%     26
  66%     29
  75%     37
  80%     42
  90%     45
  95%     45
  98%     45
  99%     45
100%     45 (longest request)
2,查看代码在日志中写入的结果:
2022-01-24 16:37:50--192.168.219.6--rate res:1:
2022-01-24 16:37:50--192.168.219.6--rate res:1:
2022-01-24 16:37:50--192.168.219.6--rate res:0:
2022-01-24 16:37:50--192.168.219.6--rate res:0:
2022-01-24 16:37:50--192.168.219.6--rate res:1:
2022-01-24 16:37:50--192.168.219.6--rate res:0:
2022-01-24 16:37:50--192.168.219.6--rate res:0:
2022-01-24 16:37:50--192.168.219.6--rate res:0:
2022-01-24 16:37:50--192.168.219.6--rate res:0:
2022-01-24 16:37:50--192.168.219.6--rate res:0:

可以看到在同一秒钟内,有三次返回成功,其余是返回失败

四,查看php和thinkphp的版本 

php:
liuhongdi@lhdpc:/data/php/admapi$ php --version
PHP 8.1.1 (cli) (built: Dec 20 2021 16:12:16) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.1.1, Copyright (c) Zend Technologies
    with Zend OPcache v8.1.1, Copyright (c), by Zend Technologies 
thinkphp:
liuhongdi@lhdpc:/var/www/html$ cd /data/php/admapi/
liuhongdi@lhdpc:/data/php/admapi$ php think version
v6.0.10LTS 

 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
Lua代码提示和方法跳转发布时间:2022-07-22
下一篇:
Lua安全调用metatable的简单应用发布时间:2022-07-22
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap