前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >workerman基于Lua脚本Redis限流令牌桶中间件实例

workerman基于Lua脚本Redis限流令牌桶中间件实例

原创
作者头像
OwenZhang
发布于 2022-05-30 07:10:58
发布于 2022-05-30 07:10:58
5100
举报
文章被收录于专栏:Owen's WorldOwen's World

本文环境 CentOS8.0,PHP8.1,Nginx1.8,Workerman 4.0\ 不懂的可以评论联系我。 著作权归OwenZhang所有。商业转载请联系OwenZhang获得授权,非商业转载请注明出处。

简要

为防止滥用,你应该考虑对您的 API 限流。 例如,您可以限制每个用户 10 分钟内最多调用 API 100 次。 如果在规定的时间内接收了一个用户大量的请求,将返回响应状态代码 429 (这意味着过多的请求)。

workerman介绍

Workerman是一款纯PHP开发的开源高性能的PHP 应用容器

Workerman不是重复造轮子,它不是一个MVC框架,而是一个更底层更通用的服务框架,你可以用它开发tcp代理、梯子代理、做游戏服务器、邮件服务器、ftp服务器、甚至开发一个php版本的redis、php版本的数据库、php版本的nginx、php版本的php-fpm等等。Workerman可以说是PHP领域的一次创新,让开发者彻底摆脱了PHP只能做WEB的束缚。

实际上Workerman类似一个PHP版本的nginx,核心也是多进程+Epoll+非阻塞IO。Workerman每个进程能维持上万并发连接。由于本身常驻内存,不依赖Apache、nginx、php-fpm这些容器,拥有超高的性能。同时支持TCP、UDP、UNIXSOCKET,支持长连接,支持Websocket、HTTP、WSS、HTTPS等通讯协议以及各种自定义协议。拥有定时器、异步socket客户端、异步Redis、异步Http、异步消息队列等众多高性能组件。

在原作者的基础上做的修改

原地址:

https://www.workerman.net/plugin/37

https://github.com/Tinywan/webman-limit-traffic

方便不需要安装composer扩展,哈哈,但还是支持原作者!

代码实例

config/middleware.php

代码语言:txt
复制
\app\middleware\LimitTraffic::class,//令牌桶限流

app/middleware/LimitTraffic.php

代码语言:txt
复制
<?php
/**
 * Programmer: Owen Zhang
 * Email: owen@owenzhang.com
 * Start Date: 05/15/22
 * Last Update: 05 15, 2022 [OZ]
 * Functions:
 * 基于 Lua 脚本简单限流令牌桶,应用接口服务限流工具
 * 在原作者的基础上做的修改
 * 原地址:
 *      https://www.workerman.net/plugin/37
 *      https://github.com/Tinywan/webman-limit-traffic
 */

namespace app\middleware;

use app\common\ApiStatus;
use Webman\MiddlewareInterface;
use Webman\Http\Response;
use Webman\Http\Request;
use support\Redis;

class LimitTraffic implements MiddlewareInterface
{
    public const LIMIT_TRAFFIC_SCRIPT_SHA = 'limit:traffic:script';
    public const LIMIT_TRAFFIC_PRE        = 'limit:traffic:pre:';

    public function process(Request $request, callable $next): Response
    {
        if ($result = $this->traffic()) {
            return new Response($result['status'], [
                'Content-Type' => 'application/json',
            ], json_encode($result['body']));
        }
        return $next($request);
    }

    /**
     * 校测
     *
     * @return array|false
     */
    public function traffic()
    {
        $config    = $this->getRateLimit();
        $scriptSha = Redis::get(self::LIMIT_TRAFFIC_SCRIPT_SHA);
        if (!$scriptSha) {
            $script    = <<<luascript
            local result = redis.call('SETNX', KEYS[1], 1);
            if result == 1 then
                return redis.call('expire', KEYS[1], ARGV[2])
            else
                if tonumber(redis.call("GET", KEYS[1])) >= tonumber(ARGV[1]) then
                    return 0
                else
                    return redis.call("INCR", KEYS[1])
                end
            end
luascript;
            $scriptSha = Redis::script('load', $script);
            Redis::set(self::LIMIT_TRAFFIC_SCRIPT_SHA, $scriptSha);
        }
        $limitKey = self::LIMIT_TRAFFIC_PRE . request()->getRealIp(true);
        $result   = Redis::rawCommand('evalsha', $scriptSha, 1, $limitKey, $config['limit'], $config['window_time']);
        if ($result === 0) {
            return [
                'limit'     => $config['limit'],
                'remaining' => $config['limit'] - Redis::get($limitKey),
                'reset'     => Redis::ttl($limitKey),
                'status'    => $config['status'],
                'body'      => $config['body'],
            ];
        }
        return false;
    }

