使用 RedisTemplate 执行 Lua 脚本永远不起作用

Executing Lua Script with RedisTemplate never works

我目前正在为 kafka 和 GC PubSub 开发一个基准测试工具。我想查看有关分钟的结果。最大和平均传输速度。之前,我将每个条目都设置为 reddis 哈希。之后,我将 reddis 哈希映射到 java 映射,并在过程结束时对它们进行迭代以获得最小值、最大值。它看起来很慢,因为如果我调用 100000 个条目,程序将迭代 x3 以获得最小值、最大值和平均值。所以我试着用 Lua 脚本来做到这一点。发布消息后,我将开始时间设置为散列映射,当侦听器收到消息时,我从散列中获取消息开始时间,并计算与 System.currentTimeMillis 的差异。在这一步之后,我试图执行 Lua 脚本,将当前值与旧值进行比较并设置它。但是当我执行脚本时,程序似乎停在那里。我尝试过从 Lua 脚本返回 true 但我无法得到任何响应。

 private void calculateSetANDLogAgain(User user){
        long startTime = ((long) redisTemplate.opsForHash().get("times", user.getId()));
        logger.info("Received message -> " + user.toString());
        long duration = 0L;
        duration = System.currentTimeMillis() - startTime;
        Object[] args = new Object[1];
        args[0] = duration;
        System.out.println("BEFORE");
        boolean a = redisTemplate.execute(statisticScript, Collections.singletonList("a"),args);
        System.out.println("AFTER: " + a);
    }

在这里我看到之前但我看不到打印之后。这里是log output and configuration about script executing. And here is my class tree。请注意RedisConfig class 有下面的bean。

 @Bean
    public DefaultRedisScript<Boolean> redisscript(){
        DefaultRedisScript defaultRedisScript = new DefaultRedisScript<>();
        defaultRedisScript.setLocation(new ClassPathResource("statistics.lua"));
        defaultRedisScript.setResultType(Boolean.class);
        return defaultRedisScript;
    }

我正在 class 中自动装配 DefaultRedisScript 实例,它拥有 calculateSetANDLogAgain 方法。脚本文件只有“return true;

编辑;如果有帮助,这是我的第一个脚本。

local difference = tonumber(ARGV[1])
local max = tonumber(redis.call("GET","max"))
local min = tonumber(redis.call("GET","min"))
if max == nil then
    redis.call("SET","max",difference)
elseif difference > max then
    redis.call("SET","max",difference)
end
if min == nil then
    redis.call("SET","min",difference)
elseif difference < min then
    redis.call("SET","min",difference)
end

那么可能会出什么问题呢?我想不通...

我解决了这个问题。这很奇怪,但似乎失败的根源是错误的类路径。我对我的代码做了一些更改,请看一下。

这里是 Bean 定义。

   @Bean
    public DefaultRedisScript<Boolean> redisscript() {
        DefaultRedisScript defaultRedisScript = new DefaultRedisScript<Boolean>();
        defaultRedisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("statistics.lua")));
        defaultRedisScript.setResultType(Boolean.class);
        return defaultRedisScript;
    }

这里是 calculateSetANDLogAgain 函数。

    private void calculateSetANDLogAgain(User user) {
        long startTime = ((long) redisTemplate.opsForHash().get("times", user.getId()));
        logger.info("Received message -> " + user.toString());
        Long duration = null;
        duration = System.currentTimeMillis() - startTime;
        Object[] args = new Object[1];
        args[0] = duration;
        try {
            redisTemplate.execute(statisticScript, null, args);
        } catch (Exception e) {
            finalLogger.info("Error while executing script -> " + e.getLocalizedMessage());
        }
    }

这是脚本;

local difference = tonumber(ARGV[1])
local max = tonumber(redis.call("GET","max"))
local min = tonumber(redis.call("GET","min"))
if max == nil then
    redis.call("SET","max",tostring(difference));
elseif difference > max then
    redis.call("SET","max",tostring(difference));
end

if min == nil then
    redis.call("SET","min",tostring(difference));
elseif difference < min then
    redis.call("SET","min",tostring(difference));
end
return nil;

最后我的脚本在资源文件夹中,我在构造函数中注入了重新模板。