Выполнение Lua Script с RedisTemplate никогда не работает

В настоящее время я работаю над эталонным инструментом для kafka и GC PubSub. Я хочу увидеть результаты о мин. Максимальная и средняя скорость передачи. Раньше я устанавливал каждую запись в хеш Reddis. После этого я сопоставлял хэши reddis с картой java и повторял их в конце процесса для минимальных и максимальных значений. Это кажется таким медленным, потому что, если я назову 100000 записей, программа повторяет x3 для минимального, максимального и среднего. Поэтому я попытался сделать это с помощью сценария Lua. После публикации сообщения я устанавливаю время начала для хеш-карты, и когда слушатель получает сообщение, я беру это время начала сообщений из хеша и вычисляю разницу с помощью System.currentTimeMillis. После этого шага я пытаюсь выполнить Lua Script, который сравнивает текущее значение со старым значением и устанавливает его. Но когда я запускаю скрипт, кажется, что программа останавливается на этом. Я попытался просто вернуть true из сценария Lua, но не смог получить никакого ответа.

 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);
    }

Здесь я вижу ДО, но не могу видеть ПОСЛЕ печати. Вот вывод журнала и конфигурация выполнения скрипта. А вот мое дерево классов. Обратите внимание, что класс RedisConfig имеет bean ниже.

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

И я автоматически связываю экземпляр 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

Так что же может пойти не так? Я не мог понять это...


person Kadir Akin    schedule 14.07.2020    source источник


Ответы (1)


Я решил проблему. Это странно, но кажется, что источником сбоя является неправильный путь к классам. Я внес некоторые изменения в свой код, так что взгляните.

Вот определение 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;

Наконец, мой скрипт в папке ресурсов, и я внедрил redistemplate в конструктор.

person Kadir Akin    schedule 10.08.2020