在laravel中如何用redis创建限流中间件

发布时间:2022-03-14 20:17:13 阅读:1379次

在laravel中如何用redis创建限流中间件

其实主要实现两个功能

单位时间内,限制所有用户的访问次数
单位时间内,限制一个用户[ip]的访问次数
// 以Laravel框架为例
namespace App\Http\Middleware;

use Closure,redis;
use Illuminate\Http\Request;
use Illuminate\Http\Response as SymfonyResponse;
use Illuminate\Support\Facades\Response;

/**
 * 流量限制器
 * 实现两个功能
 * 1. 单位时间内,限制所有用户的访问次数
 * 2. 单位时间内,限制一个用户[ip]的访问次数
 */
class LimitFlowMiddleware
{
    private $oneITime = 60; // 单位时间 一分钟
    private $oneIMax = 50; // 一个用户Ip一分钟最多仅允许访问访问10次

    private $platITime = 60; // 针对所有用户,单位时间内允许访问的最大次数
    private $platIMax = 10; // 针对所有的用户,该接口最多仅允许访问N次


    public function handle(Request  $request, Closure $next)
    {
        $redis = new redis();
        $userid = 12;
        $redis->connect("127.0.0.1");
        $redis->auth("");
        $redis->select(0);
        //.... 针对平台全局锁,用于限制单位时间内所有用户访问的次数
        $platKey = md5($request->path());

        $platFlowCount = $redis->get($platKey);// 平台访问次数
        if($platFlowCount){
            if($platFlowCount >= $this->platIMax){
                return Response::json("平台超过限制",SymfonyResponse::HTTP_LOCKED,[],256);
            }
        }
        $redis->incr($platKey);// ++1 次访问次数
        !$platFlowCount && $redis->expire($platKey,$this->platITime); // 设置锁的有效时间

        // ... 针对单个用户实现的访问锁
        $key = md5($request->getClientIp().":".$userid);
        // 实现一个用户一分钟最多允许访问10次
        $userFlowCount = $redis->get($key); // 单个用户访问次数
        if($userFlowCount){
            if($userFlowCount >= $this->oneIMax){
                return Response::json("用户访问超过限制",SymfonyResponse::HTTP_LOCKED,[],256);
            }
        }
        $redis->incr($key);// ++1 次访问次数
        !$userFlowCount && $redis->expire($key,$this->oneITime);// 设置锁的有效时间

        return $next($request);
    }
}

如有问题,可以QQ搜索群1028468525加入群聊,欢迎一起研究技术

支付宝 微信

有疑问联系站长,请联系QQ:QQ咨询

转载请注明:在laravel中如何用redis创建限流中间件 出自老鄢博客 | 欢迎分享