令牌桶

<?php
/**
 * 令牌桶
 * Class TokenBucket
 */
class TokenBucket
{
    // 令牌最大数量
    private $token_num;
    // redis对象
    private $redis;
    // 队列名称
    private $queue;

    public function __construct($redis_host = '127.0.0.1', $redis_password = '', $redis_port = 6379, $queue = 'token_bucket', $token_num = 100)
    {
        $this->redis = new Redis();
        $this->redis->pconnect($redis_host, $redis_port);
        if(!empty($redis_password))
        {
            $this->redis->auth($redis_password);
        }
        $this->queue = $queue;
        $this->token_num = $token_num;
    }

    /**
     * 加入到令牌桶
     * @param int $num 加入令牌桶的数量
     * @return bool
     */
    public function add($num = 0)
    {
        // 当前令牌桶的数量
        $now_num = $this->redis->lSize($this->queue);
        // 可加入的令牌数
        $num = ($this->token_num - $now_num) >= $num ? $num : $this->token_num - $now_num;

        if($num > 0)
        {
            $this->redis->lPush($this->queue, ...array_fill(0, $num, 1));
            return true;
        }
        return false;
    }

    /**
     * 重置令牌桶
     */
    public function reset()
    {
        $this->redis->delete($this->queue);
        $this->add($this->token_num);
    }

    /**
     * 获取令牌
     * @return bool
     */
    public function get()
    {
        return $this->redis->rPop($this->queue) ? true : false;
    }
}
原文链接:,转发请注明来源!
评论已关闭。