百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

限流 Redis list 列表 Lpush rpop 实现令牌桶 – PHP 实例

mhr18 2024-12-01 09:07 18 浏览 0 评论

令牌桶限流介绍

令牌桶算法 (Token Bucket) 和 Leaky Bucket 效果一样但方向相反的算法,更加容易理解。
随着时间流逝,系统会按恒定 1/QPS 时间间隔 (如果 QPS=100, 则间隔是 10ms) 往桶里加入 Token (想象和漏洞漏水相反,有个水龙头在不断的加水), 如果桶已经满了就不再加了。
新请求来临时,会各自拿走一个 Token, 如果没有 Token 可拿了就阻塞或者拒绝服务.

  • 令牌桶的另外一个好处是可以方便的改变速度。
  • 一旦需要提高速率,则按需提高放入桶中的令牌的速率。
  • 一般会定时 (比如 1000 毫秒) 往桶中增加一定数量的令牌,有些变种算法则实时的计算应该增加的令牌的数量.

父类

<?php

namespace common\components;

use Yii;

use yii\redis\Connection;

/**

* 令牌桶 - 限流

*

* 令牌桶算法 (Token Bucket) 和 Leaky Bucket 效果一样但方向相反的算法,更加容易理解。

* 随着时间流逝,系统会按恒定 1/QPS 时间间隔 (如果 QPS=100, 则间隔是 10ms) 往桶里加入 Token (想象和漏洞漏水相反,有个水龙头在不断的加水), 如果桶已经满了就不再加了。

* 新请求来临时,会各自拿走一个 Token, 如果没有 Token 可拿了就阻塞或者拒绝服务.

*

* 令牌桶的另外一个好处是可以方便的改变速度。

* 一旦需要提高速率,则按需提高放入桶中的令牌的速率。

* 一般会定时 (比如 1000 毫秒) 往桶中增加一定数量的令牌,有些变种算法则实时的计算应该增加的令牌的数量.

*

* Class TrafficShaper

* @package common\components

*/

class TrafficShaper

{

/**

* 令牌桶

*

* @var string

*/

public $container;

/**

* 最大令牌数

*

* @var int

*/

public $max;

/**

* @var Connection

*/

protected $redis;

/**

* TrafficShaper constructor.

* @param int $max

* @param string $container

*/

public function __construct($max = 300, $container = 'container')

{

$this->redis = Yii::$app->redis;

$this->max = $max;

$this->container = $container;

}

/**

* 加入令牌

*

* 注意:需要加入定时任务,定时增加令牌数量

*

* @param int $num 加入的令牌数量

* @return int 加入的数量

*/

public function add($num = 0)

{

// 当前剩余令牌数

$curnum = intval($this->redis->llen($this->container));

// 最大令牌数

$maxnum = intval($this->max);

// 计算最大可加入的令牌数量,不能超过最大令牌数

$num = $maxnum >= $curnum + $num ? $num : $maxnum - $curnum;

// 加入令牌

if ($num > 0) {

$token = array_fill(0, $num, 1);

$this->redis->lpush($this->container, ...$token);

return $num;

}

return 0;

}

/**

* 获取令牌

*

* @return bool

*/

public function get()

{

return $this->redis->rpop($this->container) ? true : false;

}

/**

* 重设令牌桶,填满令牌

*/

public function reset()

{

$this->redis->lrem($this->container, 0, $this->max);

$this->add($this->max);

}

}

调用实例

添加令牌

/**

* 添加令牌数量

*/

public function add()

{

// 默认最大添加数量为300

$trafficShaper = new TrafficShaper(300);

$trafficShaper->add(50);

}

请求过快

$trafficShaper = new TrafficShaper();

if (!$trafficShaper->get()) {

throw new TooManyRequestsHttpException('请求过快');

}

转载地址:https://my.oschina.net/owenzhang24/blog/5495382

相关推荐

Manus放开注册,但Flowith才是Agent领域真正的yyds

大家好,我是运营黑客。前天,AIAgent领域的当红炸子鸡—Manus宣布全面放开注册,终于,不需要邀请码就能体验了。于是,赶紧找了个小号去确认一下。然后,额……就被墙在了外面。官方解释:中文版...

