zoukankan      html  css  js  c++  java
  • php 基于redis使用令牌桶算法 计数器 漏桶算法 实现流量控制

    通常在高并发和大流量的情况下,一般限流是必须的。为了保证服务器正常的压力。那我们就聊一下几种限流的算法。

    1. 计数器
      计数器是一种最常用的一种方法,在一段时间间隔内,处理请求的数量固定的,超的就不做处理。

    demo

    public function SpeedCounter()
        {
            $redis = new Redis();
            $redis->connect('127.0.0.1', 6379);
    
            // 最大请求数量
            $maxCount = 100;
    
            //每分钟内,一个用户只能访问10次
            $interval =60;
            //请求总数量
            $zcount = $redis->incr('zcont');
    
            //判断是否超过最大值
            if ($zcount<=$maxCount) {
                //业务处理
                $user = [
                    11,21,31,41,51,61
                ];
    
                foreach ($user as $val) {
                    $key = $val;
                    $check = $redis->exists($key);
                    if ($check) {
                        $sum = $redis->incr($key);
    
                        if ($sum<=5){
                            //业务处理
                            echo "每个用户在规定的时间内只能访问5次 $sum";
                        } else {
    
                            echo "你已经购买过 $sum";
                        }
    
    
    
                    } else {
                        //print_r($redis->get($key)) ;
                        ///请购买
                        echo "请购买";
                        $sum = $redis->incr($key);
                        $redis->Expire($key,$interval);
    
                    }
    
    
                }
    
    
            } else {
                //超过请求数量
                $redis->Expire('zcont',$interval);
                echo '超出请求'.$zcount;
    
            }
    
    
    1. 漏桶算法

    漏桶的大小是固定的,处理速度也是固定的,但是请求的速率的不固定的。在突发的情况下,会丢弃很多请求。

     /**
         * **漏桶的大小是固定的,处理速度也是固定的,但是请求的速率的不固定的。在突发的情况下,会丢弃很多请求。**
         */
        function LeackBucket() {
    
            $redis = new Redis();
            $redis->connect('127.0.0.1', 6379);
    
            //桶的容量
            $maxCount = 1000;
            //时间
            $interval = 10;
            //每分钟流出的数量
            $speed   = 20;
            //用户
            $time = $redis->time();
            $key = $time[0].$time[1];
    
                //时间判断
    
            //$redis->del('outCount');
            $check = $redis->exists('outCount');
          // echo $check;
                if ($check){
                    //出桶的速率的请求数量
                    $outCount = $redis->incr('outCount');
    
                    if ($outCount<=$speed){
                        //业务处理
    
                        echo "规定的时间内只能访问20次 $outCount";
    
                    } else {
    
                        echo "你已经超过每分钟的访问 $outCount";
                    }
    
                } else {
    
                    $outCount = $redis->incr('outCount');
                  //  echo $outCount;
                    $redis->Expire('outCount',$interval);
    
                    echo "时间过了";exit;
                }
    
    
    
    
    
    
    
        }
    
    1. 令牌桶
      令牌桶算法(Token Bucket)和 Leaky Bucket 效果一样但方向相反的算法,更加容易理解.随着时间流逝,系统会按恒定1/QPS时间间隔(如果QPS=100,则间隔是10ms)往桶里加入Token(想象和漏洞漏水相反,有个水龙头在不断的加水),如果桶已经满了就不再加了.新请求来临时,会各自拿走一个Token,如果没有Token可拿了就阻塞或者拒绝服务.

    令牌桶的另外一个好处是可以方便的改变速度. 一旦需要提高速率,则按需提高放入桶中的令牌的速率. 一般会定时(比如100毫秒)往桶中增加一定数量的令牌, 有些变种算法则实时的计算应该增加的令牌的数量.

     /**
         * 令牌
         */
        function TrafficShaper(){
    
            $redis = new Redis();
            $redis->pconnect('127.0.0.1', 6379);
            //桶的容量
            $maxCount = 10;
            //当前容量
            $curnum = $maxCount-$redis->get('token')-1;
            echo $curnum;
    
    
             if ($curnum>0){
                 //业务逻辑
                 //成功后
    
                $token = $redis->incr('token');
                 echo "===$token";
    
    
    
             } else {
    
                 echo "没有令牌了";
                 $redis->set('token',0);
             }
    
    
    
        }
  • 相关阅读:
    1.linux6 x86-64 RPM包安装mysql5.7.20
    zepto中的animate
    java开发环境配置
    sql按相似度模糊查询实例
    下载方法收集
    myeclipseBlue6.5破解,运行即可得到key
    浮点数特点
    java进制之间的转换
    java小算法
    Java中的DateFormat用法
  • 原文地址:https://www.cnblogs.com/myJuly/p/13608524.html
Copyright © 2011-2022 走看看