失效模式下升级Infinispan版本的集群启动问题求助
问题根源
这个错误是新旧Infinispan版本间的序列化/反序列化不兼容导致的。即使是小版本升级,Infinispan也可能调整内部对象的Externalizer类型ID(比如报错中的Unknown type: 28是新版本新增的类型标识,旧版本节点无法识别),导致跨版本集群节点无法正常通信,进而阻塞启动流程。
优化解决方案
1. 启用Infinispan跨版本兼容模式
Infinispan提供了兼容性模式,允许新版本节点识别旧版本的序列化格式,同时让旧版本节点兼容新版本的核心对象,支持滚动升级。
配置方式
在application.yml中添加以下配置:
infinispan: global: marshaller: compatibility-mode: true # 指定兼容的旧版本号,即升级前的Infinispan版本 max-version: 14.0.24.Final
或在infinispan.xml中配置:
<infinispan> <global> <marshaller compatibility-mode="true" max-version="14.0.24.Final"/> </global> </infinispan>
升级步骤
- 先给所有待升级的新版本节点启用该配置,部署第一个新版本节点时,它会兼容旧集群的序列化格式,正常加入集群。
- 逐步滚动升级所有节点,完成后可以关闭兼容性模式(移除上述配置)。
2. 逻辑隔离的分阶段滚动升级
不需要修改TCP端口,而是通过JGroups的集群名称实现逻辑隔离,零停机完成升级:
步骤
- 部署新版本临时集群:将新版本节点的JGroups集群名称修改为新值(比如原集群名为
app-cluster,新版本设为app-cluster-v2),同时保持旧集群正常对外提供服务。 - 批量升级节点:逐步将所有服务器升级到新版本,加入
app-cluster-v2,确保新集群节点数量满足服务容量要求。 - 切换流量并下线旧集群:将负载均衡流量切换到新集群,确认服务正常后,逐步关闭旧集群节点。
这种方式避免了跨版本集群通信的问题,同时保证服务持续可用。
3. 锁定Infinispan/JGroups版本
如果不需要Infinispan/JGroups的小版本修复,可以强制锁定依赖版本,保持与Spring Boot 3.2.3一致的版本,仅升级Spring Boot的其他组件:
Maven配置示例
<dependencyManagement> <dependencies> <!-- 锁定Infinispan版本 --> <dependency> <groupId>org.infinispan</groupId> <artifactId>infinispan-bom</artifactId> <version>14.0.24.Final</version> <type>pom</type> <scope>import</scope> </dependency> <!-- 锁定JGroups版本 --> <dependency> <groupId>org.jgroups</groupId> <artifactId>jgroups</artifactId> <version>5.2.21.Final</version> </dependency> </dependencies> </dependencyManagement>
Gradle配置示例
dependencyManagement { imports { mavenBom 'org.infinispan:infinispan-bom:14.0.24.Final' } } dependencies { implementation 'org.jgroups:jgroups:5.2.21.Final' }
这个方案适合对集群稳定性要求极高,且不需要依赖版本更新带来的修复或功能的场景。
4. 架构迁移到Infinispan客户端-服务器模式
如果当前使用的是嵌入式Infinispan集群,可以考虑迁移到客户端-服务器模式:
- 部署独立的Infinispan服务器集群,应用作为客户端通过远程连接访问缓存。
- 升级应用时,只需保证客户端版本与服务器版本兼容,无需考虑应用节点间的集群通信问题。
- Infinispan服务器本身支持滚动升级,进一步降低升级风险。
这种方式适合长期架构优化,彻底解决应用升级与缓存集群的耦合问题。
内容的提问来源于stack exchange,提问作者Janning Vygen
相关产品推荐
相关产品推荐

