【PHP】php 基于redis使用令牌桶算法实现流量控制
整理自:
https://www.cnblogs.com/itbsl/p/13407489.html
https://www.cnblogs.com/myJuly/p/13608475.html
https://mp.weixin.qq.com/s/JQYWVL2YUKLiVZfV99z4cg
如果有侵权请联系删除
令牌桶算法
-
首先设有一个令牌桶,桶内存放令牌,一开始令牌桶内的令牌是满的(桶内令牌的数量可根据服务器情况设定)
-
每次访问从桶内取走一个令牌,当桶内令牌为0,则不允许再访问。
-
每隔一段时间,放入令牌,最多使桶内令牌满额。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | class TrafficShaperController extends Controller { /** * 令牌桶总数量 * @var int */ private $totleNum = 25; /** * 令牌标识(可以根据需要加上关键ID,uid、orderid...) * @var string */ private $quekueName = "TrafficShaper_queue" ; /** * redis缓存类 * @var object */ private $redis ; /** * 初始化方法 * * @author heyw<1051834593@qq.com> * @since 2020/12/10 */ public function _initialize() { $this ->redis = Redis::getInstance(); } /** * 模拟用户消耗令牌 * * @param int $num * @author heyw<1051834593@qq.com> * @since 2020/12/10 */ public function run( $num = 1) { // 初始化 $this ->reset(); // 模拟1s请求10次 while (1) { $this ->getKey(); sleep(0.1); } } /** * 获取令牌 * * @return bool * @author heyw<1051834593@qq.com> * @since 2020/12/11 */ protected function getKey() { // 初始化 $redis = $this ->redis; $queueName = $this ->quekueName; // 获取一个令牌,如果没有直接返回 $res = $redis ->rPop( $queueName ); // 获得令牌,处理业务 var_dump( $res ? 'get it' : 'empty' ); return true; } /** * 重置 * * @author heyw<1051834593@qq.com> * @since 2020/12/11 */ protected function reset() { $this ->redis-> delete ( $this ->quekueName); $this ->add(25); } /** * 定时加入令牌桶,1s执行1次 * * @author heyw<1051834593@qq.com> * @since 2020/12/10 */ public function add( $stepNum = 5) { // 初始化 $redis = $this ->redis; $queueName = $this ->quekueName; // 当前令牌书 $currNum = $redis ->lSize( $queueName ) ?: 0; $maxNum = $this ->totleNum; $addNum = $maxNum >= $currNum + $stepNum ? $stepNum : $maxNum - $currNum ; if ( $addNum == 0) { return true; } // 加入令牌 $token = array_fill (0, $addNum , 1); $redis ->lPush( $queueName , $token ); return true; } } |
得意时做事,失意时读书
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律