Java Spring Boot连接Cassandra双节点报错:打开新通道失败
问题分析与解决方案
错误信息
[s0|/ip_address_node2:9042] Error while opening new channel (ConnectionInitException: [s0|connecting...] Protocol initialization request, step 1 (STARTUP { CQL_VERSION=3.0.0, DRIVER_NAME=Apache Cassandra Java Driver, DRIVER_VERSION=4.18.1, CLIENT_ID=67d065fa-b9b2-44ff-a162-cb7b15de06ab }): failed to send request (java.nio.channels.NotYetConnectedException))
成因分析
- 网络连通性问题:node2的9042端口(CQL默认端口)未开放,或防火墙/安全组拦截了客户端请求;节点间网络路由存在故障,导致TCP连接无法建立。
- Cassandra节点状态异常:node2未完成启动初始化,或Cassandra服务进程已停止,无法响应连接请求。
- 版本不兼容:Cassandra节点版本过低(如低于3.x),与4.18.1版本的Java驱动存在协议版本不匹配问题,导致初始化请求失败。
- 节点配置错误:node2的
cassandra.yaml中start_native_transport被设为false(关闭了CQL端口),或rpc_address/broadcast_rpc_address配置错误,导致客户端无法正确寻址。
修复方案
1. 排查网络连通性
- 执行
telnet ip_address_node2 9042或nc -zv ip_address_node2 9042测试端口是否可访问。 - 检查防火墙、安全组规则,确保允许客户端IP访问node2的9042端口,同时集群节点间的7000(内部通信)、7001(SSL内部通信)、9042端口需开放。
2. 检查节点状态
- 登录node2,执行
nodetool status确认节点处于UN(正常可用)状态。 - 查看Cassandra系统日志(默认路径
/var/log/cassandra/system.log),排查启动失败、初始化异常的报错信息,必要时重启Cassandra服务:systemctl restart cassandra(根据系统服务管理命令调整)。
3. 验证版本兼容性
- 确认Cassandra节点版本与Java驱动兼容:4.x驱动建议搭配Cassandra 3.11+或4.x版本,若版本不匹配,可升级Cassandra节点或降级驱动至对应兼容版本。
4. 修正节点配置
- 打开node2的
cassandra.yaml,确保start_native_transport: true;rpc_address设置为节点可被访问的IP,broadcast_rpc_address设置为集群对外广播的IP(集群环境下)。 - 修改配置后重启Cassandra服务,确保配置生效。
Java 21 + Spring Boot 3.3.0 + Cassandra 项目实践示例
核心依赖(Maven)
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-cassandra</artifactId> </dependency>
连接配置(application.properties)
spring.data.cassandra.contact-points=ip_address_node1,ip_address_node2 spring.data.cassandra.port=9042 spring.data.cassandra.local-datacenter=your_datacenter_name spring.data.cassandra.cluster-name=your_cluster_name
实体类示例
import org.springframework.data.cassandra.core.mapping.PrimaryKey; import org.springframework.data.cassandra.core.mapping.Table; @Table("user_info") public class UserInfo { @PrimaryKey private String userId; private String username; private int age; // Getters & Setters }
Repository层示例
import org.springframework.data.cassandra.repository.CassandraRepository; public interface UserInfoRepository extends CassandraRepository<UserInfo, String> { }
业务层调用示例
import org.springframework.stereotype.Service; import java.util.Optional; @Service public class UserService { private final UserInfoRepository userInfoRepository; public UserService(UserInfoRepository userInfoRepository) { this.userInfoRepository = userInfoRepository; } public UserInfo saveUser(UserInfo userInfo) { return userInfoRepository.save(userInfo); } public Optional<UserInfo> getUserById(String userId) { return userInfoRepository.findById(userId); } }
内容的提问来源于stack exchange,提问作者omen_123
相关产品推荐
相关产品推荐

