NetworkClient分析
来源:互联网 发布:3dcg制作软件 编辑:程序博客网 时间:2024/06/06 18:25
NetworkClient是一个网络客户端实现,它可以用于生产者发送消息,也可以用于消费者消费消息以及服务器端broker之间的通信
一 核心字段
Selectable selector: 用于执行网络I/O
MetadataUpdater: 用于更新Metadata
ClusterConnectionStates connectionStates: 每一个node的连接状态
InFlightRequests: 缓存发送请求但是还没有收到响应的队列
int socketSendBuffer:发送请求的缓冲区大小
int socketReceiveBuffer: 接收响应的缓冲区大小
String clientId: 客户端唯一标示
int requestTimeoutMs:生产者等待服务器端确认消息的超时时间
二 重要方法
2.1 ready 检测是否可以发送请求
public booleanready(Node node, long now) {
// 检测节点是否为空
if (node.isEmpty())
throw new IllegalArgumentException("Cannotconnect to empty node "+ node);
// 判断是否已经准备好发送请求
if (isReady(node,now))
return true;
// 检测该节点现在是否能够连接
if (connectionStates.canConnect(node.idString(),now))
// 初始化一个连接
initiateConnect(node, now);
return false;
}
public boolean isReady(Node node, long now) { // 是否我们现在需要更新元数据以及该node是否已经可以发送请求 return !metadataUpdater.isUpdateDue(now) && canSendRequest(node.idString());}
2.2 send 发送请求
public void send(ClientRequest request, long now) { // 获取发送请求的目的地 String nodeId = request.request().destination(); // 如果该节点不能发送请求,则抛出异常 if (!canSendRequest(nodeId)) throw new IllegalStateException("Attempt to send a request to node " + nodeId + " which is not ready."); doSend(request, now);}private void doSend(ClientRequest request, long now) { request.setSendTimeMs(now); // 将请求添加到等待响应的inFlightRequests队列 this.inFlightRequests.add(request); // 发送请求 selector.send(request.request());}
2.3 poll 进行网络I/O操作
public List<ClientResponse> poll(long timeout, long now) { // 更新元数据请求 long metadataTimeout = metadataUpdater.maybeUpdate(now); try { // 执行I/O操作 this.selector.poll(Utils.min(timeout, metadataTimeout, requestTimeoutMs)); } catch (IOException e) { log.error("Unexpected error during I/O", e); } // 处理完成的行为 long updatedNow = this.time.milliseconds(); List<ClientResponse> responses = new ArrayList<>(); handleCompletedSends(responses, updatedNow);// 处理completedSends队列 handleCompletedReceives(responses, updatedNow);// 处理completedReceivess队列 handleDisconnections(responses, updatedNow);//处理disconnect列表 handleConnections();//处理connect列表 handleTimedOutRequests(responses, updatedNow);// 处理InflightRquest中超时请求 // 循环调用ClientRequest的回调函数 for (ClientResponse response : responses) { if (response.request().hasCallback()) { try { response.request().callback().onComplete(response); } catch (Exception e) { log.error("Uncaught error in request completion:", e); } } } return responses;}
2.4 handleCompletedSends
我们知道completedSends保存的是最近一次poll发送成功的请求
private void handleCompletedSends(List<ClientResponse> responses, long now) { // 遍历completedSends集合 for (Send send : this.selector.completedSends()) { // 获取指定队列的第一个元素 ClientRequest request = this.inFlightRequests.lastSent(send.destination()); if (!request.expectResponse()) {// 检测请求是否需要响应 // 不需要的话将inFlightRequests队列中的第一个请求删除 this.inFlightRequests.completeLastSent(send.destination()); // 生成ClientResponse对象添加到response集合 responses.add(new ClientResponse(request, now, false, null)); } }}
2.5 handleCompletedReceives
private void handleCompletedReceives(List<ClientResponse> responses, long now) { for (NetworkReceive receive : this.selector.completedReceives()) { String source = receive.source(); // 从inFlightRequests队列中取出对应的ClientRequest ClientRequest req = inFlightRequests.completeNext(source); // 解析响应 Struct body = parseResponse(receive.payload(), req.request().header()); // 处理response,会更新metadata元数据,并唤醒所有等待metadata // 更新完成的线程 if (!metadataUpdater.maybeHandleCompletedReceive(req, now, body)) // 如果不是MetadataResponse,则创建ClientResponse并添加到responses集合 responses.add(new ClientResponse(req, now, false, body)); }}
2.6 handleDisconnections
private void handleDisconnections(List<ClientResponse> responses, long now) { // 更新连接状态,并清理掉inFlightRequests中断开连接的Node对应的ClientRequest for (String node : this.selector.disconnected()) { log.debug("Node {} disconnected.", node); processDisconnection(responses, node, now); } if (this.selector.disconnected().size() > 0) metadataUpdater.requestUpdate(); // 标识需要更新集群元数据}
2.7 handleConnections
private void handleConnections() { // 遍历connect列表,将ConnectionStates中记录的连接状态修改为CONNECTed for (String node : this.selector.connected()) { log.debug("Completed connection to node {}", node); this.connectionStates.connected(node); }}
2.8 handleTimedOutRequests
private void handleTimedOutRequests(List<ClientResponse> responses, long now) { // 获取inFlightRequests中超时的请求 List<String> nodeIds = this.inFlightRequests.getNodesWithTimedOutRequests(now, this.requestTimeoutMs); // 遍历这些超时的请求 for (String nodeId : nodeIds) { // 关闭连接 this.selector.close(nodeId); log.debug("Disconnecting from node {} due to request timeout.", nodeId); processDisconnection(responses, nodeId, now); } // 更新元数据 if (nodeIds.size() > 0) metadataUpdater.requestUpdate();}
- NetworkClient分析
- WARN org.apache.kafka.clients.NetworkClient
- Kafka java Client 错误 org.apache.kafka.clients.NetworkClient Error connecting to node 1 at slave2:909
- 分析
- 分析
- 分析
- 分析
- 分析
- 分析
- 分析
- 分析
- 分析
- 大家帮忙分析分析!
- FFMpeg分析详细分析
- FFMpeg分析详细分析
- core 分析的分析
- 写给自己,分析分析
- FFMpeg分析详细分析
- SpringMVC绑定json数组,参考链接http://www.th7.cn/web/ajax/201603/158081.shtml
- python基础知识小总结
- CI框架表单验证
- Quartz使用总结
- Mybatis 向指定表中批量插入数据
- NetworkClient分析
- 使用wireshark常用的过滤命令
- LeetCode-algorithms 49. Group Anagrams
- MYSQL中利用select查询某字段中包含以逗号分隔的字符串的记录方法
- omp计算时间(高精度)
- VLAN介绍
- 华为或者荣耀手机用Android Studio 不能输出logcat问题
- AirMan建设的经验
- MYSQL查询实例