令牌桶算法PHP简单实现,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);

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值