redis onExpire 事件仅由一个实例处理

redis onExpire event handled by only one instance

我在集群 (JGroups) 中有一个应用程序 运行 的 2 个实例,并且在 redis 的 onExpire 事件上注册了一个侦听器,问题是侦听器是由这两个实例触发的。如何让它只由一个实例处理?

我找到了解决问题的方法,方法是创建一个新的缓存来锁定 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),因为它已经是 true 然后它将 return false并且它永远不会重复到期实施执行。 锁定入口键与过期键相同,值是实例的IP地址,只是为了将来在Redis中的可追溯性。

PS:每个cacheLock条目将在15秒后过期以释放Redis中的内存。