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;
        }
    }
    

      

    得意时做事,失意时读书
  • 相关阅读:
    视图、触发器、事物、存储过程、函数、流程控制
    pymysql
    单表查询与多表查询
    多线程学习(第三天)线程间通信
    多线程学习(第二天)Java内存模型
    多线程学习(第一天)java语言的线程
    springboot集成es7(基于high level client)
    elasticSearch(六)--全文搜索
    elasticSearch(五)--排序
    elasticSearch(四)--结构化查询
  • 原文地址:https://www.cnblogs.com/lanse1993/p/14184721.html
Copyright © 2011-2022 走看看