How to implement token bucket current limiting in PHP
PHP method to implement token bucket current limiting: 1. Set up a token bucket and store tokens in the bucket; 2. Take a token from the bucket for each visit; 3. According to the actual situation , just put in a few tokens every once in a while or just fill up the token bucket directly.
#The operating environment of this article: Windows7 system, PHP7.1, Dell G3 computer.
How does PHP implement token bucket current limiting?
php uses token bucket algorithm to implement flow control based on redis
##This article introduces PHP based on redis and uses the token bucket algorithm to control access traffic. It provides a complete algorithm description and demonstration examples for everyone to learn and use. Whenever there are long domestic holidays or important festivals, domestic scenic spots or subways will be crowded with people, resulting in excessive load. Some will adopt flow limiting measures to limit the number of people entering. When the number of people in the area is reduced to a certain value , and then allow entry.For example: The maximum number of people allowed in the area is
M The current number of people in the area is
N Every entry One person,
N 1, when N = M, is not allowed to enter Every time a person leaves,
N-1, when When N < Overloaded with work. Of course we can add servers to share the pressure. First of all, adding servers also takes a certain amount of time to configure, and if servers are added because of a certain activity, these server resources will be wasted after the activity is over.
Therefore, we can first use
current limiting
to reduce server pressure according to the business type. Different from the traffic limit in scenic spots, the time from visit to end of the system is very short, so we only need to know the average duration of each visit and set the maximum number of simultaneous visitors. .
Token Bucket Algorithm
1. First, there is a token bucket, and tokens are stored in the bucket. At the beginning, the tokens in the token bucket are full (the bucket The number of tokens can be set according to server conditions).
2. Each visit takes a token from the bucket. When the token in the bucket is 0, no further visits are allowed.
3. Every once in a while, add tokens until the bucket is full of tokens. (You can put in several tokens at regular intervals according to the actual situation, or directly fill up the token bucket)
We can use the queue of
redisas the token bucket container, Use
lPush (enqueue), rPop (dequeue) to implement token addition and consumption operations. TrafficShaper.class.php<?php
/**
* PHP基于Redis使用令牌桶算法实现流量控制
* Date: 2018-02-23
* Author: fdipzone
* Version: 1.0
*
* Descripton:
* php基于Redis使用令牌桶算法实现流量控制,使用redis的队列作为令牌桶容器,入队(lPush)出队(rPop)作为令牌的加入与消耗操作。
*
* Func:
* public add 加入令牌
* public get 获取令牌
* public reset 重设令牌桶
* private connect 创建redis连接
*/class TrafficShaper{ // class start
private $_config; // redis设定
private $_redis; // redis对象
private $_queue; // 令牌桶
private $_max; // 最大令牌数
/**
* 初始化
* @param Array $config redis连接设定
*/
public function __construct($config, $queue, $max){
$this->_config = $config; $this->_queue = $queue; $this->_max = $max; $this->_redis = $this->connect();
} /**
* 加入令牌
* @param Int $num 加入的令牌数量
* @return Int 加入的数量
*/
public function add($num=0){
// 当前剩余令牌数
$curnum = intval($this->_redis->lSize($this->_queue)); // 最大令牌数
$maxnum = intval($this->_max); // 计算最大可加入的令牌数量,不能超过最大令牌数
$num = $maxnum>=$curnum+$num? $num : $maxnum-$curnum; // 加入令牌
if($num>0){ $token = array_fill(0, $num, 1); $this->_redis->lPush($this->_queue, ...$token); return $num;
} return 0;
} /**
* 获取令牌
* @return Boolean
*/
public function get(){
return $this->_redis->rPop($this->_queue)? true : false;
} /**
* 重设令牌桶,填满令牌
*/
public function reset(){
$this->_redis->delete($this->_queue); $this->add($this->_max);
} /**
* 创建redis连接
* @return Link
*/
private function connect(){
try{ $redis = new Redis(); $redis->connect($this->_config['host'],$this->_config['port'],$this->_config['timeout'],$this->_config['reserved'],$this->_config['retry_interval']); if(empty($this->_config['auth'])){ $redis->auth($this->_config['auth']);
} $redis->select($this->_config['index']);
}catch(RedisException $e){ throw new Exception($e->getMessage()); return false;
} return $redis;
}
} // class end?>
<?php
/**
* 演示令牌加入与消耗
*/
require 'TrafficShaper.class.php';
// redis连接设定
$config = array(
'host' => 'localhost',
'port' => 6379,
'index' => 0,
'auth' => '',
'timeout' => 1,
'reserved' => NULL,
'retry_interval' => 100,
);
// 令牌桶容器
$queue = 'mycontainer';
// 最大令牌数
$max = 5;
// 创建TrafficShaper对象
$oTrafficShaper = new TrafficShaper($config, $queue, $max);
// 重设令牌桶,填满令牌
$oTrafficShaper->reset();
// 循环获取令牌,令牌桶内只有5个令牌,因此最后3次获取失败
for($i=0; $i<8; $i++){
var_dump($oTrafficShaper->get());
}
// 加入10个令牌,最大令牌为5,因此只能加入5个
$add_num = $oTrafficShaper->add(10);
var_dump($add_num);
// 循环获取令牌,令牌桶内只有5个令牌,因此最后1次获取失败
for($i=0; $i<6; $i++){
var_dump($oTrafficShaper->get());
}
?>
boolean true boolean true boolean true boolean true boolean true boolean false boolean false boolean false int 5 boolean true boolean true boolean true boolean true boolean true boolean false
Regularly adding token algorithmRegularly adding tokens, we can use crontab to implement it, and call the add method to add several tokens every minute.
The minimum execution interval of crontab is 1 minute. If the tokens in the token bucket have been consumed in the first few seconds, then the tokens will not be obtained in the remaining tens of seconds. This causes users to wait longer.
We can optimize the algorithm for adding tokens and add several tokens every few seconds within a minute. This can ensure that there is a chance to obtain tokens every time within a minute.
The token joining program called by crontab is as follows, automatically adding 3 tokens per second.<?php /** * 定时任务加入令牌 */ require 'TrafficShaper.class.php'; // redis连接设定 $config = array( 'host' => 'localhost', 'port' => 6379, 'index' => 0, 'auth' => '', 'timeout' => 1, 'reserved' => NULL, 'retry_interval' => 100, ); // 令牌桶容器 $queue = 'mycontainer'; // 最大令牌数 $max = 10; // 每次时间间隔加入的令牌数 $token_num = 3; // 时间间隔,最好是能被60整除的数,保证覆盖每一分钟内所有的时间 $time_step = 1; // 执行次数 $exec_num = (int)(60/$time_step); // 创建TrafficShaper对象 $oTrafficShaper = new TrafficShaper($config, $queue, $max); for($i=0; $i<$exec_num; $i++){ $add_num = $oTrafficShaper->add($token_num); echo '['.date('Y-m-d H:i:s').'] add token num:'.$add_num.PHP_EOL; sleep($time_step); } ?>
The simulation consumption program is as follows, consuming 2-8 tokens per second.
<?php /** * 模拟用户访问消耗令牌,每段时间间隔消耗若干令牌 */ require 'TrafficShaper.class.php'; // redis连接设定 $config = array( 'host' => 'localhost', 'port' => 6379, 'index' => 0, 'auth' => '', 'timeout' => 1, 'reserved' => NULL, 'retry_interval' => 100, ); // 令牌桶容器 $queue = 'mycontainer'; // 最大令牌数 $max = 10; // 每次时间间隔随机消耗的令牌数量范围 $consume_token_range = array(2, 8); // 时间间隔 $time_step = 1; // 创建TrafficShaper对象 $oTrafficShaper = new TrafficShaper($config, $queue, $max); // 重设令牌桶,填满令牌 $oTrafficShaper->reset(); // 执行令牌消耗 while(true){ $consume_num = mt_rand($consume_token_range[0], $consume_token_range[1]); for($i=0; $i<$consume_num; $i++){ $status = $oTrafficShaper->get(); echo '['.date('Y-m-d H:i:s').'] consume token:'.($status? 'true' : 'false').PHP_EOL; } sleep($time_step); } ?>
Demonstration
Set a scheduled task and execute it once every minute* * * * * php /程序的路径/cron_add.php >> /tmp/cron_add.log
php consume_demo.php
Execution results :
[2018-02-23 11:42:57] consume token:true [2018-02-23 11:42:57] consume token:true [2018-02-23 11:42:57] consume token:true [2018-02-23 11:42:57] consume token:true [2018-02-23 11:42:57] consume token:true [2018-02-23 11:42:57] consume token:true [2018-02-23 11:42:57] consume token:true [2018-02-23 11:42:58] consume token:true [2018-02-23 11:42:58] consume token:true [2018-02-23 11:42:58] consume token:true [2018-02-23 11:42:58] consume token:true [2018-02-23 11:42:58] consume token:true [2018-02-23 11:42:58] consume token:true [2018-02-23 11:42:58] consume token:false [2018-02-23 11:42:59] consume token:true [2018-02-23 11:42:59] consume token:true [2018-02-23 11:42:59] consume token:true [2018-02-23 11:42:59] consume token:false [2018-02-23 11:42:59] consume token:false [2018-02-23 11:42:59] consume token:false [2018-02-23 11:42:59] consume token:false [2018-02-23 11:43:00] consume token:true [2018-02-23 11:43:00] consume token:true [2018-02-23 11:43:00] consume token:true [2018-02-23 11:43:00] consume token:false [2018-02-23 11:43:00] consume token:false
Because the token bucket is full at the beginning (the maximum number of tokens is 10), tokens can be obtained in the first 10 times. After 10 times, the tokens consumed will be greater than the joining token. When the number of cards is exceeded, access is restricted.
Recommended study: "PHP Video Tutorial
"
The above is the detailed content of How to implement token bucket current limiting in PHP. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

