MENU

【教程】合理实现API限制访问次数

2021 年 03 月 01 日 • 阅读: 372 • 分享教程

自己在整 API 限制一段时间内访问次数时,搜索网上的例子发现大多是限制一分钟(按时刻,例 XX:01:00--XX:02:00),这样如果在 59 秒时访问达到上限,下一秒访问次数限制刷新,又可访问达到上限次数,这样显然是不合理的,应该使用时间段来限制访问次数,下面是我在整自己 API 限制访问频率时使用的方法,如果 API 程序不限用户账号调用可自行删改。


<?php
    /**
     * @param $uid
     * @return bool|int
     * 检测用户接口访问频率
     */
    function api_frequency_visits ($uid) {
        $key = "user:{$uid}:api:frequency";
        $redis = new Redis();
        $redis->connect('127.0.0.1');
        $data = $redis->hGetAll($key);
        //需要删除的key
        $del_key = [];
        //时间内访问的总次数
        $total = 0;
        //时间内最大访问次数
        $max_frequency = 20;
        //当前时间
        $now_time = time();
        //限制时间
        $limit_time = 60;
        foreach ($data as $time=>$count) {
            if ($time < $now_time - $limit_time) {
                $del_key[] = $time;
            } else {
                $total += $count;
            }
        }
        //存在需要删除的key
        if ($del_key) {
            $redis->hDel($key, ...$del_key);
        }
        if ($total >= $max_frequency) {
            return false;
        }
        return $redis->hIncrBy($key, $now_time, 1);
    }
    //调用
    $uid = 1;
    $result = api_frequency_visits($uid);
    if (!$result) {
        echo  json_encode(['code'=>0, 'msg'=>'操作过于频繁', 'data'=>[]]);die;
    }
    echo  json_encode(['code'=>1, 'msg'=>'', 'data'=>[
        'uid'=>$uid,
        'other'=>rand()
    ]]);die;
?>
最后编辑于: 2021 年 03 月 06 日
返回文章列表 文章二维码
本页链接的二维码
打赏二维码