欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

thinkphp5 + redis 实现接口高并发限流

程序员文章站 2022-03-23 18:59:50
thinkphp5实现接口高并发限流基于redis实现接口限流,主要使用Redis的一个模块:Redis-Cellredis-cell如何使用,请你参考上一篇文章,传送门:https://blog.csdn.net/liuxl57805678/article/details/108824411话不多述直接上代码:先看下我项目目录:LeakyBucket实现类

基于redis实现接口限流,主要使用Redis的一个模块:Redis-Cell

redis-cell如何使用,请你参考上一篇文章,传送门:https://blog.csdn.net/liuxl57805678/article/details/108824411

话不多述直接上代码:

先看下我项目目录:

thinkphp5 + redis 实现接口高并发限流

LeakyBucket实现类

<?php

namespace app\common\server;

class LeakyBucket
{
    protected $key = null;
    
    protected $max_burst = null;
    
    protected $tokens = null;
    
    protected $seconds = null;
    
    protected $apply = 1;
    
    protected $redis_connect;
    
    /**
     * LeakyBucket construct
     * @param $key string
     * @param $max_burst int 初始桶数量
     * @param $tokens int 速率
     * @param $seconds int 时间
     * @param int $apply 每次漏水数量
     */
    public function __construct($key, $max_burst, $tokens, $seconds, $apply = 1)
    {
        $this->initRedis();
        $this->key = $key;
        $this->max_burst = $max_burst;
        $this->tokens = $tokens;
        $this->seconds = $seconds;
        $this->apply = $apply;
    }
    
    /**
     * 是否放行
     * @return int 0 or 1   0:放行  1:拒绝
     */
    public function isPass()
    {
        $rs = $this->redis_connect->rawCommand('CL.THROTTLE', $this->key, $this->max_burst, $this->tokens, $this->seconds, $this->apply);
        return $rs[0];
    }
    
    //初始化redis
    public function initRedis($conf = [])
    {
        if (empty($conf)) {
            if (!empty(config('redis.'))) {
                $conf = config('redis.');
            }
        }
        
        $this->redis_connect = $this->init($conf);
    }
    
    protected function init($redisCfg)
    {
        if (extension_loaded('redis')) {
            if (empty($redisCfg)) {
                return '请配置redis信息!';
            }
            return $this->setupServer($redisCfg);
        } else {
            exit('缺少redis扩展!');
        }
    }
    
    public function setupServer($config)
    {
        $this->redis_connect = new \Redis();
        if ($config['socket_type'] === 'unix') {
            $success = $this->redis_connect->connect($config['socket']);
        } else {
            $success = $this->redis_connect->connect($config['host'], $config['port'], $config['timeout']);
        }
        if (!$success) {
            return false;
        } else {
            if (isset($config['password'])) {
                $this->redis_connect->auth($config['password']);
            }
            
            if (isset($config['db']) && !empty($config['db'])) {
                $this->redis_connect->select(intval($config['db']));
            }
        }
        
        return $this->redis_connect;
    }
    
}

中间件

<?php

namespace app\http\middleware;

use app\common\server\LeakyBucket;
use think\Request;

class CheckParam
{
    public function handle(Request $request, \Closure $next)
    {
        $ip = $request->ip(0, 1);
        $leakyBucketConfig = config('leaky_bucket.');
        $server = new LeakyBucket($ip, $leakyBucketConfig['max_burst'], $leakyBucketConfig['tokens'], $leakyBucketConfig['seconds']);
        if ($server->isPass()){
            $res['code'] = 1001;
            $res['msg'] = '操作频繁,请稍后再试';
            return json($res);
        }
        return $next($request);
        }
    }
}

中间件配置 config 目录下找到:middleware.php

<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------

// +----------------------------------------------------------------------
// | 中间件配置
// +----------------------------------------------------------------------
return [
    // 默认中间件命名空间
    'check'	=>	app\http\middleware\CheckParam::class
];

调用中间件:(后面所有的控制器集成Common即可)其他调用中间件方式,请参考官方手册。

<?php

namespace app\index\controller;

use think\Controller;

class Common extends Controller
{
    protected $middleware = ['check'];
}

 

相关配置文件:配置文件放在config目录下

leaky_bucket.php

<?php
// +----------------------------------------------------------------------
// | LeakyBucket设置
// +----------------------------------------------------------------------
return [
    'max_burst' => 60,  //初始化桶容量
    'tokens' => 20,     //漏斗的速率
    'seconds' => 60,    //时间
];

redis.php

<?php

// +----------------------------------------------------------------------
// | Redis设置
// +----------------------------------------------------------------------
return [
    'socket_type' => 'tcp',
    'host' => '127.0.0.1',
    'port' => '6379',
    'timeout' => 10,
    'password' => '',
    'db' => 0
];

 

喜欢的朋友记得点赞收藏哦。

 

本文地址:https://blog.csdn.net/liuxl57805678/article/details/108849044

相关标签: Redis PHP