You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Apache Ignite客户端节点频繁故障致Spring Boot重启问题求助

问题描述

现有2台Apache Ignite服务器,已成功接入3个客户端,每个客户端为各自缓存配置独立数据区域,运行状态良好。新增第4个客户端后,该客户端节点偶尔故障,且触发错误时Spring Boot应用会完全重启。

故障日志

WARN 1 --- [vent-worker-#44] o.a.i.i.m.d.GridDiscoveryManager         : Node FAILED:
TcpDiscoveryNode [id=6ff310ca-dd51-4115-9fdf-fbf3d093b5b3, consistentId=6ff310ca-dd51-4115-9fdf-fbf3d093b5b3,
addrs=ArrayList [0:0:0:0:0:0:0:1%lo, x.y.z.a, 127.0.0.1], sockAddrs=null, discPort=0, order=967, 
intOrder=487, lastExchangeTime=1731680665767, loc=false, ver=2.15.0#20230425-sha1:f98f7f35, isClient=true]

客户端配置代码

@Configuration
public class IgniteConfig {

    @Bean
    public Ignite igniteInstance() {
        IgniteConfiguration cfg = new IgniteConfiguration();

        cfg.setMetricsLogFrequency(0);


        // Set client mode
        cfg.setClientMode(true);

        // Configure discovery SPI
        TcpDiscoverySpi discoverySpi = new TcpDiscoverySpi();
        TcpDiscoveryVmIpFinder ipFinder = new TcpDiscoveryVmIpFinder();
        ipFinder.setAddresses(Arrays.asList(
                "x.y.z.a:47500..47509"
    ));
        discoverySpi.setIpFinder(ipFinder);
        discoverySpi.setNetworkTimeout(10000); // Network timeout (5 seconds)
        discoverySpi.setJoinTimeout(10000);   // Join timeout (10 seconds)
        cfg.setDiscoverySpi(discoverySpi);

        // Set failure detection timeouts
        cfg.setFailureDetectionTimeout(120000); // 120 seconds
        cfg.setClientFailureDetectionTimeout(120000); // 120 seconds

        // Configure TCP communication SPI
        TcpCommunicationSpi spi = new TcpCommunicationSpi();
        spi.setConnectTimeout(30000); // Initial connection timeout (3 seconds)
        spi.setMaxConnectTimeout(10000); // Max connection timeout (6 seconds)
        spi.setReconnectCount(3); // Number of reconnection attempts
        spi.setIdleConnectionTimeout(3000); // Idle connection timeout (100 ms)
        cfg.setCommunicationSpi(spi);

        // Configure event logging to capture node failures and disconnections
        cfg.setIncludeEventTypes(
                EventType.EVT_NODE_FAILED,
                EventType.EVT_NODE_LEFT,
                EventType.EVT_NODE_JOINED,
                EventType.EVT_NODE_SEGMENTED
        );

        // Configure event storage for diagnostics
        MemoryEventStorageSpi eventStorageSpi = new MemoryEventStorageSpi();
        eventStorageSpi.setExpireCount(1000); // Store up to 1000 events in memory
        cfg.setEventStorageSpi(eventStorageSpi);

        // Set metrics log frequency to zero to reduce logging noise
        cfg.setMetricsLogFrequency(0);

        // Start the Ignite instance
        return Ignition.start(cfg);
    }
}

原因分析

  • 通信参数配置矛盾:TcpCommunicationSpi中maxConnectTimeout(10秒)小于connectTimeout(30秒),属于无效配置,会导致连接超时逻辑混乱,触发节点故障判定。
  • 空闲连接超时过短:idleConnectionTimeout设为3秒,客户端与服务器短暂无通信时连接会被强制关闭,引发节点离线误判。
  • 集群负载压力:新增第4个客户端后,服务器或客户端主机的CPU、内存、网络带宽达到瓶颈,心跳包发送延迟,被Ignite判定为节点故障。
  • Spring集成逻辑缺陷:直接使用Ignition.start()初始化Ignite节点,未配置异常兜底处理,节点故障时会导致Spring上下文崩溃,触发应用重启。

解决办法

1. 修正通信SPI参数配置

调整超时参数,确保逻辑合理,避免误关连接:

TcpCommunicationSpi spi = new TcpCommunicationSpi();
spi.setConnectTimeout(10000); // 初始连接超时10秒
spi.setMaxConnectTimeout(30000); // 最大连接超时30秒(需大于初始超时)
spi.setReconnectCount(5); // 增加重连次数,提升容错性
spi.setIdleConnectionTimeout(60000); // 空闲连接超时改为60秒,减少误断连接
cfg.setCommunicationSpi(spi);

2. 优化发现SPI配置

适配网络波动,延长超时时间:

discoverySpi.setNetworkTimeout(30000); // 网络超时改为30秒
discoverySpi.setJoinTimeout(30000); // 集群加入超时改为30秒

3. 排查资源负载

  • 监控Ignite服务器和第4个客户端主机的CPU、内存、网络使用率,确认是否存在资源瓶颈;
  • 若服务器负载过高,可考虑新增服务器节点或优化缓存数据区域的内存分配策略。

4. 调整Spring与Ignite集成方式

使用IgniteSpringBean替代直接启动,内置上下文管理逻辑,避免应用崩溃:

@Bean
public IgniteSpringBean igniteInstance() {
    IgniteSpringBean ignite = new IgniteSpringBean();
    ignite.setConfiguration(cfg);
    return ignite;
}

同时自定义节点故障事件处理器,优雅处理异常:

Ignite ignite = igniteInstance();
ignite.events().localListen(evt -> {
    if (evt.type() == EventType.EVT_NODE_FAILED && ((NodeEvent) evt).eventNode().isClient()) {
        // 自定义处理逻辑:如重新初始化节点、发送告警等
        return true;
    }
    return true;
}, EventType.EVT_NODE_FAILED);

5. 配置唯一客户端一致性ID

确保每个客户端节点的consistentId唯一,避免节点识别冲突:

cfg.setConsistentId(UUID.randomUUID().toString()); // 或使用主机名+进程ID等唯一标识

内容的提问来源于stack exchange,提问作者Dude Ramasamy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 05:13:17