• PHP版滑动时间窗口算法


     
     
    <?php
    /**
     * 作者:码农编程进阶笔记
     * 点赞、分享朋友圈是最大的支持
     */
    session_start();
    $time = 60;//60秒
    $count = 10; //可访问 10次
    //第一次初始化
    if(!isset($_SESSION['count'])){
        $_SESSION['count'] = 1;
        $_SESSION['time'] = time();
        $_SESSION['cha'] = 0;
        $_SESSION['status'] = 'success';
        print_r($_SESSION);
    }else {
        $now = time();
        $cha = $now - $_SESSION['time'];
        $avg = intval($time / $count);//平均多少秒可获得一次机会
        //如果超过次数
        if($_SESSION['count'] > $count){
            //如果时差超过平均可获得次数的时长
            if($cha > $avg){
                $_SESSION['count'] -= intval($cha / $avg); //计算可得多少次机会
                $_SESSION['count'] = max($_SESSION['count'], 0);//修正次数不能为负。
                $_SESSION['count']++;
                $_SESSION['time'] = $now;
                $_SESSION['cha'] = $cha;
                $_SESSION['status'] = 'success';
                print_r($_SESSION);
            }else{
                //如果时差没有超过 $avg ,则还是失败。
                $_SESSION['cha'] = $cha;
                $_SESSION['status'] = 'fail';
                print_r($_SESSION);
            }
        }else{
            //如果没超过次数正常访问
            if($cha > $avg) {
                $_SESSION['count'] -= intval($cha / $avg); //计算可得多少次机会
                $_SESSION['count'] = max($_SESSION['count'], 0);//修正次数不能为负。
            }
            $_SESSION['count']++;
            $_SESSION['time'] = $now;
            $_SESSION['cha'] = $cha;
            $_SESSION['status'] = 'success';
            print_r($_SESSION);
        }
    }

    如果要精确计算,则要记录每次访问以元素的形式记录时间戳,到数组,每次请求的时候,遍历数组元素中的时间戳,与当前时间比较,清理掉 N分钟之前的元素,然后再计算个数,如果个数没超,则允许,反之不行。

    /**
     * 滑动时间窗口
     * 每次成功访问时,记录访问时间点
     * 每次清理N分钟之前的访问时间点
     * 对访问次数进行计数,判断是否超过次数
     * 作者:码农编程进阶笔记
     * @param $minute
     * @param $count
     * @param $times
     * @return bool
     */
    function timeWindow($minute, $count, &$times){
    
        $now = time();
        $point = $now - $minute * 60;//从当前时间往前推N分钟的时间点
        foreach($times as $key => $item){
            if($item < $point) unset($times[$key]); //把N分钟之前的访问清理掉
        }
    
        if(count($times) <= $count){
            $times[] = $now; //成功时,记录本次访问时间点
            return true;
        }
        return false;
    
    }

    ceb83ebd74f8651b91b502b4dbaf3cb0.png

  • 相关阅读:
    void及void指针含义的深刻解析
    jbpm入门样例
    给字符数组赋值的方法
    linux tar.gz zip 解压缩 压缩命令
    android 文件上传
    职员有薪水了
    sublime配置全攻略
    [置顶] WPF数据修改demo
    Java实现快速排序
    Java实现快速排序
  • 原文地址:https://www.cnblogs.com/lxwphp/p/15847707.html
Copyright © 2020-2023  润新知