#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.