Flink 运行时之基于 Netty 的网络通信

本文深入分析了Flink运行时基于Netty的网络通信,重点关注客户端的PartitionRequestClientHandler处理器,以及服务端的PartitionRequestServerHandler和PartitionRequestQueue。客户端处理器处理服务端响应,通过BufferListener和stagedMessages队列管理消息。服务端处理器负责消息分发,使用PartitionRequestQueue进行队列管理,确保消息正确处理和响应。
摘要由CSDN通过智能技术生成

客户端核心处理器
我们分析一下客户端协议栈中的核心的处理器PartitionRequestClientHandler,该处理器用于处理服务端的响应消息。我们以客户端获取到响应之后回调该处理器的channelRead方法为入口来进行分析:public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { try { //当没有待解析的原始消息时,直接解码消息,否则将消息加入到stagedMessages队列中,等待排队处理 if (!bufferListener.hasStagedBufferOrEvent() && stagedMessages.isEmpty()) { decodeMsg(msg); } else { stagedMessages.add(msg); } } catch (Throwable t) { notifyAllChannelsOfErrorAndClose(t); }}12345678910111213这里涉及到两个对象,首先是bufferListener,用于感知可用Buffer的事件侦听器,它是内部实现的BufferListenerTask类型。其次是stagedMessages,用于接收原始未解码消息的队列。解码方法decodeMsg的主要逻辑包含对两种类型消息的解析。一种是服务端的错误响应消息ErrorResponse,另一种是正常的Buffer请求响应消息BufferResponse。对于错误响应消息会判断是否是致命错误,如果是致命错误,则直接通知所有的InputChannel并关闭它们;如果不是,则让该消息对应的InputChannel按不同情况处理。我们重点关注对BufferResponse的处理:if (msgClazz == NettyMessage.BufferResponse.class) { NettyMessage.BufferResponse bufferOrEvent = (NettyMessage.BufferResponse) msg; //根据响应消息里的receiverId,从注册map里获取到接收该消息的RemoteInputChannel实例 RemoteInputChannel inputChannel = inputChannels.get(bufferOrEvent.receiverId); //如果该响应没有对应的接收者,则释放该Buffer,同时通知服务端取消该请求 if (inputChannel == null) { bufferOrEvent.releaseBuffer(); cancelRequestFor(bufferOrEvent.receiverId); return true; } //接下来才进入到真正的解析逻辑 return decodeBufferOrEvent(inputChannel, bufferOrEvent);}12345678910111213在decodeBufferOrEvent中,它会对该消息具体是Buffer还是Event进行区分,如果是Buffer:if (bufferOrEvent.isBuffer()) { //空Buffer if (bufferOrEvent.getSize() == 0) { inputChannel.onEmptyBuffer(bufferOrEvent.sequenceNumber); return true; } //获得Buffer提供者,如果为空,则通知服务端取消请求 BufferProvider bufferProvider = inputChannel.getBufferProvider(); if (bufferProvider == null) { cancelRequestFor(bufferOrEvent.receiverId); return false; } while (true) { //从Buffer提供者请求Buffer,以放置响应结果数据 Buffer buffer = bufferProvider.requestBuffer(); //如果请求到Buffer,则读取数据同时触发InputChannel的onBuffer回调 //该方法在前文分析输入通道时我们早已提及过,它会将Buffer加入到队列中 if (buffer != null) { buffer.setSize(bufferOrEvent.getSize()); bufferOrEvent.getNettyBuffer().readBytes(buffer.getNioBuffer()); inputChannel.onBuffer(buffer, bufferOrEvent.sequenceNumber); return true; } //否则进入等待模式,当有Buffer可用时,会触发bufferListener的onEvent方法 else if (bufferListener.waitForBuffer(bufferProvider, bufferOrEvent)) { releaseNettyBuffer

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值