啥是令牌桶算法限流:
回到了改革开放吃集体饭的时代(生产力不足),有布票才能买到布,才能做成衣服。
回到服务器来说,就是服务器每秒并发只有200,但是超过200以上的访问,持续一段时间,就可能导致‘岩机’。如果服务器被ddos攻击了,用到令牌桶算法限流,可以解决服务器死机不响应问题。
如何实现呢,我简单写了一个令牌桶类,大概能描述这个意思:
<?php /** *User:jiangsheng *Date:2021/11/29 *Email:<547814711@qq.com> */ ## 令牌桶功能 ### 请求令牌|生成令牌|初始化临牌桶 ### 逻辑:每秒根据给生成100个令牌,用完就不给访问(提示没有访问间隔),每秒往令牌桶插入100条,如果存在未使用完令牌就补充多少个 class TokenBucket{ private static $_maxNum = 100; private static $_redis=null; private static $_link; private static $_config = [ 'host'=>'127.0.0.1', 'port'=>'6379' ]; # 创建一个redis单例对象,初始化 public static function initialization(array $config=[]){ if ( count($config) > 0 ) self::$_config = $config; if ( self::$_redis == null ) self::$_redis = new redis(); try{ self::$_link = self::$_redis->connect( self::$_config['host'] , self::$_config['port'] ); }catch (Exception $e){ die($e->getMessage()); } return self::$_redis; } # 初始化令牌 public static function set(string $key='k'){ // self::$_redis->flushAll(); $currNum = self::$_redis->lLen( $key ); do{ self::$_redis->lPush($key, $key.$currNum); $currNum++; }while( $currNum < self::$_maxNum ); return self::$_redis->lRange($key, 0, self::$_maxNum); } public static function get(string $key='k'){ return self::$_redis->rPop($key); } private function __construct(){ // TODO: Implement __wakeup() method. } final function __destruct(){ // TODO: Implement __wakeup() method. } final function __clone(){ // TODO: Implement __wakeup() method. } final function __wakeup(){ // TODO: Implement __wakeup() method. } } $config = ['host'=>'localhost','port'=>'6379']; $link = TokenBucket::initialization($config); $k1Arr = TokenBucket::set(); // 模拟客户端1s请求102次 $i=0; $requestNum = 102; while($i<$requestNum){ $key = TokenBucket::get(); if(empty($key)){ echo "<br>用户".$i."无法访问"; }else{ echo "<br>用户".$i.",获取到key=》".$key; } $i++; }