if (!this.client.ready(node, now)) {
-> NetworkClient.ready
public boolean ready(Node node, long now) {
//如果当前检查的节点为null,就报异常。
if (node.isEmpty())
throw new IllegalArgumentException("Cannot connect to empty node " + node);
//TODO 判断要发送消息的主机,是否具备发送消息的条件
//第一次进来,不具备。false
if (isReady(node, now))
return true;
//判断是否可以尝试去建立网络
if (connectionStates.canConnect(node.idString(), now))
// if we are interested in sending to a node and we don't have a connection to it, initiate one
//初始化连接
//绑定了 连接到事件而已
initiateConnect(node, now);
return false;
}
isReady -> canSendRequest
private boolean canSendRequest(String node) {
/**
* connectionStates.isConnected(node):
* 生产者:多个连接,缓存多个连接(跟我们的broker的节点数是一样的)
* 判断缓存里面是否已经把这个连接给建立好了。
*
* selector.isChannelReady(node):
* java NIO:selector
* selector -> 绑定了多个KafkaChannel(java socketChannel)
* 一个kafkaChannel就代表一个连接。
*
* inFlightRequests.canSendMore(node):
* 每个往broker主机上面发送消息的连接,
* 最多能容忍5个请求,发送出去了但是还没有接受到响应。
* 影响发送数据的顺序。重试会造成乱序
* 1,2,3,4,5
*/
return connectionStates.isConnected(node)
&& selector.isChannelReady(node)
&& inFlightRequests.canSendMore(node);
}
--> connectionStates.canConnect
public boolean canConnect(String id, long now) {
//首先从缓存里面获取当前主机的连接。
NodeConnectionState state = nodeState.get(id);
//如果值为null,说明从来没有连接过。
if (state == null)
return true;
else
//可以从缓存里面获取到连接。
//但是连接的状态是DISCONNECTED 并且
// now - state.lastConnectAttemptMs >= this.reconnectBackoffMs 说明可以进行重试,重试连接。
return state.state == ConnectionState.DISCONNECTED && now - state.lastConnectAttemptMs >= this.reconnectBackoffMs;
}