Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >swoole如何对ip限制访问频率

swoole如何对ip限制访问频率

作者头像
北溟有鱼QAQ
发布于 2019-12-19 05:34:02
发布于 2019-12-19 05:34:02
2.7K00
代码可运行
举报
文章被收录于专栏:北溟有鱼QAQ北溟有鱼QAQ
运行总次数:0
代码可运行

swoole如何对ip限制访问频率

在我们开发api的过程中,有的时候我们还需要考虑单个用户(ip)访问频率控制,避免被恶意调用。

归根到底也就只有两个步骤:

  • 用户访问要统计次数
  • 执行操作逻辑之前要判断次数频率是否过高,过高则不执行

easyswoole中实现Ip访问频率限制

本文章举例的是在easyswoole框架中实现的代码,在swoole原生中实现方式是一样的。

只要在对应的回调事件做判断拦截处理即可。

  • 使用swoole\Table,储存用户访问情况(也可以使用其他组件、方式储存)
  • 使用定时器,将前一周期的访问情况清空,统计下一周期

如以下IpList类,实现了初始化Table、统计IP访问次数、获取一个周期内次数超过一定值的记录

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<?php
/**
 * Ip访问次数统计
 * User: Siam
 * Date: 2019/7/8 0008
 * Time: 下午 9:53
 */

namespace App;

use EasySwoole\Component\Singleton;
use EasySwoole\Component\TableManager;
use Swoole\Table;

class IpList
{
    use Singleton;

    /** @var Table */
    protected $table;

    public  function __construct()
    {
        TableManager::getInstance()->add('ipList', [
            'ip' => [
                'type' => Table::TYPE_STRING,
                'size' => 16
            ],
            'count' => [
                'type' => Table::TYPE_INT,
                'size' => 8
            ],
            'lastAccessTime' => [
                'type' => Table::TYPE_INT,
                'size' => 8
            ]
        ], 1024*128);
        $this->table = TableManager::getInstance()->get('ipList');
    }

    function access(string $ip):int
    {
        $key  = substr(md5($ip), 8,16);
        $info = $this->table->get($key);

        if ($info) {
            $this->table->set($key, [
                'lastAccessTime' => time(),
                'count'          => $info['count'] + 1,
            ]);
            return $info['count'] + 1;
        }else{
            $this->table->set($key, [
                'ip'             => $ip,
                'lastAccessTime' => time(),
                'count'          => $info['count'] + 1,
            ]);
            return 1;
        }
    }

    function clear()
    {
        foreach ($this->table as $key => $item){
            $this->table->del($key);
        }
    }

    function accessList($count = 10):array
    {
        $ret = [];
        foreach ($this->table as $key => $item){
            if ($item['count'] >= $count){
                $ret[] = $item;
            }
        }
        return $ret;
    }

}

封装完IP统计的操作之后

我们可以在EasySwooleEvent.php的mainServerCreate回调事件中初始化IpList和定时器

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<?php

public static function mainServerCreate(EventRegister $register)
{
    // 开启IP限流
    IpList::getInstance();
    $class = new class('IpAccessCount') extends AbstractProcess{
        protected function run($arg)
        {
            $this->addTick(5*1000, function (){
                /**
                 * 正常用户不会有一秒超过6次的api请求
                 * 做列表记录并清空
                 */
                $list = IpList::getInstance()->accessList(30);
                // var_dump($list);
                IpList::getInstance()->clear();
            });
        }
    };
}

接着我们在OnRequest回调中,判断和统计Ip的访问

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<?php