    /**
     * @desc   : 返回允许的请求的最大数目及时间,例如,[100, 600] 表示在 600 秒内最多 100 次的 API 调
     * @author Tinywan(ShaoBo Wan)
     */
    public function getRateLimit(): array
    {
        return [
            'limit'       => 100, // 请求次数
            'window_time' => 5, // 窗口时间,单位:秒
            'status'      => 429,  // HTTP 状态码
            'body'        => [
                // 响应返回的结构信息
                'code' => ApiStatus::API_ERROR->value,
                'msg'  => 'Too Many Requests'
            ],
        ];
    }
}

运行状态

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

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

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

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

评论
登录后参与评论
暂无评论
推荐阅读
SEO网站优化:如何针对内容素材做优化?
在SEO工作中,内容如同的网站的灵魂,它严重影响网站的长期发展,几乎没有任何网站可以脱离内容,而独立存在。
蝙蝠侠IT
2019/07/10
7110
SEO网站优化:如何针对内容素材做优化?
关键词网站优化的四个方法标梵互动
许多搜索引擎优化人员在推广网站时最关心的是写网站标题。总而言之,标题是网站关键词优化的重要组成部分。高质量的网站标题可以为搜索用户提供高水平的内容摘要,使用户对网站内容有清晰的认识。合理设置标题,进一步提高搜索引擎对网页的相关性识别能力。
不知道起啥名
2020/10/20
6000
关键词网站优化的四个方法标梵互动
网站一直优化不动?三大致命因素!
SEO是一个千变万化的工作,你的每一个优化策略,都决定网站不同的走向,在很长一段时期中,我们通常会遇到各种问题,比如:网站一直优化不动。
一墨编程学习
2019/01/03
4700
拢金富挣谈谈:SEO网站优化,网站SEO优化策略与方法
随着互联网时代的不断发展,企业想要扩大宣传范围,就需要利用互联网来宣传自己,只有这样才能让更多的用户通过互联网了解到企业,从而获得更多的流量。而企业想要达到这种效果,就需要做SEO网站优化,把网站关键词优化到搜索引擎的首页,进而达到扩大企业宣传范围的目的。
拢金富挣
2022/04/29
3950
为什么质疑问难,SEO人员需要经常思考?
质疑问难,主要是指在日常工作中,我们应该经常的多邀请同行业的朋友,相互交流与学习,并通过一起讨论得到更加完善的结果。
蝙蝠侠IT
2021/05/14
2760
为什么质疑问难,SEO人员需要经常思考?
个人博客网站数据更新及流量分析
网站经营者都希望发布的重要内容如新产品信息或重要新闻被蜘蛛快速抓取并出现在搜索结果中。但现今我们点击搜索结果中的链接,往往进入后发现内容与结果描述不同,这是因为搜索到的结果是搜索蜘蛛在上次光顾该网站时抓取到的信息,之后该页内容更新,蜘蛛程序却还没有来得及抓取,从而造成的搜索结果与实际内容不符。不过,各搜索引擎都在加快 对网站访问的频率,除了每月一次全面的深度检索,还对频繁更新的网站进行数天甚至每天简单检索一次,以保证搜索结果的时效性。总结起来,Google对网站信息的更新取决于以下因素: 
李洋博客
2021/06/15
8000
个人博客网站数据更新及流量分析
五金企业网站排名,常用的8个流程
我们知道SEO是一门技术,但针对包罗万象的企业而言,各个行业的网站都具有不一样的特点,其中,五金企业网站更多的是侧重在B2B领域。
蝙蝠侠IT
2021/06/02
5560
五金企业网站排名,常用的8个流程
网站优化技巧,值得关注的3个细节
网站优化技巧,是每个SEO人员都在深度研究与讨论的一个话题,但我们知道不同行业的网站优化策略不同,因此,当你长期在一个垂直领域做SEO工作的时候,你的思维可能是局限的,虽然,我们强调网站优化的差异化,但基于搜索引擎工作的原理,一些网站优化技巧是不会轻易改变的。
蝙蝠侠IT
2021/08/19
3580
网站优化技巧,值得关注的3个细节
「入门须知」网站优化过程中都需要做些什么?推荐入门阅读
今天就根据自己的SEO经验与大家分享一下,“网站优化过程中都需要做些什么?”这个问题希望能对刚开始做SEO的SEOer有所帮助。
大脸猫
2019/11/12
5160
「入门须知」网站优化过程中都需要做些什么?推荐入门阅读
网站优化门槛低了还是高了?
自从2015年刚接触网站时,从一无所知到现在无人指导,一直跌跌撞撞走过来,当年花了1500元找了广东一个网友用织梦CMS做了一个门户网站,记得那时一星期没下楼,把网站折腾的千疮百孔,而终逐步熟悉网站建设与搜索引擎优化。
用户11304699
2024/10/09
1010
网站优化门槛低了还是高了?
「进阶篇」网站优化中关键词的选择以及关键词的类别
那么关键词又分为好几种,选择对的关键词对我们网站优化的速度,简直是可以起到事半功倍的作用。
大脸猫
2019/11/13
6630
「进阶篇」网站优化中关键词的选择以及关键词的类别
网站优化SEO新手操作流程汇总
SEO是一个系统的过程,如果你对SEO概念没有很了解,是很难操作的。我们列出有关SEO网站优化操作流程。
你的明明呐丶
2022/06/27
5650
SEO辩论,如何在团队内部可以言之凿凿?
在做SEO的过程中,我们经常会遇到小组讨论,制定下一步决策的时候,但有的时候,每当我们在做相关会议的时候,总是话到嘴边而又嘎然而止,不知道怎么梳理自己的观点,这就在日后自我工作中,增添一定的麻烦,自己的想法很难得到有效的验证。
蝙蝠侠IT
2020/10/26
5600
SEO辩论,如何在团队内部可以言之凿凿?
为什么这些SEO指标,对于企业而言非同小可?
如果你是一个企业网站的网站推广员,在做SEO的道路上,我们经常会总结一些自己的独门秘籍,而实际上,条条大路通罗马,用这句话来形容网站优化,也不为过,特别是对于企业一些非同小可的技术指标,我们一定要全盘掌握。
蝙蝠侠IT
2021/06/09
2970
为什么这些SEO指标,对于企业而言非同小可?
【SEO优化】分析为什么网站优化一年比一年难做的10个原因
现在的网站优化越来越难做了。以前优质的文章加内链、外链搞好网站基本上就有流量了,权重提升的也是很快。但是现在不行了优化不动了。
鸣奔博客
2023/03/23
4980
【SEO优化】分析为什么网站优化一年比一年难做的10个原因
如何优化一个网站的seo结构
如果一个网站做得好,没有搜索,没有流量,没有排名,那么之前的功课都是白费的。而对一个网站进行专业的优化操作,是网站上线后必不可少的操作,关系到用户能否通过搜索与工作相关的关键词找到自己的网站。那么如何通过技能水平来设置SEO呢?然后,让边肖和大家谈谈。从大方向出发,不包括网站设置的优化(如典型的内部链和结构优化、代码优化、页面加载时间优化等)。),网站原创内容的创建,网站外链的推送,改善用户体验的优化。
幻影龙王
2021/09/08
5710
如何优化一个网站的seo结构
网站SEO诊断优化方案
网站SEO诊断是针对网站行业定位、页面展现、用户体验、搜索引擎优化、在行业中竞争性分析、短期规划与长期战略发展对策、目标客户转化等进行的站内和站外的优化操作过程,我首先考虑是否利于搜索引擎搜索优化、是否利于用户浏览、是否有利于友好的交互体验以及是否利于网站关键词排名优化的一种综合优化行为。
竹清
2018/08/31
1.8K0
「网站优化」网站优化不能做的事情——做了等于作弊
网站优化就是我们平时说的“黑帽SEO”,他们就是通过利用搜索漏洞让网站获得更多的流量以及更好的排名。
大脸猫
2019/11/05
6620
「网站优化」网站优化不能做的事情——做了等于作弊
如何做网站优化(SEO优化)
信息化进入到如今,网站已经成为企业所不可或缺的必要配置,更注重企业信息化建设的企业,早已经成立信息部门。不仅仅如此,世界最大的网民国家——中国, 孕育最大的资源与商机,更多的互联网创业及个人站长纷纷瓜分中国互联网大蛋糕的同时,针对于搜索引擎优化(SEO)的话题就从未停止过。如何做网站优化 (SEO优化)已经成为一种学科,在不断的发展及更新中,与搜索引擎相互依存,相互促进。
数据通20847430
2020/04/15
1.2K0
企业网站SEO推广优化方案怎么写?
网站优化的最终目的是为企业带来流量转化和提升品牌知名度。不管是自己做SEO优化,还是给公司或者客户提供SEO服务,良家佐言认为做一份详细的SEO方案,就能起到事半功倍的效果。
茹莱神兽
2022/03/12
1.4K0
企业网站SEO推广优化方案怎么写?
推荐阅读
相关推荐
SEO网站优化:如何针对内容素材做优化?
更多 >
目录
  • 简要
  • workerman介绍
  • 在原作者的基础上做的修改
  • 代码实例
    • config/middleware.php
    • app/middleware/LimitTraffic.php
  • 运行状态
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档