公众号|松华说|Netty接收和发送数据
  • 分享在京东工作的技术感悟,还有JAVA技术和业内最佳实践,大部分都是务实的、能看懂的、可复现的

扫一扫
关注公众号

Netty接收和发送数据

博客首页文章列表 松花皮蛋me 2020-03-11 23:53

一、Netty接收数据


1、自适应数据大小的分配器,动态分配byte buffer的大小。


2、连续读。判断byte buffer是否装满,如果不是,则结束当前读。如果是,则调整大小,尝试继续读取直到没有数据或者满16次。

二、Netty业务处理

触发pipeline.fireChannelRead(byteBuf)把读取的数据传播出去。这里需要注意往pipleline添加handler时的顺序问题,读顺序自上而下,写顺序自下而上,业务处理在中间。

三、Netty写数据

write动作表示将数据写到一个buffer、flush动作表示将buffer里的数据发送出去(刷数据)、writeAndFlush动作表示写完立即发送出去。


Netty flush数据时发现写不进去时会停止,然后注入一个OP_WRITE事件,以便通知什么时候可以再刷数据了才会继续。不过,当Netty待刷数据太多,超过一定的水位线时,会将可刷的标志位改成false,让应用端自己做决定要不要发送数据了(decrementPendingOutboundBytes)。


Netty批量刷数据时,如果想刷的数据都已经完成了,接下来会尝试写更多,直到没有数据要处理或者次数满16次。当次数满16次后,还没有处理完数据则重新提交一个flush0任务,而不是重新注册事件。这样能减少开销,也能保证多个Request Handler处理的数据量平均或者说负载平均。

四、断开连接


当连接被关闭或者读取异常时都会触发断开连接处理的逻辑,断开连接要做的事情无非是关闭channel、清理消息、触发断开连接事件。也就是javaChannel.close()、outboundBuffer.failFlushed、selectionKey.cancel()、pipeline.fireChannelUnregistered()。

五、关闭服务


通过group.shutdownGracefully()触发修改当前状态为关闭状态。然后在NioEventLoop中判断isShuttingDown条件得到满足,从而触发关闭服务的逻辑。关闭服务时,先不接活后尽量干完手头的活。也就是,关闭时检查是否有需要处理的tasks,如果有则不能关闭。如果没有的话,首先判断是否超过最大”优雅”关闭时间(gracefulShutdownStartTime),如果超过则关闭服务。如果没有超过,还要判断静默期(gracefulShutdownQuietPeriod)是否有任务执行过,如果有也不能关闭,当没有满足关闭条件时,进入下一轮关闭判断。

阅读 12 次