redis并发锁 thinkphp5_thinkphp5 + redis 实现接口高并发限流

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

话不多述直接上代码:

先看下我项目目录:

05acc0bff6039fd9ad5e8f086889cebc.png

LeakyBucket实现类

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;

}

}

中间件

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

// +----------------------------------------------------------------------

// | 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

// +----------------------------------------------------------------------

// +----------------------------------------------------------------------

// | 中间件配置

// +----------------------------------------------------------------------

return [

// 默认中间件命名空间

'check'=>app\http\middleware\CheckParam::class

];

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

namespace app\index\controller;

use think\Controller;

class Common extends Controller

{

protected $middleware = ['check'];

}

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

leaky_bucket.php

// +----------------------------------------------------------------------

// | LeakyBucket设置

// +----------------------------------------------------------------------

return [

'max_burst' => 60, //初始化桶容量

'tokens' => 20, //漏斗的速率

'seconds' => 60, //时间

];

redis.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

希望与广大网友互动??

点此进行留言吧!