分享一個簡單的redis限流

TechKoga發表於2021-06-22
/**
 * Class RedisLimit
 * @package app\common\service
 * redis 簡單限流
 */
class RedisLimit
{
    /**
     * @var int
     */
    static $oneITime = 60; // 單位時間 一分鐘
    /**
     * @var int
     */
    static $oneIMax = 50; // 一個使用者Ip一分鐘最多僅允許訪問訪問10次

    /**
     * @var int
     */
    static $platITime = 60; // 針對所有使用者,單位時間內允許訪問的最大次數
    /**
     * @var int
     */
    static $platIMax = 10; // 針對所有的使用者,該介面最多僅允許訪問N次

    /**
     * Redis配置:IP
     */
    const REDIS_CONFIG_HOST = '127.0.0.1';
    /**
     * Redis配置:埠
     */
    const REDIS_CONFIG_PORT = 6379;


    /**
     * @return \think\response\Json
     * @throws Exception
     * 限制全域性請求
     */
    public static function redis_lock_all_limit()
    {
        $redis = self::getRedisConn();
        //.... 針對平臺全域性鎖,用於限制單位時間內所有使用者訪問的次數
        $platKey = md5(request()->url());

        $platFlowCount = $redis->get($platKey);// 平臺訪問次數
        if($platFlowCount){
            if($platFlowCount >= self::$platIMax){
                return json(['code'=>0,'msg'=>'超過訪問次數']);
            }
        }
        $redis->incr($platKey);// ++1 次訪問次數

        !$platFlowCount && $redis->expire($platKey,self::$platITime); // 設定鎖的有效時間

        return json(['code'=>1,'msg'=>'透過']);

    }


    /**
     * @param $mer_no
     * @return \think\response\Json
     * @throws Exception
     * 限制單個商戶在 多少秒內的請求次數
     */
    public static function redis_lock_single_limit($mer_no)
    {

        $redis = self::getRedisConn();
        // ... 針對單個商戶戶實現的訪問鎖
        $key = md5($mer_no.":".request()->ip());
        // 實現一個使用者一分鐘最多允許訪問10次
        $userFlowCount = $redis->get($key); // 單個使用者訪問次數
        if($userFlowCount){
            if($userFlowCount >= self::$oneIMax){
                return json(['code'=>0,'msg'=>'超過訪問次數']);
            }
        }
        $redis->incr($key);// ++1 次訪問次數
        !$userFlowCount && $redis->expire($key,self::$oneITime);// 設定鎖的有效時間
    }


    /**
     * @param string $strIp
     * @param int $intPort
     * @return \Redis
     * @throws Exception
     */
    public static function getRedisConn($strIp = self::REDIS_CONFIG_HOST, $intPort = self::REDIS_CONFIG_PORT)
    {
        try {
            if (!extension_loaded('redis')) {
                throw new \BadFunctionCallException('not support: redis');
            }
            $objRedis = new \Redis();
            $objRedis->connect($strIp, $intPort);
            return $objRedis;
        }catch (Exception $exception){
            throw new Exception($exception->getMessage());
        }
    }


}
本作品採用《CC 協議》,轉載必須註明作者和本文連結
愛程式碼,不愛程式設計的小夥子 ^v^

相關文章