国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

使用 redis 實(shí)現(xiàn)分布式接口限流注解 RedisLimit

這篇具有很好參考價(jià)值的文章主要介紹了使用 redis 實(shí)現(xiàn)分布式接口限流注解 RedisLimit。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

前言

  • 很多時(shí)候,由于種種不可描述的原因,我們需要針對單個(gè)接口實(shí)現(xiàn)接口限流,防止訪問次數(shù)過于頻繁。這里就用 redis+aop 實(shí)現(xiàn)一個(gè)限流接口注解

@RedisLimit 代碼

點(diǎn)擊查看RedisLimit注解代碼

import java.lang.annotation.*;

/**
 * 功能:分布式接口限流注解
 * @author love ice
 * @create 2023-09-18 15:43
 */
@Target({ElementType.TYPE,ElementType.METHOD})
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface RedisLimit {
    /**
     * redis中唯一key,一般用方法名字做區(qū)分
     * 作用: 針對不同接口,做不同的限流控制
     */
    String key() default "";

    /**
     * 限流時(shí)間內(nèi)允許訪問次數(shù) 默認(rèn)1
     */
    long permitsPerSecond() default 1;

    /**
     * 限流時(shí)間,單位秒 默認(rèn)60秒
     */
    long expire() default 60;

    /**
     * 限流提示信息
     */
    String msg() default "接口限流,請稍后重試";
}

AOP代碼

點(diǎn)擊查看aop代碼

import com.aliyuncs.utils.StringUtils;
import com.test.redis.Infrastructure.annotation.RedisLimit;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.scripting.support.ResourceScriptSource;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * redis限流切面
 *
 * @author love ice
 * @create 2023-09-18 15:44
 */
@Slf4j
@Aspect
@Component
public class RedisLimitAop {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    private DefaultRedisScript<Long> redisScript;

    @PostConstruct
    public void init() {
        redisScript = new DefaultRedisScript<>();
        redisScript.setResultType(Long.class);
        // 執(zhí)行 lua 腳本
        ResourceScriptSource resourceScriptSource = new ResourceScriptSource(new ClassPathResource("rateLimiter.lua"));
        redisScript.setScriptSource(resourceScriptSource);
    }

    @Pointcut("@annotation(com.test.redis.Infrastructure.annotation.RedisLimit)")
    private void check() {

    }

    @Before("check()")
    private void before(JoinPoint joinPoint) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();

        // 拿到 RedisLimit 注解,如果存在則說明需要限流
        RedisLimit redisLimit = method.getAnnotation(RedisLimit.class);

        if (redisLimit != null) {
            // 獲取 redis 的 key
            String key = redisLimit.key();
            String className = method.getDeclaringClass().getName();
            String name = method.getName();
            String limitKey = key + className + name;
            log.info("限流的key:{}", limitKey);

            if (StringUtils.isEmpty(key)) {
                // 這里是自定義異常,為了方便寫成了 RuntimeException
                throw new RuntimeException("code:101,msg:接口中 key 參數(shù)不能為空");
            }

            long limit = redisLimit.permitsPerSecond();
            long expire = redisLimit.expire();
            // 把 key 放入 List 中
            List<String> keys = new ArrayList<>(Collections.singletonList(key));
            Long count = stringRedisTemplate.execute(redisScript, keys, String.valueOf(limit), String.valueOf(expire));
            log.info("Access try count is {} for key ={}", count, keys);

            if (count != null && count == 0) {
                log.debug("令牌桶={}, 獲取令牌失效,接口觸發(fā)限流", key);
                throw new RuntimeException("code:10X, redisLimit.msg()");
            }
        }
    }
}

lua腳本代碼

注意:腳本代碼是放在 resources 文件下的,它的類型是 txt,名稱后綴是lua。如果你不想改名稱,就使用我寫好的全名--> rateLimiter.lua

點(diǎn)擊查看腳本代碼
--獲取KEY
local key = KEYS[1]

local limit = tonumber(ARGV[1])

local curentLimit = tonumber(redis.call('get', key) or "0")

if curentLimit + 1 > limit
    then return 0
else
    -- 自增長 1
    redis.call('INCRBY', key, 1)
    -- 設(shè)置過期時(shí)間
    redis.call('EXPIRE', key, ARGV[2])
    return curentLimit + 1
end

最后為了照顧純小白,給大家看一下我的目錄結(jié)構(gòu)

使用 redis 實(shí)現(xiàn)分布式接口限流注解 RedisLimit文章來源地址http://www.zghlxwxcb.cn/news/detail-712235.html

