日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

Springboot使用Redis-Cell實現限流

作者:毅大師 更新時間: 2022-05-25 編程語言

一、Redis-Cell安裝如下

Redis-Cell限流插件安裝(Centos)_毅呀毅呀喲-CSDN博客一、下載wget https://github.com/brandur/redis-cell/releases/download/v0.3.0/redis-cell-v0.3.0-x86_64-unknown-linux-gnu.tar.gz二、解壓tar -zxvf redis-cell-v0.3.0-x86_64-unknown-linux-gnu.tar.gz三、得到如下四、復制.so文件的地址,在redis.conf文件中添加如下配置loadmodule /usr/l.https://blog.csdn.net/qq_39648029/article/details/121245348二、Redis-Cell指令介紹

CL.THROTTLE user123 15 30 60 1

?三、返回值

127.0.0.1:6379> CL.THROTTLE user123 15 30 60
1) (integer) 0     # 0允許,1拒絕
2) (integer) 16????# 容量,等于指令第二個參數 +1 
3) (integer) 15    # 剩余量
4) (integer) -1    #-1表示正常放入,0表示已滿,正數表示幾秒可放入(單位:秒)
5) (integer) 2     # 多長時間漏斗完全漏空(單位:秒)

四、spring boot代碼

package com.zyweb.admin.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
 * redis 工具類
 * @Author ZhangYi
 */
@Component
public class RedisUtil {

    private final Logger logger = LoggerFactory.getLogger(RedisUtil.class);

    @Resource
    private RedisTemplate redisTemplate;

    /**
     * lua 腳本
     */
    public static final String LUA_SCRIPT = "return redis.call('cl.throttle',KEYS[1], ARGV[1], ARGV[2], ARGV[3], ARGV[4])";
    
    /**
     * 測試
     *
     * @param key
     * @param maxBurst
     * @param countPerPeriod
     * @param period
     * @param quantity
     * @return
     */
    public boolean redisCellDemo(String key, int maxBurst, int countPerPeriod, int period, int quantity) {
        try {
            DefaultRedisScript script = new DefaultRedisScript<>(LUA_SCRIPT, List.class);
            /**
             * KEYS[1]需要設置的key值,可以結合業務需要
             * ARGV[1]參數是漏斗的大小 最大爆發
             * ARGV[2]頻率次數,結合ARGV[3]一起使用
             * ARGV[3]周期(秒),結合ARGV[2]一起使用
             *      最后的速率就是ARGV[2]次/ARGV[3]秒
             * ARGV[4]申請令牌數,默認是1
             */
            List rst = redisTemplate.execute(script, Arrays.asList(key), maxBurst, countPerPeriod, period, quantity);
            logger.info("限流{}返回:{}", key, rst);
            /**
             * 1. 動作是否受限:
             *   0 表示允許該操作。
             *   1 表示該操作受到限制/阻止。
             * 2. 密鑰的總限制 (max_burst+1)。這相當于常見的X-RateLimit-Limit HTTP返回頭。
             * 3. 密鑰的剩余限制。相當于X-RateLimit-Remaining。
             * 4. 用戶應重試之前的秒數,-1如果允許操作,則始終如此。相當于Retry-After。
             * 5. 限制將重置為其最大容量之前的秒數。相當于X-RateLimit-Reset。
             */
            //這里只關注第一個元素0表示正常,1表示過載
            return rst.get(0) == 0;
        } catch (Exception e) {
            logger.error("限流{}獲取拋錯:", key, e);
            return false;
        }
    }
}

?五、測試

    @GetMapping("/redisCell")
    public void redisCell(){
        // 模擬30次請求
        for (int i = 0; i < 30; i++) {
            boolean rst = redisUtil.redisCellDemo("user123 ", 5, 10, 30, 1);
            if (!rst) {
                logger.info("訪問{}過于頻繁,請稍后再試",i);
            } else {
                logger.info("訪問{}通過",i);
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

六、demo表示,每秒有1個請求進入,漏斗最大容量為5,漏水速率為10個/30秒,也就是3秒鐘漏掉一個

整合攔截器+自定義注解,可自定義對接口進行限流

原文鏈接:https://zhangyi520.blog.csdn.net/article/details/121249036

欄目分類
最近更新