PHP 8.4 brings several new features, security improvements, and performance improvements with healthy amounts of feature deprecations and removals. This guide explains how to install PHP 8.4 or upgrade to PHP 8.4 on Ubuntu, Debian, or their derivati

If you are an experienced PHP developer, you might have the feeling that you’ve been there and done that already.You have developed a significant number of applications, debugged millions of lines of code, and tweaked a bunch of scripts to achieve op

Visual Studio Code, also known as VS Code, is a free source code editor — or integrated development environment (IDE) — available for all major operating systems. With a large collection of extensions for many programming languages, VS Code can be c

JWT is an open standard based on JSON, used to securely transmit information between parties, mainly for identity authentication and information exchange. 1. JWT consists of three parts: Header, Payload and Signature. 2. The working principle of JWT includes three steps: generating JWT, verifying JWT and parsing Payload. 3. When using JWT for authentication in PHP, JWT can be generated and verified, and user role and permission information can be included in advanced usage. 4. Common errors include signature verification failure, token expiration, and payload oversized. Debugging skills include using debugging tools and logging. 5. Performance optimization and best practices include using appropriate signature algorithms, setting validity periods reasonably,

A string is a sequence of characters, including letters, numbers, and symbols. This tutorial will learn how to calculate the number of vowels in a given string in PHP using different methods. The vowels in English are a, e, i, o, u, and they can be uppercase or lowercase. What is a vowel? Vowels are alphabetic characters that represent a specific pronunciation. There are five vowels in English, including uppercase and lowercase: a, e, i, o, u Example 1 Input: String = "Tutorialspoint" Output: 6 explain The vowels in the string "Tutorialspoint" are u, o, i, a, o, i. There are 6 yuan in total

This tutorial demonstrates how to efficiently process XML documents using PHP. XML (eXtensible Markup Language) is a versatile text-based markup language designed for both human readability and machine parsing. It's commonly used for data storage an

Static binding (static::) implements late static binding (LSB) in PHP, allowing calling classes to be referenced in static contexts rather than defining classes. 1) The parsing process is performed at runtime, 2) Look up the call class in the inheritance relationship, 3) It may bring performance overhead.

What are the magic methods of PHP? PHP's magic methods include: 1.\_\_construct, used to initialize objects; 2.\_\_destruct, used to clean up resources; 3.\_\_call, handle non-existent method calls; 4.\_\_get, implement dynamic attribute access; 5.\_\_set, implement dynamic attribute settings. These methods are automatically called in certain situations, improving code flexibility and efficiency.
