如何在Apache Ignite v2.14中禁用自动发现?解决版本不兼容启动失败问题
问题描述
近期将Apache Ignite从2.10.0版本(对应应用版本1.X)升级至2.14.0版本(对应应用版本2.X)后,Spring应用(v2.X)启动失败,原因是尝试连接远程未升级的Ignite节点(应用v1.X),触发版本不兼容错误:
2023-03-27 14:32:23.180 ERROR [TLM-Services,,] 4915 --- [ServerService Thread Pool -- 89] o.a.i.i.IgniteKernal%rate-limiting : Failed to start manager: GridManagerAdapter [enabled=true, name=o.a.i.i.managers.discovery.GridDiscoveryManager] org.apache.ignite.IgniteCheckedException: Failed to start SPI: TcpDiscoverySpi [addrRslvr=null, addressFilter=null, sockTimeout=5000, ackTimeout=5000, marsh=JdkMarshaller [clsFilter=org.apache.ignite.marshaller.MarshallerUtils$1@69749b3c], reconCnt=10, reconDelay=2000, maxAckTimeout=600000, soLinger=0, forceSrvMode=false, clientReconnectDisabled=false, internalLsnr=null, skipAddrsRandomization=false] ... Caused by: org.apache.ignite.spi.IgniteSpiException: Local node and remote node have different version numbers (node will not join, Ignite does not support rolling updates, so versions must be exactly the same) [locBuildVer=2.10.0, rmtBuildVer=2.14.0, locNodeAddrs=[bripfm005/192.168.200.205], rmtNodeAddrs=[192.168.200.206], locNodeId=8ff94531-125c-4d2d-815b-cc2106c5e24d, rmtNodeId=6c2799d7-5bb7-4c71-96c7-8c96ab3987cc]
两个版本的Spring配置一致,具体代码如下:
@Configuration @ConditionalOnProperty(prefix= RateLimitingProperties.PROPERTY_PREFIX, value = {"enabled"}, havingValue = "true") @EnableIgniteRepositories(basePackages = "com.example", includeFilters = { @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = { IgniteRepository.class }) }) public class RateLimitingIgniteCacheConfig { private static final Logger LOGGER = LoggerFactory.getLogger(RateLimitingIgniteCacheConfig.class); @SuppressWarnings("rawtypes") private final List<CacheConfiguration> cacheConfigurations; @Autowired public RateLimitingIgniteCacheConfig(@SuppressWarnings("rawtypes") List<CacheConfiguration> cacheConfigurations) { LOGGER.info(SAFE, "Detected {} cache configurations to start", cacheConfigurations.size()); this.cacheConfigurations = cacheConfigurations; } @Bean public Ignite igniteInstance() { IgniteConfiguration cfg = new IgniteConfiguration(); cfg.setGridLogger(new Slf4jLogger()); cfg.setMetricsLogFrequency(0); cfg.setCacheConfiguration(cacheConfigurations.toArray(new CacheConfiguration[0])); return Ignition.start(cfg); } @Bean public RateLimitingIgniteCacheResolver rateLimitingIgniteCacheResolver() { return new RateLimitingIgniteCacheResolver(igniteInstance()); } }
由于v1.X应用是生产系统暂无法修改,已尝试以下两种禁用自动发现的方法但均无效:
- 为两个应用添加IGNITE_LOCAL_HOST JVM参数:
JAVA_OPTS="$JAVA_OPTS -DIGNITE_LOCAL_HOST=192.168.200.206" - 在配置中添加Discovery SPI:
TcpDiscoverySpi spi = new TcpDiscoverySpi() .setIpFinder(new TcpDiscoverySpi().getIpFinder()); IgniteConfiguration cfg = new IgniteConfiguration(); cfg.setDiscoverySpi(spi);
请问在Apache Ignite v2.14中是否有其他禁用自动发现的有效方法?
解决方案
要彻底让v2.X应用的Ignite节点不尝试发现其他节点,有两种可靠的方式:
1. 使用TcpDiscoveryVmIpFinder指定仅本地节点
修改Ignite配置,将IP Finder设置为只包含当前节点的地址,这样节点只会尝试连接自己,不会去发现其他远程节点:
@Bean public Ignite igniteInstance() { IgniteConfiguration cfg = new IgniteConfiguration(); cfg.setGridLogger(new Slf4jLogger()); cfg.setMetricsLogFrequency(0); cfg.setCacheConfiguration(cacheConfigurations.toArray(new CacheConfiguration[0])); // 配置Discovery SPI,仅连接本地节点 TcpDiscoverySpi discoverySpi = new TcpDiscoverySpi(); TcpDiscoveryVmIpFinder ipFinder = new TcpDiscoveryVmIpFinder(); // 设置当前节点的IP和默认Discovery端口(47500,可根据实际配置修改) ipFinder.setAddresses(Collections.singletonList("192.168.200.206:47500")); discoverySpi.setIpFinder(ipFinder); cfg.setDiscoverySpi(discoverySpi); return Ignition.start(cfg); }
2. 使用NoopDiscoverySpi(仅适用于单机测试/非集群场景)
如果你的v2.X应用不需要集群功能,只是单机使用Ignite,可以直接使用NoopDiscoverySpi,它完全禁用节点发现机制:
@Bean public Ignite igniteInstance() { IgniteConfiguration cfg = new IgniteConfiguration(); cfg.setGridLogger(new Slf4jLogger()); cfg.setMetricsLogFrequency(0); cfg.setCacheConfiguration(cacheConfigurations.toArray(new CacheConfiguration[0])); // 禁用所有节点发现 cfg.setDiscoverySpi(new NoopDiscoverySpi()); return Ignition.start(cfg); }
注意事项
NoopDiscoverySpi不支持集群,仅适合单机运行的Ignite节点;如果未来需要扩展集群,建议使用第一种方式。- 确保两个版本的应用使用的Ignite集群完全隔离,因为Ignite不支持滚动升级,版本必须完全一致才能加入同一集群。
内容的提问来源于stack exchange,提问作者Milan Desai
相关产品推荐
相关产品推荐

