zoukankan      html  css  js  c++  java
  • 令牌桶实现服务器限流

    啥是令牌桶算法限流:

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

    回到服务器来说,就是服务器每秒并发只有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++;
    }
    分享技术,方便你我他。
  • 相关阅读:
    SqlHelper
    asp.net中窗口相关操作总结(javascript)
    ASP.NET顯示對話框
    为ASP.NET控件添加常用的JavaScript操作
    右键弹出菜单
    log4net的初使用
    QQ/MSN右下角弹出提示窗口
    简便无刷新文件上传系统
    简单的自动更新程序实
    SQL中的单记录函数
  • 原文地址:https://www.cnblogs.com/leijiangsheng/p/15623234.html
Copyright © 2011-2022 走看看