lua脚本,获取参数失败问题解决

##lua脚本,获取参数的失败

我想进行AOP + Redis + lua脚本 进行接口防刷

但是出现了个问题,无法传入参数
在这里插入图片描述
每次都有这个问题

以下是我的代码

package com.qiwenshare.file.aop;

import com.qiwenshare.file.annotation.RateLimit;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Collections;

@Aspect
@Component
public class RateLimitAspect {

    @Autowired
    private RedisTemplate redisTemplate;
    private static final DefaultRedisScript<Long> redisScript;
    static{
        redisScript = new DefaultRedisScript<>();
        redisScript.setLocation(new ClassPathResource("RateLimit.lua"));
        redisScript.setResultType(Long.class);
    }
    @Around("@annotation(rateLimit)")
    public Object around(ProceedingJoinPoint joinPoint, RateLimit rateLimit) throws Throwable {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
        String key = request.getRequestURI() + ":" + request.getMethod() + ":" + request.getRemoteAddr();

        // 构造Redis中存储的键名
        String redisKey = "rate_limit:" + key;
        Long limit = rateLimit.limit();
        Long timeout = rateLimit.timeout();

        // 执行Lua脚本
        Long result = (Long)redisTemplate.execute(redisScript, Collections.singletonList(redisKey), limit.toString(), timeout.toString());

        if (result != null && result == 1) {
            // 请求次数未超限,继续执行方法
            return joinPoint.proceed();
        } else {
            // 请求次数超限,返回限流提示或异常
            throw new RuntimeException("接口请求过于频繁,请稍后再试!");
        }
    }
}
---
--- Generated by EmmyLua(https://github.com/EmmyLua)
--- Created by fuzhongsuo.
--- DateTime: 2024/8/14 15:04
---
local current = tonumber(redis.call('get', KEYS[1]))
local limit = tonumber(ARGV[1])
local timeout = tonumber(ARGV[2])
redis.call('set', 'debug:limit', limit)
redis.call('set', 'debug:expireSeconds', timeout)
if current == nil then
    current = 0
    redis.call('set',KEYS[1],current)
    redis.call('expire', KEYS[1], ARGV[2])
end
if current + 1 > limit then
    return 0
else redis.call('INCRBY', KEYS[1], 1)
    return 1
end

为了排查问题,先修改一下lua脚本,把我需要传的参数 limt timeout
存入redis进行查看,排查到底是什么原因
redis.call('set','test1',limit)
redis.call('set','test1',time)
结果发现,存入redis的是以对象序列化的

其实问题就出在
private RedisTemplate<String,String> redisTemplate;
没有配置

RedisTemplate<String, String> 中,泛型参数指定了模板操作的键(keys)和值(values)的数据类型。第一个泛型参数 String 指定了键(Key)的类型。在这个例子中,键是 String 类型的,这意味着所有的键都将以字符串形式存储在Redis中。
第二个泛型参数 String 指定了值(Value)的类型。在这个例子中,值也是 String 类型的,这意味着所有的值都将以字符串形式存储在Redis中。

这样就完美解决了这个问题,但是花费了我 4个小时,才明白问题

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值