Netty源码-业务流程之写数据

Netty基本介绍,参考 Netty与网络编程

1、源码分析,EchoServerHandler之Write流程

在这里插入图片描述

1.1 write流程入口

通常我们通过ChannelRead收到消息后,需要给一个响应,通过ctx.write()将响应返回客户端。

在自定义handler的channelRead方法打一个断点,客户端发起请求,并进入ctx.write
在这里插入图片描述

1.2 AbstractChannelHandlerContext#write方法

我们看到下图中,先通过findContextOutbound方法找到下一个责任节点再执行。

如果我们自定义方法里用的是ctx.writeAndFlush(写入并发送数据),那么下面就是走第一个分支,否则走第二个分支,继续进入next.invokeWrite
在这里插入图片描述

1.3 invokeWrite写入数据方法

进入了责任链的头节点HeadContext的invokeWrite方法,接着进入invokeWrite0

在这里插入图片描述

1.4 invokeWrite0执行handler写入方法

这里根据handler的类型调用不同的实现类的方法,我们这里是headContext.write方法,继续进入
在这里插入图片描述

1.5 AbstractChannel.AbstractUnsafe#write方法

我们来到AbstractChannel.AbstractUnsafe#write,又是Unsafe类型,Netty的大量读写操作在这个类,进入最后一行的方法addMessage,该方法里面有对写入高水位的判断,

然后再addMessage方法中进入incrementPendingOutboundBytes
在这里插入图片描述

1.6 ChannelOutboundBuffer#incrementPendingOutboundBytes高水位判断

下图,判断待发送的size是不是高于高水位(默认高水位是60M),如果是,那么unwritable设置为false。应用可以根据这个标志决定是否继续发送数据。
在这里插入图片描述

通过CAS操作,设置buffer的unwritable属性:
在这里插入图片描述

1.7 应用层如何处理unwritable标志

如图,应用层可以通过上下文ctx获取可以标志,这个标志最终是从ChannelOutboundBuffer里获取的
在这里插入图片描述
在这里插入图片描述

2、Flush流程

2.1 EchoServerHandler.channelReadComplete

在自定义handler的channelReadComplete方法打一个断点,客户端发起请求,并进入ctx.flush,一直往下走,我们来到DefaultChannelPipeline.HeadContext#flush方法
在这里插入图片描述
在这里插入图片描述

2.2 进入AbstractChannel.AbstractUnsafe#flush0方法

又来到的unsafe的Flush方法,进入doWrite
在这里插入图片描述

2.3 NioSocketChannel#doWrite写操作执行16次

写数据在do-while循环中执行,默认执行16次,writeSpinCount初始是16。如果16次没有完成,截止schedule一个新的flush task出来,而不是注册写事件
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.4 NioSocketChannel#doWrite的while循环

看一下doWrite的while循环

  • 最多返回1024个buffer,总数量尽量不超过maxBytesPerGatheringWrite
  • nioBufferCnt=1 ,单个bytebuffer
  • nioBufferCnt>1 ,批量数据多个bytebuffer。如果缓冲区写满了,注册写事件,启用更多线程来处理
    在这里插入图片描述
    在这里插入图片描述

3.总结

写数据首先通过Write将数据写入Buffer(ChannelOutboundBuffer),然后通过Flush将数据发送出去。写数据包含两个流程Write和flush。

1、Netty写数据太多时,超过一定水位线,会将unwritable标志置为false,应用端根据这个标志决定要不要发送数据

2、只要有数据,就一直写,写到16次,如果还没有写完,会重启一个线程继续写

3、批量写数据是,如果尝试写的都写入了,下次会尝试更多。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值