【问题标题】:redis onExpire event handled by only one instanceredis onExpire 事件仅由一个实例处理
【发布时间】:2021-12-21 05:28:00
【问题描述】:

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

【问题讨论】:

    标签: java redis jgroups


    【解决方案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),因为它已经为 true,然后它将返回 false,并且永远不会重复过期实现执行。 锁定入口键与过期键相同,值是实例的IP地址,只是为了将来在Redis中的可追溯性。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-11-05
      • 2020-11-03
      • 1970-01-01
      • 2016-11-28
      • 1970-01-01
      • 2023-03-16
      • 2021-05-01
      • 2013-01-22
      相关资源
      最近更新 更多