企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
## 一,系统配置 .env 中配置redis ~~~ [REDIS0] TYPE = redis HOST = 127.0.0.1 PORT = 6379 PASSWORD = ~~~ 说明:刘宏缔的架构森林是一个专注架构的博客,地址:[https://www.cnblogs.com/architectforest](https://www.cnblogs.com/architectforest)          对应的源码可以访问这里获取: [https://github.com/liuhongdi/ ](https://github.com/liuhongdi/)         或: [https://gitee.com/liuhongdi](https://gitee.com/liuhongdi) 说明:作者:刘宏缔 邮箱: 371125307@qq.com ## 二,编写php代码 1,controller/Goods.php [![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码") ~~~ 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","超出访问频率限制"); } } } ~~~ [![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码") 说明:此处仅做演示,实际应用时应该把这个拦截限流的功能放到middleware中 2,lib/util/RedisLuaRate.php [![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码") ~~~ <?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; } } ~~~ [![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码") 说明: eval函数的第3个参数为KEYS个数。 phpredis依据此值将KEYS和ARGV做区分 ## 三,测试效果 1,用ab做并发测试: [![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码") ~~~ 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) ~~~ [![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(0); "复制代码") 2,查看代码在日志中写入的结果: [![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(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: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: ~~~ [![复制代码](https://common.cnblogs.com/images/copycode.gif)](javascript:void(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 ~~~