Ignite 服务器在侦听远程事件时挂在那里:EVT_NODE_LEFT

Ignite server hang there when listen to remote event: EVT_NODE_LEFT

我有 2 个配置了以下发现 spi 的 ignite 服务器

TcpDiscoveryMulticastIpFinder ipFinder = new TcpDiscoveryMulticastIpFinder();
ipFinder.setAddresses(Arrays.asList("127.0.0.1:47500..47509"));
discoSpi.setIpFinder(ipFinder);

他们都在监听远程事件:EVT_NODE_LEFT,当我关闭其中一个服务器时,EVT_NODE_LEFT 被触发,我将从该节点上的 ignite 开始做一些清理工作

IgniteEvents events = ignite.events();

IgnitePredicate<DiscoveryEvent> filter = evt -> {
    if (evt.eventNode().isClient()) {
        return true;
    }
    System.out.println("remote event: " + evt.name());
    System.out.println("remote event: " + evt.eventNode().consistentId());
    return true;
};
UUID uuid = events.remoteListen(new IgniteBiPredicate<UUID, DiscoveryEvent>() {

    @Override
    public boolean apply(UUID uuid, DiscoveryEvent e) {
        ClusterNode node = e.eventNode();
        if(node.isClient()) {
            return true;
        }
        String consistentId= node.consistentId().toString();
        IgniteCache<String, String> cache = ignite.getOrCreateCache("test");
        //some operation on cache...
        return true; //continue listening
    }
}, filter, EventType.EVT_NODE_LEFT);

当我在键“test”下有数据时,程序运行完美;如果我在键“测试”下没有数据,服务器挂在那里并显示以下消息:

[2021-08-18 15:16:03,828][ERROR][tcp-disco-msg-worker-[crd]-#2-#42][G] Blocked system-critical thread has been detected. This can lead to cluster-wide undefined behaviour [workerName=disco-event-worker, threadName=disco-event-worker-#49, blockedFor=18s]
[15:16:03] Possible failure suppressed accordingly to a configured handler [hnd=StopNodeOrHaltFailureHandler [tryStop=false, timeout=0, super=AbstractFailureHandler [ignoredFailureTypes=UnmodifiableSet [SYSTEM_WORKER_BLOCKED, SYSTEM_CRITICAL_OPERATION_TIMEOUT]]], failureCtx=FailureContext [type=SYSTEM_WORKER_BLOCKED, err=class o.a.i.IgniteException: GridWorker [name=disco-event-worker, igniteInstanceName=null, finished=false, heartbeatTs=1629270945183]]]

调试后,我发现在调用 ignite.getOrCreateCache("test") 时,线程停在方法 GridFutureAdapter.get0(boolean ignoreInterrupts) 的行:LockSupport.park();好像它正在等待离线服务器的响应。我不知道为什么只有在没有数据时才会发生这种情况,但在我的场景中没有数据是一种常见情况。我该如何解决这个问题?谢谢

点燃版本:2.9.1

这是预期的行为。您不应在事件侦听器中执行任何阻塞操作,否则,您的线程可能会被阻塞。

问题是 - 正在 Ignite 的内部线程上调用回调,应该尽快完成。只需将回调逻辑转发到自定义线程池即可。

或者,您可以切换到以异步方式工作且没有阻塞机制的 Continuous Query