歌浓酒庄总酿酒师:我们有最好的葡萄园和最棒的酿酒师

中新网1月23日电1月18日,张裕董事长周洪江及总经理孙健一行在澳大利亚阿德莱德,完成了歌浓酒庄股权交割签约仪式,这也意味着张裕全球布局基本成型。歌浓:澳大利亚年度最佳酒庄据悉,此次张裕收购的...

软件测试进阶之自动化测试——python+appium实例

扼要:1、了解python+appium进行APP的自动化测试实例;2、能根据实例进行实训操作;本课程主要讲述用python+appium对APP进行UI自动化测试的例子。appium支持Androi...

为什么说Python是最伟大的语言?看图就知道了

来源:麦叔编程作者:麦叔测试一下你的分析能力,直接上图,自己判断一下为什么Python是最好的语言?1.有图有真相Java之父-JamesGoshlingC++之父-BjarneStrou...

如何在Eclipse中配置Python开发环境?

Eclipse是著名的跨平台集成开发环境(IDE),最初主要用来Java语言开发。但是我们通过安装不同的插件Eclipse可以支持不同的计算机语言。比如说,我们可以通过安装PyDev插件,使Eclip...

联合国岗位上新啦(联合国的岗位)

联合国人权事务高级专员办事处PostingTitleIntern-HumanRightsDutyStationBANGKOKDeadlineOct7,2025CategoryandL...

一周安全漫谈丨工信部:拟定超1亿条一般数据泄露属后果严重情节

工信部:拟定超1亿条一般数据泄露属后果严重情节11月23日,工信部官网公布《工业和信息化领域数据安全行政处罚裁量指引(试行)(征求意见稿)》。《裁量指引》征求意见稿明确了行政处罚由违法行为发生地管辖、...

oracle列转行以及C#执行语句时报错问题

oracle列转行的关键字:UNPIVOT,经常查到的怎么样转一列,多列怎么转呢,直接上代码(sshwomeyourcode):SELECTsee_no,diag_no,diag_code,...

力控工业实时历史数据库软件pSpace,支持OPC/UA数据接口

在工业领域中,实时数据库处于企业管理层与现场控制层的桥梁位置,承担着生产数据上传下达的职责。力控企业级实时历史数据库pSpace凭借独特的“接口矩阵”技术,实现了与PLC、DCS、仪器仪表等端设备的向...

机房硬件设备及Oracle数据库软件维护服务项目竞争性磋商公告

图片来自:https://www.gxzbcg.cn/class1/226093.html

LabVIEW实现Oracle数据库的访问(labview oracle)

1.安装Oracle客户端下载:从Oracle官方网站下载适用于Windows操作系统的Oracle驱动程序。确保下载的版本与LabVIEW环境和操作系统兼容。1)以Windo...

【Docker 新手入门指南】附:Windows系统安装Docker

一、Windows10/11安装(推荐DockerDesktop)1.系统要求操作系统:仅支持Windows10/11专业版、企业版、教育版或家庭版(需开启WSL2)。硬件要求...

【Windows篇】告别误操作:简单几步隐藏Windows关机按钮

前言最近小编遇到客户想要将VirtualBox发布为虚拟应用供用户使用,但是遇到了问题,就是安装好VirtualBox无法打开虚拟机,打开提示报错。如图:客户是在vSphere虚拟化环境中安装的Win...

PL/SQL 杂谈(七)(pl/sql相关知识)

承接(六)。今天来聊聊SQL*Plus中的异常处理。SQL*Plus表达运行成功的方式与命令的种类相关。对于大多数SQL*Plus独有的命令,如果没有返回错误信息,那么就表示运行成功。另一方面...

PL/SQL 杂谈(四)(pl sql怎么使用)

承接(三)。晚上在家闲来没事,这次我们来聊一聊关于创建和运行PL/SQL代码的的一些建议。假设一个PL/SQL程序员从来没考虑过诸如系统设计或者单元测试这样的任务,那么他至少应该熟悉下面这些操作...

取消回复欢迎 发表评论: