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(),将前序数据写入缓冲区。
