1. 前言
在近期研读芋道源码对Netty代码的解析过程中,其中提及Netty在执行写入操作时进行了优化处理。通常情况下,SocketChannel
能够直接完成数据写入,但如果写入的数据量过大(如写入大文本文件)或者客户端读取能力较弱,就容易导致写入缓冲区溢出,进而造成数据丢失。
2. 优化方案
2.1 尝试写入Channel
Netty首先尝试调用NioSocketChannel#write(ByteBuf)
方法执行写入操作,若写入失败(即返回结果为0),则执行写入不完整标记操作。则为当前的SelectionKey
注册SelectionKey.OP_WRITE
事件,以便后续继续处理写入操作。
2.2 Channle注册SelectionKey.OP_WRITE
若当前Channel
缓冲区已满,无法执行写入操作,则给当前Channel注册SelectionKey.OP_WRITE
事件。
2.3 写入判断
当Channel
调用flush0()
执行写入操作时,会判断当前Channel是否注册了SelectionKey.OP_WRITE
事件,若注册了SelectionKey.OP_WRITE
事件,则表明当前Channel
写入缓冲区已满,无需执行写入操作。
2.4 继续写入
当Selector
发现Sokcet
可写入时,会尝试调用forceFlush()
,将前序数据写入缓冲区。