到了這里,關(guān)于使用 redis 實(shí)現(xiàn)分布式接口限流注解 RedisLimit的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 分布式限流:Redis

    分布式限流:Redis

    目錄 1:如何實(shí)現(xiàn)分布式限流 2:限流的幾種類別? 2.1:固定窗口限流 2.2:滑動窗口限流 2.3:漏桶限流 2.4:令牌桶限流 3:實(shí)現(xiàn)分布式限流:Redis 3.1:引入Redisson的依賴包 3.2:初始化Redisson 3.3:創(chuàng)建Redisson的限流類? 1:把統(tǒng)計(jì)用戶的使用頻率等這些數(shù)據(jù)放到一個(gè)集中的存儲,比如redis,這樣無

    2024年02月08日
    瀏覽(20)
  • 基于Redis的分布式限流詳解

    基于Redis的分布式限流詳解

    Redis除了能用作緩存外,還有很多其他用途,比如分布式鎖,分布式限流,分布式唯一主鍵等,本文將和大家分享下基于Redis分布式限流的各種實(shí)現(xiàn)方案。 用最簡單的話來說: 外部請求是不可控的,而我們系統(tǒng)的負(fù)載是有限的,如果沒有限流機(jī)制,一旦外部請求超過系統(tǒng)承載

    2024年02月04日
    瀏覽(28)
  • 使用策略模式實(shí)現(xiàn) Spring 分布式和單機(jī)限流

    我們可以使用策略模式來統(tǒng)一單機(jī)限流和分布式限流的實(shí)現(xiàn),提高代碼的可擴(kuò)展性和可維護(hù)性。 思路是定義一個(gè) RateLimitStrategy 接口,并分別實(shí)現(xiàn)單機(jī)限流策略 LocalRateLimitStrategy 和分布式限流策略 DistributedRateLimitStrategy 。在 AOP 切面中,根據(jù)配置決定使用哪種限流策略。 定義策略

    2024年04月24日
    瀏覽(29)
  • Redis的4種分布式限流算法

    Redis的4種分布式限流算法

    服務(wù)系統(tǒng)流量多,的確是一件好事,但是如果過載,把系統(tǒng)打掛了,那大家都要吃席了。 所以,在各種大促活動之前,要對系統(tǒng)進(jìn)行壓測,評估整個(gè)系統(tǒng)的峰值QPS,要做一些限流的設(shè)置,超過一定閾值,就拒絕處理或者延后處理,避免把系統(tǒng)打掛的情況出現(xiàn)。 限流和熔斷有

    2024年02月15日
    瀏覽(28)
  • 使用Redission自定義注解實(shí)現(xiàn)分布式鎖(聲明式)

    1.主要依賴 配置redission 自定義注解 sepl工具類 aop

    2024年02月11日
    瀏覽(14)
  • 分布式限流方案及實(shí)現(xiàn)

    分布式限流方案及實(shí)現(xiàn)

    優(yōu)質(zhì)博文:IT-BLOG-CN 限流是對高并發(fā)訪問進(jìn)行限制,限速的過程。通過限流來限制資源,可以提高系統(tǒng)的穩(wěn)定性和可靠性,控制系統(tǒng)的負(fù)載,削峰填谷,保證服務(wù)質(zhì)量。 服務(wù)限流后的常見處理方式: 【1】拒絕服務(wù); 【2】排隊(duì)或等待; 【3】服務(wù)降級(當(dāng)服務(wù)器壓力劇增的情

    2024年02月14日
    瀏覽(21)
  • 四種常見分布式限流算法實(shí)現(xiàn)!

    四種常見分布式限流算法實(shí)現(xiàn)!

    大家好,我是老三,最近公司在搞年終大促,隨著各種營銷活動“組合拳”打出,進(jìn)站流量時(shí)不時(shí)會有一個(gè)小波峰,一般情況下,當(dāng)然是流量越多越好,前提是系統(tǒng)能杠地住。大家都知道,一個(gè)分布式系統(tǒng),有兩個(gè)“棄車保帥”的策略: 限流 和 熔斷 ,這期,我們就來討論一

    2024年02月16日
    瀏覽(21)
  • 使用redis實(shí)現(xiàn)分布式鎖

    使用redis實(shí)現(xiàn)分布式鎖

    在一個(gè)分布式系統(tǒng)中,也會涉及多個(gè)節(jié)點(diǎn)訪問同一個(gè)公共資源的情況,此時(shí)就需要通過鎖來做互斥控制,避免出現(xiàn)類似于“線程安全”的問題,而java的synchronized這樣的鎖只能在當(dāng)前進(jìn)程中生效,在分布式的這種多個(gè)進(jìn)程多個(gè)主機(jī)的場景無能為力,此時(shí)就需要分布式鎖。 例如

    2024年02月07日
    瀏覽(37)
  • 如何使用 Redis 快速實(shí)現(xiàn)分布式鎖?

    如何使用 Redis 快速實(shí)現(xiàn)分布式鎖?

    本文我們來討論如何使用 Redis 快速實(shí)現(xiàn)分布式鎖。 分布式鎖有很多種解決方案,前面簡單介紹過,Redis 可以通過 set key 方式來實(shí)現(xiàn)分布式鎖,但實(shí)際情況要更加復(fù)雜,比如如何確保臨界資源的串行執(zhí)行,如何及時(shí)釋放,都是需要額外考慮的。 本文要講的是一個(gè)完備的分布式

    2024年02月04日
    瀏覽(23)
  • SpringBoot使用Redis實(shí)現(xiàn)分布式緩存

    SpringBoot使用Redis實(shí)現(xiàn)分布式緩存

    ?作者簡介:2022年 博客新星 第八 。熱愛國學(xué)的Java后端開發(fā)者,修心和技術(shù)同步精進(jìn)。 ??個(gè)人主頁:Java Fans的博客 ??個(gè)人信條:不遷怒,不貳過。小知識,大智慧。 ??當(dāng)前專欄:SpringBoot 框架從入門到精通 ?特色專欄:國學(xué)周更-心性養(yǎng)成之路 ??本文內(nèi)容:SpringBoot使用

    2023年04月09日
    瀏覽(20)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包