Redis+lua限流大致流程

该博客介绍了如何使用Redis和Lua脚本来实现限流。首先定义了一个名为iplimite.lua的lua脚本,放置在资源目录下。接着,通过lua配置类加载脚本到内存,以便Redis操作。博客还涉及了限流注解、获取用户IP的工具类、AOP切面限流以及限流测试Controller。在限流核心代码中,关键点包括确保key的唯一性和处理Nginx反向代理导致的真实用户IP获取问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

06、定义限流lua脚本

新建一个iplimite.lua文件,放在resources目录下的lua文件夹下:

在这里插入图片描述

-- 为某个接口的请求IP设置计数器,比如:127.0.0.1请求课程接口
-- KEYS[1] = 127.0.0.1 也就是用户的IP
-- ARGV[1] = 过期时间 30m
-- ARGV[2] = 限制的次数
local limitCount = redis.call('incr',KEYS[1]);
if limitCount == 1 then
    redis.call("expire",KEYS[1],ARGV[2])
end
-- 如果次数还没有过期,并且还在规定的次数内,说明还在请求同一接口
if limitCount > tonumber(ARGV[1]) then
    return false
end

return true

07、Lua限流脚本配置类

lua配置类主要是去加载lua文件的内容,到时内存中。方便redis去读取和控制。

package com.taimi.config;

@Configuration
public class LuaConfiguration {
   

    /**
     * 将lua脚本的内容加载出来放入到DefaultRedisScript
     * @return
     */
    @Bean
    public DefaultRedisScript<Boolean> ipLimitLua() {
   
        DefaultRedisScript<Boolean> defaultRedisScript = new DefaultRedisScript<>();
        defaultRedisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("lua/iplimiter.lua")));
        defaultRedisScript.setResultType(Boolean.class);
        return defaultRedisScript;
    }

    /**
     * 将lua脚本的内容加载出来放入到DefaultRedisScript
     * @return
     */
    @Bean
    public DefaultRedisScript<Boolean> ipLimiterLuaScript() {
   
        DefaultRedisScript<Boolean> defaultRedisScript = new DefaultRedisScript<>();
        defaultRedisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("lua/iplimiter2.lua")));
        defaultRedisScript.setResultType(Boolean.class);
        return defaultRedisScript;
    }

}

08、限流注解

package com.taimi.aop;


@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AcessLimter {
   
    // 每timeout限制请求的个数
    int limit() default 10;

    // 时间,单位默认是秒
    int timeout() default 1;
}

09、请求获取用户IP工具类

package com.taimi.aop;


public class RequestUtils {
   

    public static String getIpAddr(HttpServletRequest request)
    {
   
        if (request == null)
        {
   
            return "unknown";
        }
        String ip = request.getHeader(</
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值