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

redis+lua實(shí)現(xiàn)限流

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

1、需要引入Redis的maven坐標(biāo)

<!--redis和 springboot集成的包 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
    <version>2.3.0.RELEASE</version>
</dependency>

2、redis配置

spring:
? # Redis數(shù)據(jù)庫(kù)索引
? redis:
? ? database: 0
? # Redis服務(wù)器地址
? ? host: 127.0.0.1
? # Redis服務(wù)器連接端口
? ? port: 6379
? # Redis服務(wù)器連接密碼(默認(rèn)為空)
? ? password:
? # 連接池最大連接數(shù)(使用負(fù)值表示沒有限制)
? ? jedis:
? ? ? pool:
? ? ? ? max-active: 8
? # 連接池最大阻塞等待時(shí)間(使用負(fù)值表示沒有限制)
? ? ? ? max-wait: -1
? # 連接池中的最大空閑連接
? ? ? ? max-idle: 8
? # 連接池中的最小空閑連接
? ? ? ? min-idle: 0
? # 連接超時(shí)時(shí)間(毫秒)
? ? timeout: 10000

3、新建腳本放在該項(xiàng)目的 resources 目錄下,新建 limit.lua

local key = KEYS[1] --限流KEY 
local limit = tonumber(ARGV[1]) --限流大小 
local current = tonumber(redis.call('get', key) or "0") if current + 1 > limit then 
return 0 else redis.call("INCRBY", key,"1") redis.call("expire", key,"2") return current + 1 end

4、自定義限流注解

import java.lang.annotation.*;

@Target(value = ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RedisRateLimiter {

   //往令牌桶放入令牌的速率
    double value() default  Double.MAX_VALUE;
    //獲取令牌的超時(shí)時(shí)間
    double limit() default  Double.MAX_VALUE;
}

5、自定義切面類 RedisLimiterAspect 類 ,修改掃描自己controller類

import com.imooc.annotation.RedisRateLimiter;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.assertj.core.util.Lists;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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 javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.List;

@Aspect
@Component
public class RedisLimiterAspect {
    @Autowired
    private HttpServletResponse response;

    /**
     * 注入redis操作類
     */
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

     private DefaultRedisScript<List> redisScript;

    /**
     * 初始化 redisScript 類
     * 返回值為 List
     */
    @PostConstruct
    public void init(){
        redisScript = new DefaultRedisScript<List>();
        redisScript.setResultType(List.class);
        redisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("limit.lua")));
    }

    public final static Logger log = LoggerFactory.getLogger(RedisLimiterAspect.class);

    @Pointcut("execution( public * com.zz.controller.*.*(..))")
    public void pointcut(){

    }
    @Around("pointcut()")
    public Object process(ProceedingJoinPoint proceedingJoinPoint) throws  Throwable {
        MethodSignature  signature = (MethodSignature)proceedingJoinPoint.getSignature();
        //使用Java 反射技術(shù)獲取方法上是否有@RedisRateLimiter 注解類
        RedisRateLimiter redisRateLimiter = signature.getMethod().getDeclaredAnnotation(RedisRateLimiter.class);
        if(redisRateLimiter == null){
            //正常執(zhí)行方法,執(zhí)行正常業(yè)務(wù)邏輯
            return proceedingJoinPoint.proceed();
        }
        //獲取注解上的參數(shù),獲取配置的速率
        double value = redisRateLimiter.value();
        double time = redisRateLimiter.limit();


        //list設(shè)置lua的keys[1]
        //取當(dāng)前時(shí)間戳到單位秒
        String key = "ip:"+ System.currentTimeMillis() / 1000;

        List<String> keyList = Lists.newArrayList(key);

        //用戶Mpa設(shè)置Lua 的ARGV[1]
        //List<String> argList = Lists.newArrayList(String.valueOf(value));

        //調(diào)用腳本并執(zhí)行
        List result = stringRedisTemplate.execute(redisScript, keyList, String.valueOf(value),String.valueOf(time));

        log.info("限流時(shí)間段內(nèi)訪問第:{} 次", result.toString());

        //lua 腳本返回 "0" 表示超出流量大小,返回1表示沒有超出流量大小
        if(StringUtils.equals(result.get(0).toString(),"0")){
            //服務(wù)降級(jí)
            fullback();
            return null;
        }

        // 沒有限流,直接放行
        return proceedingJoinPoint.proceed();
    }

    /**
     * 服務(wù)降級(jí)方法
     */
    private  void  fullback(){
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json; charset=utf-8");
        PrintWriter writer = null;
        try {
            writer= response.getWriter();
            JSONObject o = new JSONObject();
            o.put("status",500);
            o.put("msg","Redis限流:請(qǐng)求太頻繁,請(qǐng)稍后重試!");
            o.put("data",null);
            writer.printf(o.toString()
            );

        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if(writer != null){
                writer.close();
            }
        }
    }
}

