Jquery中文网 www.jquerycn.cn
Jquery中文网 >  脚本编程  >  php  >  正文 令牌桶算法如何使用php实现

令牌桶算法如何使用php实现

发布时间:2020-05-23   编辑:www.jquerycn.cn
jquery中文网为您提供令牌桶算法如何使用php实现等资源,欢迎您收藏本站,我们将为您提供最新的令牌桶算法如何使用php实现资源

php redis实现令牌桶算法代码:

<?phpnamespace Api\Lib;/**
 * 限流控制
 */class RateLimit{
    private $minNum = 60; //单个用户每分访问数
    private $dayNum = 10000; //单个用户每天总的访问量

    public function minLimit($uid)
    {
        $minNumKey = $uid . '_minNum';
        $dayNumKey = $uid . '_dayNum';
        $resMin    = $this->getRedis($minNumKey, $this->minNum, 60);
        $resDay    = $this->getRedis($minNumKey, $this->minNum, 86400);
        if (!$resMin['status'] || !$resDay['status']) {
            exit($resMin['msg'] . $resDay['msg']);
        }
    }

    public function getRedis($key, $initNum, $expire)
    {
        $nowtime  = time();
        $result   = ['status' => true, 'msg' => ''];
        $redisObj = $this->di->get('redis');
        $redis->watch($key);
        $limitVal = $redis->get($key);
        if ($limitVal) {
            $limitVal = json_decode($limitVal, true);
            $newNum   = min($initNum, ($limitVal['num'] - 1)   (($initNum / $expire) * ($nowtime - $limitVal['time'])));
            if ($newNum > 0) {
                $redisVal = json_encode(['num' => $newNum, 'time' => time()]);
            } else {
                return ['status' => false, 'msg' => '当前时刻令牌消耗完!'];
            }
        } else {
            $redisVal = json_encode(['num' => $initNum, 'time' => time()]);
        }
        $redis->multi();
        $redis->set($key, $redisVal);
        $rob_result = $redis->exec();
        if (!$rob_result) {
            $result = ['status' => false, 'msg' => '访问频次过多!'];
        }
        return $result;
    }}

代码要点:

1、首先定义规则

单个用户每分钟访问次数($minNum),单个用户每天总的访问次数($dayNum),接口总的访问次数等不同的规则。

2、计算速率

该代码示例以秒为最小的时间单位,速率=访问次数/时间($initNum / $expire)

3、每次访问后补充的令牌个数计算方式

获取上次访问的时间即上次存入令牌的时间,计算当前时刻与上次访问的时间差乘以速率就是此次需要补充的令牌个数,注意补充令牌后总的令牌个数不能大于初始化的令牌个数,以补充数和初始化数的最小值为准。

4、程序流程

第一次访问时初始化令牌个数($minNum),存入Redis同时将当前的时间戳存入以便计算下次需要补充的令牌个数。

第二次访问时获取剩余的令牌个数,并添加本次应该补充的令牌个数,补充后如何令牌数>0则当前访问是有效的可以访问,否则令牌使用完毕不可访问。先补充令牌再判断令牌是否>0的原因是由于还有速率这个概念即如果上次剩余的令牌为0但是本次应该补充的令牌>1那么本次依然可以访问。

5、针对并发的处理

使用Redis的乐观锁机制。

更多相关知识,请关注 jquery中文网!!

以上就是令牌桶算法如何使用php实现的详细内容,更多请关注jQuery中文网其它相关文章!

  • 本文原创发布jQuery中文网,转载请注明出处,感谢您的尊重!
  • 您可能感兴趣的文章:
    Golang 限流器的使用和实现
    令牌桶算法如何使用php实现
    (三)go-kit服务接口限流
    Golang map底层实现原理解析
    php洗牌算法的实现代码
    简单意义上的桶排序(PHP实现)
    PHP开发者如何做好密码保护以及Laravel底层密码存储和验证实现
    Golang map之tophash详解
    jQuery实战之仿淘宝商城左侧导航效果
    PHP防止重复提交表单的例子

    [关闭]