php令牌桶限流
作者:互联网
前端每次请求从令牌桶取走令牌,后端匀速向桶内投递令牌,如果前端取到令牌,则说明这次请求有效,否则让前端再次请求或者等待。避免了大量请求下服务器压力过大导致的崩溃问题。
令牌桶算法:
<?php
class Token
{
private $_max;
private $_queue;
private $_redis;
public function __construct()
{
try {
$this->_redis = new \Redis();
$this->_redis->connect('127.0.0.1', 6379);
$this->_queue = 'token';
$this->_max = 10;
} catch (RedisException $exception) {
throw new Exception($exception->__toString());
return false;
}
}
/**
* 令牌初始化
*/
public function reset()
{
$this->_redis->del($this->_queue);
$this->add($this->_max);
}
/**
* 添加令牌
* @param int $number
*/
public function add($number = 1)
{
$maxNumber = $this->_max;
$currentNumber = $this->_redis->lLen($this->_queue);
$number = $maxNumber >= ($currentNumber + $number) ? $number : ($maxNumber - $currentNumber);
if ($number > 0) {
$tokens = array_fill(0, $number, 1);
foreach ($tokens as $token) {
$this->_redis->lPush($this->_queue, $token);
}
}
}
/**
* 获取令牌
*/
public function get()
{
return $this->_redis->rPop($this->_queue) ? true : false;
}
}
消费类:模拟用户请求
<?php
require 'token.php';
$token = new Token();
swoole_timer_tick(500, function () use ($token) {
var_dump($token->get());
});
投递类:后端向令牌桶投递
定时写入令牌
<?php
require 'token.php';
$token = new Token();
//投递令牌
swoole_timer_tick(800, function () use ($token) {
$token->add(1);
});
标签:maxNumber,令牌,redis,number,queue,token,限流,php 来源: https://blog.csdn.net/qq_43035350/article/details/111053234