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);
});

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值