событие redis onExpire обрабатывается только одним экземпляром

#java #redis #jgroups

Вопрос:

У меня есть 2 экземпляра приложения, запущенного в кластере(JGroups), и у меня есть прослушиватель, зарегистрированный в событии onExpire redis, проблема в том, что прослушиватель запускается 2 экземплярами. Как я могу сделать так, чтобы это обрабатывалось только одним экземпляром?

Ответ №1:

Я выяснил, как решить проблему с созданием нового кэша для блокировки выполнения onExpired только для одного экземпляра. В реализации выполнения события я проверяю, может ли экземпляр выполнить его или нет, как показано ниже

 class InvalidationListener implements CacheEntryExpiredListener<String, .....> {

    .....

    @Override
    public void onExpired(Iterable<CacheEntryEvent<? extends String, ? extends ....>> events) {

        events.forEach(event -> {
            try {
                ....
                boolean canExecute = cacheLock.putIfAbsent(key, InetAddress.getLocalHost().getHostAddress());
                if (canExecute) {
                    logger.info("This instance will execute the onExpired ");
                    ....
                } else {
                    logger.info("onExpired already executed by another instance");
                }
            } catch (IOException e) {
                logger.error("An error occured in onExpired event", e);
            }
        });

    }
}
 

Пояснение :
Первый экземпляр для запуска onExpired установит запись блокировки в значение true и выполнит реализацию истечения срока действия, а затем любой другой экземпляр не изменит значение (putIfAbsent), поскольку оно уже является истинным, а затем вернет значение false и никогда не будет дублировать выполнение реализации истечения срока действия.
Ключ ввода блокировки совпадает с ключом с истекшим сроком действия, и значение-это IP-адрес экземпляра только для отслеживания в Redis в будущем.

PS: Срок действия каждой записи cacheLock истечет через 15 секунд, чтобы освободить память в Redis.