通常在高并发和大流量的情况下,一般限流是必须的。为了保证服务器正常的压力。那我们就聊一下几种限流的算法。

  1. 计数器
    计数器是一种最常用的一种方法,在一段时间间隔内,处理请求的数量固定的,超的就不做处理。

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; }
  1. 漏桶算法

漏桶的大小是固定的,处理速度也是固定的,但是请求的速率的不固定的。在突发的情况下,会丢弃很多请求。

 /**
* **漏桶的大小是固定的,处理速度也是固定的,但是请求的速率的不固定的。在突发的情况下,会丢弃很多请求。**
*/
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;
} }
  1. 令牌桶
    令牌桶算法(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);
} }

最新文章

  1. [Android]快捷键
  2. mysql的enum和set数据类型
  3. iOS开发-UI 从入门到精通(五)
  4. Elasticsearch常用配置及性能参数
  5. javaweb -- 获取请求IP(附实现源码)
  6. 给dos命令“.bat”文件换图标
  7. 【Oracle】Oracle 11g 64位安装完后,ora-12541错误和ora-12514错误的解决
  8. Reverse Nodes in k-Group [LeetCode]
  9. 内存映射 madvise mmap
  10. 【DP_树形DP专题】题单总结
  11. IIS Shared Configuration
  12. Delphi 用Web App Debugger简单调试ISAPI 转
  13. jsp页面适应手机页面
  14. mysql(4)—— 表连接查询与where后使用子查询的性能分析。
  15. SSD trim及4k对齐
  16. 论文笔记——An online EEG-based brain-computer interface for controlling hand grasp using an adaptive probabilistic neural network(10年被引用66次)
  17. 11-jQuery的事件绑定和解绑
  18. python zeros用法实例
  19. (办公)百度api的使用
  20. swift - UIImageView 的使用

热门文章

  1. python文件处理(对比和筛选)
  2. Docker之tomcat安装与部署项目
  3. 详述盒子模型(包含padding、border、margin的详细用法和描述)
  4. Mysql索引数据结构为什么是B+树?
  5. Docker学习(13) Docker容器的网络连接
  6. 常用正则表达式RE(慕课网_Meshare_huang)
  7. ADAS摄像头图像环视拼接算法
  8. Paddle概述
  9. MLPerf Inference 0.7应用
  10. jvm调优的几种场景