什么是 TcpCommunicationSpi


🧩 一、核心定位:什么是 TcpCommunicationSpi

java 复制代码
/**
 * <tt>TcpCommunicationSpi</tt> is default communication SPI which uses
 * TCP/IP protocol and Java NIO to communicate with other nodes.
 */

翻译TcpCommunicationSpi 是默认的通信 SPI,使用 TCP/IP 协议和 Java NIO 与其他节点通信。

关键点

  • 它是 Ignite 集群中节点间通信的底层引擎
  • 使用 TCP 长连接 + Java NIO(非阻塞 I/O) 实现高性能、可靠的数据传输。
  • 所有消息(缓存更新、计算任务、事务、心跳等)都走这个通道。

🌐 二、节点发现与属性注入

java 复制代码
 * This SPI adds {@link #ATTR_ADDRS} and {@link #ATTR_PORT} local node attributes...

翻译 :该 SPI 会向本地节点添加两个属性:IP 地址列表(ATTR_ADDRS)和端口(ATTR_PORT),其他节点可以通过 ClusterNode.attributes() 获取。

作用

  • 其他节点通过 Discovery SPI(如 TcpDiscoverySpi)发现新节点时,能知道它监听的 IP 和端口。
  • 实现自动连接,无需手动配置每个节点的地址。

📌 示例:

java 复制代码
for (ClusterNode node : ignite.cluster().nodes()) {
    String ip = node.attribute(TcpCommunicationSpi.ATTR_ADDRS);
    int port = node.attribute(TcpCommunicationSpi.ATTR_PORT);
    System.out.println("Node: " + ip + ":" + port);
}

🔌 三、端口绑定与自动递增

java 复制代码
 * At startup, this SPI tries to start listening to local port specified by setLocalPort(int).
 * If local port is occupied, then SPI will automatically increment the port number...
 * setLocalPortRange(int) controls maximum number of ports that SPI will try before it fails.

翻译 :启动时尝试绑定指定端口,如果被占用,则自动 +1 尝试,最多尝试 localPortRange 次。

设计目的

  • 支持单机多节点部署(比如开发测试或容器环境)。
  • 无需手动为每个节点分配不同端口。

📌 示例:

java 复制代码
commSpi.setLocalPort(47100);           // 起始端口
commSpi.setLocalPortRange(100);        // 最多尝试 100 个端口(47100~47199)

⚠️ 生产建议:固定端口范围,便于防火墙策略和运维监控。


🔁 四、连接缓存与空闲超时

java 复制代码
 * This SPI caches connections to remote nodes... idle connections are kept active for DFLT_IDLE_CONN_TIMEOUT...
 * Use setIdleConnectionTimeout(long) to configure.

翻译:SPI 会缓存到远程节点的连接,默认空闲一段时间后关闭(默认 60 秒)。

为什么这么做?

  • 避免频繁建立/断开 TCP 连接(开销大)。
  • 但也不能无限保持连接(浪费资源)。

📌 建议:

  • 高并发场景:可适当增大超时时间(如 300 秒),减少连接重建。
  • 资源紧张环境:可减小超时,及时释放资源。

🚨 五、故障检测机制(Failure Detection)

这是最重要的一段

java 复制代码
 * Configuration defaults... are chosen to make possible for communication SPI work reliably...
 * but this has made failure detection time worse.

翻译:默认配置为了"稳定运行"而牺牲了"故障检测速度"。

1. 推荐方式:使用 failureDetectionTimeout

java 复制代码
 * It's highly recommended to do this using IgniteConfiguration.setFailureDetectionTimeout(long)
  • 这是一个高层超时设置 ,会自动影响底层多个参数:
    • 连接超时(connectTimeout
    • 最大重连超时(maxConnectTimeout
    • 重连次数(reconnectCount

📌 示例:

java 复制代码
IgniteConfiguration cfg = new IgniteConfiguration();
cfg.setFailureDetectionTimeout(10_000); // 10秒内检测失败

最佳实践 :优先设置 failureDetectionTimeout,不要手动设置底层参数。

2. 高级调优(不推荐)

java 复制代码
 * If advanced settings are required... various TcpCommunicationSpi parameters may be used.
  • 只有在 failureDetectionTimeout 不够用时才手动调这些:
    • setConnectTimeout(2000)
    • setMaxConnectTimeout(60000)
    • setReconnectCount(10)

⚠️ 警告:手动设置这些参数会覆盖 failureDetectionTimeout 的自动计算!


⚙️ 六、配置参数详解(Optional)

文档列出了大量可选参数,我们分类总结:

类别 参数 建议
网络地址 setLocalAddress() 多网卡时必须设置
端口 setLocalPort(), setLocalPortRange() 生产建议固定范围
连接管理 setConnectionsPerNode(2) 提升并发吞吐
性能优化 setTcpNoDelay(true) 禁用 Nagle,降低小消息延迟
setSocketReceiveBuffer(512*1024) 增大缓冲区提升吞吐
setDirectBuffer(true) 使用堆外内存减少 GC
NIO 调优 setSelectorsCount(4) NIO 选择器线程数(通常 = CPU 核数)
消息控制 setMessageQueueLimit(0) 0 表示无限制(防丢包)
setAckSendThreshold(32) 每 32 条消息发一次 ACK,减少网络开销
安全 setSharedMemoryPort(-1) 生产环境禁用共享内存

🛠️ 七、Java 和 Spring 配置示例

✅ Java 配置

java 复制代码
TcpCommunicationSpi commSpi = new TcpCommunicationSpi();
commSpi.setLocalPort(4321); // 覆盖默认端口

IgniteConfiguration cfg = new IgniteConfiguration();
cfg.setCommunicationSpi(commSpi);

Ignition.start(cfg);

💡 注意:只有需要覆盖默认值时才需要显式配置,否则用默认即可。

✅ Spring XML 配置

xml 复制代码
<bean id="grid.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
    <property name="communicationSpi">
        <bean class="org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi">
            <property name="localPort" value="4321"/>
        </bean>
    </property>
</bean>

📌 Spring 用户可以通过 XML 统一管理配置。


📌 八、关键总结与最佳实践

项目 建议
是否必须配置 ❌ 否,有合理的默认值
生产环境必须设置 localAddress, localPort, failureDetectionTimeout
性能调优重点 tcpNoDelay=true, connectionsPerNode=2, socketBuffer=512K+
故障检测 ✅ 优先使用 failureDetectionTimeout
避免手动设置 connectTimeout, maxConnectTimeout, reconnectCount(除非高级需求)
单机多节点 ✅ 利用 localPortRange 自动递增
监控 ✅ 使用 commSpi.getMetrics() 查看连接、吞吐、延迟

🎯 一句话理解全文

TcpCommunicationSpi 是 Ignite 的"神经网络"

  • 它自动建立 TCP 连接,缓存连接,处理消息收发。
  • 默认配置追求"稳定",但故障检测较慢。
  • 生产环境应通过 failureDetectionTimeout 统一调优,并适当优化缓冲区和连接数。
  • 你不需要手动管理连接,但需要理解它的行为来避免性能瓶颈。

相关推荐
lang201509281 天前
Apache Ignite的流处理(Streaming)示例程序
开发语言·apache·ignite
lang201509286 天前
Apache Ignite Data Streaming 案例 QueryWords
apache·ignite
lang201509288 天前
Apache Ignite 的对等类加载(Peer Class Loading, P2P Class Loading)机制
apache·ignite
lang201509288 天前
Apache Ignite 与 Spring Boot 集成
spring boot·后端·apache·ignite
lang201509288 天前
如何使用 Apache Ignite 作为 Spring 框架的缓存(Spring Cache)后端
spring·缓存·apache·ignite
lang201509288 天前
Apache Ignite 的监控与指标(Monitoring and Metrics)
apache·ignite
lang201509288 天前
Apache Ignite 集群状态(Cluster States)
apache·ignite
lang201509288 天前
Apache Ignite 的分布式锁Distributed Locks的介绍
apache·ignite
lang201509289 天前
关于 Apache Ignite 中 Job 调度(Job Scheduling)与冲突控制(Collision Control) 的机制说明
apache·ignite