6、在需要限流的類添加注解

import com.imooc.annotation.RedisRateLimiter;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.TimeUnit;

@RestController
@Api(value = "限流", tags = {"限流測(cè)試接口"})
@RequestMapping("limiter")
public class LimiterController {

    @ApiOperation(value = "Redis限流注解測(cè)試接口",notes = "Redis限流注解測(cè)試接口", httpMethod = "GET")
    @RedisRateLimiter(value = 10, limit = 1)
    @GetMapping("/redislimit")
    public IMOOCJSONResult redislimit(){

        System.out.println("Redis限流注解測(cè)試接口");
        return IMOOCJSONResult.ok();
    }


}

文章來源地址http://www.zghlxwxcb.cn/news/detail-734461.html

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

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

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

相關(guān)文章

  • Redis實(shí)現(xiàn)限流的三種方式

    所謂固定窗口限流即時(shí)間窗口的起始和結(jié)束時(shí)間是固定的,在固定時(shí)間段內(nèi)允許要求的請(qǐng)求數(shù)量訪問,超過則拒絕;當(dāng)固定時(shí)間段結(jié)束后,再重新開始下一個(gè)時(shí)間段進(jìn)行計(jì)數(shù)。 我們可以根據(jù)當(dāng)前的時(shí)間,以分鐘為時(shí)間段,每分鐘都生成一個(gè)key,用來inc,當(dāng)達(dá)到請(qǐng)求數(shù)量就返回

    2024年02月11日
    瀏覽(21)
  • Redis 實(shí)現(xiàn)限流的三種方式

    面對(duì)越來越多的高并發(fā)場(chǎng)景,限流顯示的尤為重要。 當(dāng)然,限流有許多種實(shí)現(xiàn)的方式,Redis具有很強(qiáng)大的功能,我用Redis實(shí)踐了三種的實(shí)現(xiàn)方式,可以較為簡(jiǎn)單的實(shí)現(xiàn)其方式。Redis不僅僅是可以做限流,還可以做數(shù)據(jù)統(tǒng)計(jì),附近的人等功能,這些可能會(huì)后續(xù)寫到。 我們?cè)谑褂?/p>

    2024年02月11日
    瀏覽(25)
  • 【Spring】SpringBoot整合Redis,用Redis實(shí)現(xiàn)限流(附Redis解壓包)

    【Spring】SpringBoot整合Redis,用Redis實(shí)現(xiàn)限流(附Redis解壓包)

    ? ???個(gè)人主頁(yè):哈__ 期待您的關(guān)注? 本文介紹SpringBoot整合Redis并且進(jìn)行接口的限流,文章主要介紹的是一種思想,具體代碼還要結(jié)合實(shí)際。 Redis的解壓包我放在了百度網(wǎng)盤上,有需要的可以下載。 Redis-x64-3.0.504 解壓碼:uhwj 我們?cè)诒镜亟鈮合螺d的Redis壓縮包,打開解壓后的

    2024年04月09日
    瀏覽(21)
  • redis + AOP + 自定義注解實(shí)現(xiàn)接口限流

    限流(rate limiting) ? 是指在一定時(shí)間內(nèi),對(duì)某些資源的訪問次數(shù)進(jìn)行限制,以避免資源被濫用或過度消耗。限流可以防止服務(wù)器崩潰、保證用戶體驗(yàn)、提高系統(tǒng)可用性。 限流的方法有很多種,常見的有以下幾種: 漏桶算法: ?漏桶算法通過一個(gè)固定大小的漏桶來模擬流量

    2024年02月03日
    瀏覽(22)
  • Java生態(tài)/Redis中如何使用Lua腳本

    Java生態(tài)/Redis中如何使用Lua腳本

    Mac上安裝LUA很簡(jiǎn)單,直接使用 brew 相關(guān)命令; 使用 lua -v 命令可以看到lua已經(jīng)安裝完畢。 創(chuàng)建一個(gè)test.lua文件,內(nèi)容為: 執(zhí)行命令: 輸出為: Lua 提供了交互式編程和腳本式編程: 交互式編程:直接在命令行中輸入語法,可以立即執(zhí)行并查看到執(zhí)行效果。 腳本是編程:編寫

    2024年01月20日
    瀏覽(15)
  • springboot高級(jí)教程基于 redis 通過注解實(shí)現(xiàn)限流

    Spring Boot整合Redis有一種方便的方式是使用注解方式實(shí)現(xiàn)限流。 可以通過自定義注解的方式來標(biāo)注需要限流的方法,在方法執(zhí)行前進(jìn)行限流的檢查。 以下是具體實(shí)現(xiàn)方式: 1. 自定義注解`@RedisLimit`,并定義注解元素,如限流的時(shí)間、限流的次數(shù)等。 2. 編寫切面類`RedisLimitAspe

    2024年02月10日
    瀏覽(25)
  • Redis--Zset使用場(chǎng)景舉例(滑動(dòng)窗口實(shí)現(xiàn)限流)

    Redis--Zset使用場(chǎng)景舉例(滑動(dòng)窗口實(shí)現(xiàn)限流)

    前言 在Redis–Zset的語法和使用場(chǎng)景舉例(朋友圈點(diǎn)贊,排行榜)一文中,提及了redis數(shù)據(jù)結(jié)構(gòu)zset的指令語法和一些使用場(chǎng)景,今天我們使用zset來實(shí)現(xiàn)滑動(dòng)窗口限流,詳見下文。 什么是滑動(dòng)窗口 滑動(dòng)窗口是一種流量控制策略,用于控制一定時(shí)間內(nèi)請(qǐng)求的訪問數(shù)量。 其原理是

    2024年01月19日
    瀏覽(28)
  • lua腳本獲取table類型-Java使用lua腳本操作redis獲取zset元素的集合

    lua腳本獲取table類型-Java使用lua腳本操作redis獲取zset元素的集合 7.0點(diǎn)贊功能-定時(shí)持久化到數(shù)據(jù)庫(kù)-lua腳本的編寫_嗶哩嗶哩_bilibili https://www.bilibili.com/video/BV1bu411j75u 這個(gè)腳本主要是放到Springboot工程里的, 這里如果是向放到字段控制臺(tái)執(zhí)行,那就要加入 eval 以及其他參數(shù):

    2024年02月13日
    瀏覽(17)
  • 使用 redis 實(shí)現(xiàn)分布式接口限流注解 RedisLimit

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

    前言 很多時(shí)候,由于種種不可描述的原因,我們需要針對(duì)單個(gè)接口實(shí)現(xiàn)接口限流,防止訪問次數(shù)過于頻繁。這里就用 redis+aop 實(shí)現(xiàn)一個(gè)限流接口注解 @RedisLimit 代碼 點(diǎn)擊查看RedisLimit注解代碼 AOP代碼 點(diǎn)擊查看aop代碼 lua腳本代碼 注意:腳本代碼是放在 resources 文件下的,它的類型是

    2024年02月08日
    瀏覽(23)
  • SpringBoot定義攔截器+自定義注解+Redis實(shí)現(xiàn)接口防刷(限流)

    在攔截器Interceptor中攔截請(qǐng)求 通過地址+請(qǐng)求uri作為調(diào)用者訪問接口的區(qū)分在Redis中進(jìn)行計(jì)數(shù)達(dá)到限流目的 定義參數(shù) 訪問周期 最大訪問次數(shù) 禁用時(shí)長(zhǎng) 代碼實(shí)現(xiàn) 定義攔截器:實(shí)現(xiàn)HandlerInterceptor接口,重寫preHandle()方法 注冊(cè)攔截器:配置類實(shí)現(xiàn)WebMvcConfigurer接口,重寫addIntercep

    2024年02月05日
    瀏覽(32)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包