令牌桶实现服务器限流

啥是令牌桶算法限流:

  回到了改革开放吃集体饭的时代(生产力不足),有布票才能买到布,才能做成衣服。

回到服务器来说,就是服务器每秒并发只有200,但是超过200以上的访问,持续一段时间,就可能导致‘岩机’。如果服务器被ddos攻击了,用到令牌桶算法限流,可以解决服务器死机不响应问题。

如何实现呢,我简单写了一个令牌桶类,大概能描述这个意思:  

<?php
/**
 *User:jiangsheng
 *Date:2021/11/29
 *Email:<547814711@qq.com>
 */
## 令牌桶功能
### 请求令牌|生成令牌|初始化临牌桶
### 逻辑:每秒根据给生成100个令牌,用完就不给访问(提示没有访问间隔),每秒往令牌桶插入100条,如果存在未使用完令牌就补充多少个

class TokenBucket{
    private static $_maxNum = 100;
    private static $_redis=null;
    private static $_link;
    private static $_config = [
        'host'=>'127.0.0.1',
        'port'=>'6379'
    ];
    # 创建一个redis单例对象,初始化
    public static function initialization(array $config=[]){
        if ( count($config) > 0 )
            self::$_config = $config;

        if ( self::$_redis == null )
            self::$_redis = new redis();

        try{
            self::$_link = self::$_redis->connect( self::$_config['host'] , self::$_config['port'] );
        }catch (Exception $e){
            die($e->getMessage());
        }

        return self::$_redis;
    }
    # 初始化令牌
    public static function set(string $key='k'){
//        self::$_redis->flushAll();
        $currNum = self::$_redis->lLen( $key );
        do{
            self::$_redis->lPush($key, $key.$currNum);
            $currNum++;
        }while( $currNum < self::$_maxNum );
        return self::$_redis->lRange($key, 0, self::$_maxNum);
    }
    public static function get(string $key='k'){
        return self::$_redis->rPop($key);
    }
    private function __construct(){
        // TODO: Implement __wakeup() method.
    }
    final function __destruct(){
        // TODO: Implement __wakeup() method.
    }
    final function __clone(){
        // TODO: Implement __wakeup() method.
    }
    final function __wakeup(){
        // TODO: Implement __wakeup() method.
    }
}

$config = ['host'=>'localhost','port'=>'6379'];
$link =  TokenBucket::initialization($config);
$k1Arr = TokenBucket::set();

// 模拟客户端1s请求102次
$i=0;
$requestNum = 102;
while($i<$requestNum){
    $key = TokenBucket::get();
    if(empty($key)){
        echo "<br>用户".$i."无法访问";
    }else{
        echo "<br>用户".$i.",获取到key=》".$key;
    }
    $i++;
}
分享技术,方便你我他。
原文地址:https://www.cnblogs.com/leijiangsheng/p/15623234.html