当前位置: 首页 > 后端技术 > PHP

3分钟视频看懂令牌桶算法

时间:2023-03-29 23:29:58 PHP

视频介绍令牌桶,分析令牌桶原理和代码实现https://www.bilibili.com/video...嗨,我是浩刚,这个给大家讲讲令牌桶。首先想象有一个木桶,系统以固定的速率向桶中添加Token,比如每次10ms,桶满了就不再添加。当有新的请求到来时,每一个都会拿走一个Token,如果没有Token,则拒绝服务。这里,如果一段时间内没有请求,桶中就会积累一些令牌。下次有突发流量的时候,只要有足够的token,一次性处理就可以了。总结令牌桶算法的特点,令牌桶在允许突发流量的同时,可以控制进入系统的请求量。在秒杀活动中,用户的请求速率不固定,这里假设为10r/s,令牌以每秒5个的速率放入令牌桶中,桶中最多可存放20个令牌,那么系统只会允许每秒连续处理5个请求,或者每4秒,在桶中的20个令牌满之后,一次处理20个请求的突发情况,以保证系统的稳定性。伪代码实现:rate=5.0;//单位:messagesper=8.0;//单位:secondsallowance=rate;//单位:messageslast_check=now();//浮点数,例如使用精度。单位:secondswhen(message_received):current=now();time_passed=current-last_check;last_check=当前;allowance+=time_passed*(rate/per);if(allowance>rate):allowance=rate;//节流if(allowance<1.0):discard_message();否则:转发消息();津贴-=1.0;令牌传递算法PHP实现//speedbucketsize/timeperiod$rate=$maxRequests/$period;$t_key=$keyTime($id);//最终的一次性令牌获取时间$a_key=$keyAllow($id);//存在的token个数//判断是否有最后一个token获取记录if($cache->exists($t_key)){$c_time=time();//计算自上次获取令牌以来经过的时间$time_passed=$c_time-$cache->get($t_key);$cache->set($t_key,$c_time,$ttl);//获取桶中令牌的数量$allow=$cache->get($a_key);$allow+=$time_passed*$rate;//添加自上次消费token以来增长的token数量//tokens数量不能超过最大数量if($allow>$maxRequests){$allow=$maxRequests;}//使用的令牌数量不能超过最大限制if($allow<$use){$cache->set($a_key,$allow,$ttl);返回0;}else{//消费令牌$cache->set($a_key,$allow-$use,$ttl);返回(int)ceil($允许);}}else{//记录当前时间作为上次处理时间,用于下次使用$cache->set($t_key,time(),$ttl);//没有token时根据最大token个数处理$cache->set($a_key,$maxRequests-$use,$ttl);return$maxRequests;}参考TokenbucketwikiPHPRateLimitingLibraryWithTokenBucketAlgorithm