限流 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程序员从来没考虑过诸如系统设计或者单元测试这样的任务,那么他至少应该熟悉下面这些操作...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- oracle位图索引 (74)
- oracle批量插入数据 (65)
- oracle事务隔离级别 (59)
- oracle 空为0 (51)
- oracle主从同步 (56)
- oracle 乐观锁 (53)
- redis 命令 (78)
- php redis (88)
- redis 存储 (66)
- redis 锁 (69)
- 启动 redis (66)
- redis 时间 (56)
- redis 删除 (67)
- redis内存 (57)
- redis并发 (52)
- redis 主从 (69)
- redis 订阅 (51)
- redis 登录 (54)
- redis 面试 (58)
- 阿里 redis (59)
- redis 搭建 (53)
- redis的缓存 (55)
- lua redis (58)
- redis 连接池 (61)
- redis 限流 (51)