zoukankan      html  css  js  c++  java
  • 【PHP】php 基于redis使用令牌桶算法实现流量控制

    整理自:

    https://www.cnblogs.com/itbsl/p/13407489.html

    https://www.cnblogs.com/myJuly/p/13608475.html

    https://mp.weixin.qq.com/s/JQYWVL2YUKLiVZfV99z4cg

    如果有侵权请联系删除

    令牌桶算法
    1. 首先设有一个令牌桶,桶内存放令牌,一开始令牌桶内的令牌是满的(桶内令牌的数量可根据服务器情况设定)

    2. 每次访问从桶内取走一个令牌,当桶内令牌为0,则不允许再访问。

    3. 每隔一段时间,放入令牌,最多使桶内令牌满额。

    class TrafficShaperController extends Controller
    {
    
        /**
         * 令牌桶总数量
         * @var int
         */
        private $totleNum = 25;
    
        /**
         * 令牌标识(可以根据需要加上关键ID,uid、orderid...)
         * @var string
         */
        private $quekueName ="TrafficShaper_queue";
    
        /**
         * redis缓存类
         * @var object
         */
        private $redis;
    
        /**
         * 初始化方法
         *
         * @author heyw<1051834593@qq.com>
         * @since  2020/12/10
         */
        public function _initialize()
        {
            $this->redis = Redis::getInstance();
        }
    
        /**
         * 模拟用户消耗令牌
         *
         * @param int $num
         * @author heyw<1051834593@qq.com>
         * @since  2020/12/10
         */
        public function run($num = 1)
        {
            // 初始化
            $this->reset();
    
            // 模拟1s请求10次
            while (1) {
                $this->getKey();
                sleep(0.1);
            }
        }
    
        /**
         *  获取令牌
         *
         * @return bool
         * @author heyw<1051834593@qq.com>
         * @since  2020/12/11
         */
        protected function getKey()
        {
            // 初始化
            $redis = $this->redis;
            $queueName = $this->quekueName;
    
            // 获取一个令牌,如果没有直接返回
            $res = $redis->rPop($queueName);
    
            // 获得令牌,处理业务
            var_dump($res ?'get it' : 'empty');
    
            return true;
        }
    
        /**
         * 重置
         *
         * @author heyw<1051834593@qq.com>
         * @since  2020/12/11
         */
        protected function reset()
        {
            $this->redis->delete($this->quekueName);
            $this->add(25);
        }
    
        /**
         * 定时加入令牌桶,1s执行1次
         *
         * @author heyw<1051834593@qq.com>
         * @since  2020/12/10
         */
        public function add($stepNum = 5)
        {
            // 初始化
            $redis      = $this->redis;
            $queueName  = $this->quekueName;
    
            // 当前令牌书
            $currNum    = $redis->lSize($queueName) ?: 0;
            $maxNum     = $this->totleNum;
            $addNum     = $maxNum >= $currNum + $stepNum ? $stepNum : $maxNum - $currNum;
            if ($addNum == 0) {
                return true;
            }
    
            // 加入令牌
            $token = array_fill(0, $addNum, 1);
            $redis->lPush($queueName, $token);
    
            return true;
        }
    }
    

      

    得意时做事,失意时读书
  • 相关阅读:
    2.6
    2.5
    2.4
    2.3
    2.2
    2.1
    条件查询
    项目办公自动化工具-文件夹照片批量插入word&#183;
    suffer根据CGCS2000坐标利用散点图生成奥维坐标
    案例应用:给照片文件夹里照片按日期排序后引用表格的照片名称批量重命名(源码)
  • 原文地址:https://www.cnblogs.com/lanse1993/p/14184721.html
Copyright © 2011-2022 走看看