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

      

    得意时做事,失意时读书
  • 相关阅读:
    SwiftUI extension Bundle for parse JSON file All In One
    如何清理 MacBook Pro 笔记本电脑外壳上贴纸残胶 All In One
    pure CSS carousel effect All In One
    SwiftUI custom MapAnnotation All In One
    Xcode code folding ribbon All In One
    技术人员副业赚钱之道 All In One
    图解算法数据结构 All In One
    js iterator protocol & next() All In One
    Vue 3 Transition All In One
    Bloom Filter js version All In One
  • 原文地址:https://www.cnblogs.com/lanse1993/p/14184721.html
Copyright © 2020-2023  润新知