1、本系列文章每期都將解決一個Redis實際問題
2、每期問題將在每期的評論中選取
3、問題限Redis相關,其它問題如果本人感興趣也不排除開辟新系列
4、本人常用PHP所以解決方案以PHP為主
5、評論里沒有合適的提問時我會自己給自己出題
問題描述:
本期為第一期,所以只能自己出題了
如何用Redis給訂單限流,如每M秒允許N個訪問
解決方案:
<?php /** * 是否允許放行 * @param string $key redis鍵前綴 * @param int $timeInterval 時間間隔(秒) * @param int $max 時間間隔內最大放行數(shù) * @return bool 是否放行 * @throws Exception * @example * <pre> * //每秒放行一個 * isAllow('my_allow'); * * //每秒放行3個 * isAllow('my_allow',1,3); * * //每3秒放行2個 * isAllow('my_allow',3,2); */ function isAllow(string $key, int $timeInterval=1, int $max=1):bool{ if($timeInterval<1){ throw new Exception('時間間隔必須大于0'); } if($max<1){ throw new Exception('最大放行數(shù)必須大于0'); } $redis=new Redis(); $redis->connect('192.168.31.187'); if(!$redis->isConnected()){ throw new Exception('Redis服務連接失敗'); } //對時間戳取模,使得每$timeInterval秒取得同一個時間戳 $time=time(); $key.=':'.($time-($time%$timeInterval)); //自增并返回自增后的結果 $index=$redis->incr($key); //如果是第一個訪問,設置鍵的過期時間 if($index===1){ $redis->expire($key,$timeInterval+1); } return $index<$max+1; }
代碼解讀:
-
對時間取模,使得鍵名每$timeInterval秒更新一次
-
incr()方法自增鍵的值,如果鍵不存在則先創(chuàng)建一個值為0的鍵再進行自增
-
根據(jù)自增原理,同鍵名下第N次自增返回的值就是N
-
鍵名每$timeInterval秒更新一次,所以在創(chuàng)建鍵的$timeInterval+1秒后鍵就不再有價值
以上,歡迎大家提問、糾錯、補充、優(yōu)化。
推薦:《PHP視頻教程》