前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一文搞定Netty写数据高性能原理

一文搞定Netty写数据高性能原理

作者头像
JavaEdge
发布2021-02-23 15:19:20
1940
发布2021-02-23 15:19:20
举报
文章被收录于专栏:JavaEdgeJavaEdge

1 写数据的核心问题

快递场景(包裹)

Netty写数据(数据)

揽收到仓库

write:写到一个buffer

从仓库发货

flush:把buffer里的数据发送出去

揽收到仓库并立马发货( 加急件)

writeAndFlush: 写到buffer, 立马发送

揽收与发货之间有个缓冲的仓库

Write和Flush之间有个ChannelOutboundBuffer

1.1 写炸了

对方仓库爆仓时,送不了的时候,会停止送,协商等电话通知什么时候好了,再送。 Netty写数据,写不进去时,会停止写,然后注册一个 OP_WRITE事件,来通知什么时候可以写进去了再写。

1.2 挺能写的

发送快递时,对方仓库都直接收下,这个时候再发送快递时,可以尝试发送更多的快递试试,这样效果更好。 Netty批量写数据时,如果尝试写的都写进去了,接下来会尝试写更多(调整maxBytesPerGatheringWrite)

1.3 我还能写

发送快递时,发到某个地方的快递特别多,我们会连续发,但是快递车毕竟有限,也会考虑下其他地方

Netty只要有数据要写,且能写的出去,则一直尝试,直到写不出去或满16次(writeSpinCount)

写16次还没有写完,就直接 schedule 一个 task 来继续写,而不是用注册写事件来触发,更简洁有力。

1.4 写不过来了

揽收太多,发送来不及时,爆仓,这个时候会出个告示牌:收不下了,最好过2天再来邮寄吧。

Netty待写数据太多,超过一定的水位线(writeBufferWaterMark.high()) ,会将可写的标志位改成 false,让应用端自己做决定要不要发送数据(写)了(很真实,将责任推给用户)。

2 核心流程

Write - 写数据到buffer : ChannelOutboundBuffer#addMessage

Flush -发送buffer里面的数据: AbstractChannel.AbstractUnsafe#flush

  • 准备数据: ChannelOutboundBuffer#addFlush

写完了更新状态

发送: NioSocketChannel#doWrite

3 写数据的根本

Single write sun.nio.ch.SocketChannelmpl#write(java.nio.ByteBuffer)

gathering write(批量写) sun.nio.ch.SocketChannelmpl#write(java.nio.ByteBuffer[], int, int)

写数据写不进去时,会停止写,注册一个 OP_WRITE 事件,来通知什么时候可以写进去了。 OP_WRITE不代表有数据可写,而是可以写进去,所以正常情况下不要注册它,否则会一直触发。

channelHandlerContext.channel().write() 从TailContext开始执行

channelHandlerContext.write() 从当前的Context开始

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-12-28 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档