php 基于redis使用令牌桶算法 计数器 漏桶算法 实现流量控制
通常在高并发和大流量的情况下,一般限流是必须的。为了保证服务器正常的压力。那我们就聊一下几种限流的算法。
- 计数器
计数器是一种最常用的一种方法,在一段时间间隔内,处理请求的数量固定的,超的就不做处理。
demo
public function SpeedCounter()
{
$redis = new \Redis();
$redis->connect('127.0.0.1', 6379);
// 最大请求数量
$maxCount = 100;
//每分钟内,一个用户只能访问10次
$interval =60;
//请求总数量
$zcount = $redis->incr('zcont');
//判断是否超过最大值
if ($zcount<=$maxCount) {
//业务处理
$user = [
11,21,31,41,51,61
];
foreach ($user as $val) {
$key = $val;
$check = $redis->exists($key);
if ($check) {
$sum = $redis->incr($key);
if ($sum<=5){
//业务处理
echo "每个用户在规定的时间内只能访问5次 $sum";
} else {
echo "你已经购买过 $sum";
}
} else {
//print_r($redis->get($key)) ;
///请购买
echo "请购买";
$sum = $redis->incr($key);
$redis->Expire($key,$interval);
}
}
} else {
//超过请求数量
$redis->Expire('zcont',$interval);
echo '超出请求'.$zcount;
}
- 漏桶算法
漏桶的大小是固定的,处理速度也是固定的,但是请求的速率的不固定的。在突发的情况下,会丢弃很多请求。
/**
* **漏桶的大小是固定的,处理速度也是固定的,但是请求的速率的不固定的。在突发的情况下,会丢弃很多请求。**
*/
function LeackBucket() {
$redis = new \Redis();
$redis->connect('127.0.0.1', 6379);
//桶的容量
$maxCount = 1000;
//时间
$interval = 10;
//每分钟流出的数量
$speed = 20;
//用户
$time = $redis->time();
$key = $time[0].$time[1];
//时间判断
//$redis->del('outCount');
$check = $redis->exists('outCount');
// echo $check;
if ($check){
//出桶的速率的请求数量
$outCount = $redis->incr('outCount');
if ($outCount<=$speed){
//业务处理
echo "规定的时间内只能访问20次 $outCount";
} else {
echo "你已经超过每分钟的访问 $outCount";
}
} else {
$outCount = $redis->incr('outCount');
// echo $outCount;
$redis->Expire('outCount',$interval);
echo "时间过了";exit;
}
}
- 令牌桶
令牌桶算法(Token Bucket)和 Leaky Bucket 效果一样但方向相反的算法,更加容易理解.随着时间流逝,系统会按恒定1/QPS时间间隔(如果QPS=100,则间隔是10ms)往桶里加入Token(想象和漏洞漏水相反,有个水龙头在不断的加水),如果桶已经满了就不再加了.新请求来临时,会各自拿走一个Token,如果没有Token可拿了就阻塞或者拒绝服务.
令牌桶的另外一个好处是可以方便的改变速度. 一旦需要提高速率,则按需提高放入桶中的令牌的速率. 一般会定时(比如100毫秒)往桶中增加一定数量的令牌, 有些变种算法则实时的计算应该增加的令牌的数量.
/**
* 令牌
*/
function TrafficShaper(){
$redis = new \Redis();
$redis->pconnect('127.0.0.1', 6379);
//桶的容量
$maxCount = 10;
//当前容量
$curnum = $maxCount-$redis->get('token')-1;
echo $curnum;
if ($curnum>0){
//业务逻辑
//成功后
$token = $redis->incr('token');
echo "===$token";
} else {
echo "没有令牌了";
$redis->set('token',0);
}
}
php 基于redis使用令牌桶算法 计数器 漏桶算法 实现流量控制的更多相关文章
- coding++:RateLimiter 限流算法之漏桶算法、令牌桶算法--简介
RateLimiter是Guava的concurrent包下的一个用于限制访问频率的类 <dependency> <groupId>com.google.guava</g ...
- 基于redis实现的四种常见的限流策略
引言 在web开发中功能是基石,除了功能以外运维和防护就是重头菜了.因为在网站运行期间可能会因为突然的访问量导致业务异常.也有可能遭受别人恶意攻击 所以我们的接口需要对流量进行限制.俗称的QPS也是对 ...
- ASP.NET Core中使用漏桶算法限流
漏桶算法是限流的四大主流算法之一,其应用场景各种资料中介绍的不多,一般都是说应用在网络流量控制中.这里举两个例子: 1.目前家庭上网都会限制一个固定的带宽,比如100M.200M等,一栋楼有很多的用户 ...
- 漏桶、令牌桶限流的Go语言实现
限流 限流又称为流量控制(流控),通常是指限制到达系统的并发请求数. 我们生活中也会经常遇到限流的场景,比如:某景区限制每日进入景区的游客数量为8万人:沙河地铁站早高峰通过站外排队逐一放行的方式限制同 ...
- Sentinel限流之快速失败和漏桶算法
距离上次总结Sentinel的滑动窗口算法已经有些时间了,原本想着一口气将它的core模块全部总结完,但是中间一懒就又松懈下来了,这几天在工作之余又重新整理了一下,在这里做一个学习总结. 上篇滑动窗口 ...
- 使用Redis实现令牌桶算法
在限流算法中有一种令牌桶算法,该算法可以应对短暂的突发流量,这对于现实环境中流量不怎么均匀的情况特别有用,不会频繁的触发限流,对调用方比较友好. 例如,当前限制10qps,大多数情况下不会超过此数量, ...
- 基于Redis的分布式锁和Redlock算法
1 前言 前面写了4篇Redis底层实现和工程架构相关文章,感兴趣的读者可以回顾一下: Redis面试热点之底层实现篇-1 Redis面试热点之底层实现篇-2 Redis面试热点之工程架构篇-1 Re ...
- php 基于redis计数器类
本文引自网络 Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API. 本文将使用其incr(自增),get(获取), ...
- 身为一枚优秀的程序员必备的基于Redis的分布式锁和Redlock算法
1 前言 今天开始来和大家一起学习一下Redis实际应用篇,会写几个Redis的常见应用. 在我看来Redis最为典型的应用就是作为分布式缓存系统,其他的一些应用本质上并不是杀手锏功能,是基于Redi ...
随机推荐
- Hutool :一个小而全的 Java 工具类库
Hutool 简介 Hutool 是一个小而全的 Java 工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式语言般的优雅,让Java语言也可以"甜甜的 ...
- SystemVerilog 语言部分(二)
接口interface: 既可以设计,也可以用来验证. 验证环境:interface使得连接变得简单不容易出错. interface可以定义端口,单双向信号,内控部使用initial always t ...
- Go语言web开发---Beego的session
一.简介 Session是一段保存在服务器上的信息,当客户端第一次访问服务器时创建Session,同时也会创建一个名为beegosessionID,值为创建的Session的id的Cookie. 这个 ...
- camera中LENS和SENSOR的CRA是如何搭配的?
camera中LENS和SENSOR的CRA是如何搭配的? camera中,lens和sensor的搭配是非常关键的问题.但这两者是如何搭配的呢? 一般在Sensor data sheet中会附有全视 ...
- BEP 7:CUDA外部内存管理插件(上)
BEP 7:CUDA外部内存管理插件(上) 背景和目标 在CUDA阵列接口使得能够共享不同的Python之间的数据库的访问CUDA设备.但是,每个库都与其它库区别对待.例如: Numba在内部管理内存 ...
- python_pycham,连接数据库,执行sql
本地搭建的mysql的新建的表的数据如下: 在pycham中连接mysql 执行sql ,举例编写如下: import pymysql if __name__ == '__main__': conn ...
- 重新整理 .net core 实践篇—————日志系统之作用域[十七]
前言 前面介绍了服务与日志之间的配置,那么我们服务会遇到下面的场景会被遇到一些打log的问题. 前面我提及到我们的log,其实是在一个队列里面,而我们的请求是在并发的,多个用户同时发送请求这个时候我们 ...
- SQL注入问题------JDBC编写简单登录代码
一.什么是sql注入 sql注入:用户输入的内容, 有一些sql的特殊关键字参与字符串的拼接,完成了一条逻辑发生变化的新的SQL语句 !用代码举个例子简单说明一下: package cn.zhbit. ...
- 一文带你了解.Net自旋锁
本文主要讲解.Net基于Thread实现自旋锁的三种方式 基于Thread.SpinWait实现自旋锁 实现原理:基于Test--And--Set原子操作实现 使用一个数据表示当前锁是否已经被获取 0 ...
- 基于Colab Pro & Google Drive的Kaggle实战
原文:https://hippocampus-garden.com/kaggle_colab/ 原文标题:How to Kaggle with Colab Pro & Google Drive ...