public static function onRequest(Request $request, Response $response): bool
{
    $fd = $request->getSwooleRequest()->fd;
    $ip = ServerManager::getInstance()->getSwooleServer()->getClientInfo($fd)['remote_ip'];

    // 如果当前周期的访问频率已经超过设置的值,则拦截
    // 测试的时候可以将30改小,比如3
    if (IpList::getInstance()->access($ip) > 30) {
        /**
         * 直接强制关闭连接
         */
        ServerManager::getInstance()->getSwooleServer()->close($fd);
        // 调试输出 可以做逻辑处理
        echo '被拦截'.PHP_EOL;
        return false;
    }
    // 调试输出 可以做逻辑处理
    echo '正常访问'.PHP_EOL;
}

以上就实现了对同一IP访问频率的限制操作。

具体还可以根据自身需求进行扩展,如对具体的某个接口再进行限流。

Easyswoole提供了一个基于Atomic计数器的限流器组件。可以直接使用,使用教程请移步查看限流器文档。

本文原文地址为Easyswoole文档内容 详情地址为 https://www.easyswoole.com/Cn/Passage/SwooleIpLimit.html

本文为北溟有鱼QAQ原创文章,转载无需和我联系,但请注明来自北溟有鱼QAQ https://www.umdzz.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019/07/30 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
swoole如何对ip限制访问频率
在我们开发api的过程中,有的时候我们还需要考虑单个用户(ip)访问频率控制,避免被恶意调用。
宣言言言
2019/12/15
2.5K0
Easyswoole中实现think-template模板引擎使用
本文为北溟有鱼QAQ原创文章,转载无需和我联系,但请注明来自北溟有鱼QAQ https://www.umdzz.cn
北溟有鱼QAQ
2019/12/19
1.2K0
easyswoole的核心文件
<?php /** * Created by PhpStorm. * User: yf * Date: 2018/5/28 * Time: 下午6:07 */ namespace Easy
waki
2021/12/08
6020
Swoole入门到实战(二):进程,内存和协程、Swoole完美支持ThinkPHP5
以树状图显示进程间的关系:pstree -p 进程id 启动成功后会创建worker_num+2个进程。Master进程+Manager进程+serv->worker_num个Worker进程
唐成勇
2019/05/26
1.4K0
EasySwoole中利用redis实现消息队列
本文为北溟有鱼QAQ原创文章,转载无需和我联系,但请注明来自北溟有鱼QAQ https://www.umdzz.cn
北溟有鱼QAQ
2020/02/21
1.4K0
Swoole - webSocket消息服务系统代码设计篇
已经Swoole系列的第二篇知识点了,前一篇主要的针对处理的是方案设计,这一篇主要是代码实现的内容,主要介绍高性能的原因已经实现,编程框架使用EasySwoole。
stark张宇
2023/03/03
9120
swoole学习笔记
swoole是面向生产环境的 PHP 异步网络通信引擎,本笔记是本人在学习完慕课网的课程《Swoole入门到实战打造高性能赛事直播平台》后的笔记,是对学习的代码整理的补充,学习过程中整理的github代码地址:
CS逍遥剑仙
2019/03/03
1.1K0
关于easyswoole实现websocket聊天室的步骤解析
在去年,我们公司内部实现了一个聊天室系统,实现了一个即时在线聊天室功能,可以进行群组,私聊,发图片,文字,语音等功能,那么,这个聊天室是怎么实现的呢?后端又是怎么实现的呢? 后端框架 在后端框架上,
仙士可
2020/02/21
2.7K1
关于easyswoole实现websocket聊天室的步骤解析
手把手教你开发easyswoole 接口网站
基础开发示例已经开源,地址:https://github.com/easy-swoole/demo/tree/3.x
仙士可
2019/12/19
2.4K0
《五》Swoole 多协议 多端口 的应用
Swoole 支持了2种类型的自定义网络通信协议 :EOF结束符协议、固定包头+包体协议。
新亮
2019/05/28
9250
《五》Swoole 多协议 多端口 的应用
PHP物联网开发利器之Actor并发模型
在传统的思维中,经常会有人告诉你,php不适合用来做物联网服务端,让你换java,node,go等其他语言,是的,没错传统意义上的php,确实很难做物联网服务器,因为它实在太蹩脚了,当然,这也不是意味着彻底就不能做。举个例子,当你想实现一个TCP服务器的时候,你可能需要写出原理大约如下的代码:
猿哥
2019/06/14
2.3K1
EasySwoole之链路追踪
来自北溟有鱼QAQ https://www.umdzz.cn
北溟有鱼QAQ
2020/06/30
7440
EasySwoole之链路追踪
swoole入门abc1. 入门abc
分析上面的代码,我们发现会有什么问题?如果两个请求同时进来,都读到了lastTime,没有被拒绝,但是这两个请求本身是已经请求过快了。
zhuanxu
2018/08/23
6570
swoole入门abc1. 入门abc
使用easyswoole进行开发web网站
easyswoole作为swoole入门最简单的框架,其框架的定义就是适合大众php,更好的利用swoole扩展进行开发,
仙士可
2019/12/19
1.7K0
使用easyswoole进行开发web网站
《四》Swoole HTTP 的应用
我们都知道 HTTP 是一种协议,允许 WEB 服务器和浏览器通过互联网进行发送和接受数据。
新亮
2019/05/28
5000
《四》Swoole HTTP 的应用
SWOOLE高性能内存数据库的使用和配置教程
说明 由于 PHP 语言不支持多线程,因此 Swoole 使用多进程模式,在多进程模式下存在进程内存隔离,在工作进程内修改 global 全局变量和超全局变量时,在其他进程是无效的。 对应的解决方案有: 1. 使用Redis数据库、关系型数据库Mysql 2. 内存文件/dev/shm 首先数据库的操作都牵扯到IOD等待时间,因此推荐使用Table
CRMEB商城源码
2022/04/21
7880
详解PHP swoole process的使用方法
引入背景:假如我们每天有10000个订单生成,需要同步到仓储系统中去,以前做法是开启一个crontab去跑这些任务,但是发现总有感觉同步效率低,间隔时间都是分钟级别的。 解决方案测试:我们将同步订单的任务表添加一个hash作为key,作为分发条件,因为mysql中select如果做mod函数是用不到索引的,所以我们自己做随机hash,但是务必不需要范围太大,以免服务器资源不够,方法是根据hashkey投放到不同的进程中进行同步,测试代码如下
用户2323866
2021/07/02
4570
《六》Swoole 整合成一个小框架
写了关于 Swoole 入门的 5 篇文章后,增加了不少的关注者,也得到了一些大佬的鼓励和建议,也有很多关注者都加了微信好友,交流之后发现一些朋友比我优秀还比我努力。
新亮
2019/05/28
6330
《六》Swoole 整合成一个小框架
【Swoole系列3.6】进程同步与共享内存
通过前面几篇的学习,相信你已经对 Swoole 的进程有了一定的了解。不管是单进程还是进程池,我们都着重讲了进程间的通讯问题。毕竟对于进程来说,它们是内存隔离的,通讯相对来说就是一个很大的问题。而我们之前讲的内容其实都是不使用第三方工具来进行通信的,但其实更方便的方式是直接使用一些第三方工具做为中间的存储媒介,让不同的进程直接去读取这里的内容就可以实现通信的能力了。比如说我们最常见的就是使用 Redis ,不过即使是 Redis ,甚至是使用了连接池,也会有连接建立的过程,所以也并不是最高效的。今天,我们要学习的一个共享内存表格,是 Swoole 提供的一种更高效的数据同步方式。除此之外,我们还要学习另外两个非常常用的进程间同步功能,一个是无锁计数器,另一个就是进程锁。
硬核项目经理
2023/03/03
6800
【Swoole系列3.6】进程同步与共享内存
《三》Swoole WebSocket 的应用
WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。
新亮
2019/05/28
9060
《三》Swoole WebSocket 的应用
相关推荐
swoole如何对ip限制访问频率
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档