Netty中Channel的isWritable方法理解

目录

初见  

深入

需要注意

对待超SIZE情况开源项目怎么做

1、seata中

2、SUMMER中

3、一些资料中

 总结


初见  

以下是包中注释

Returns true if and only if the I/O thread will perform the requested write operation immediately. Any write requests made when this method returns false are queued until the I/O thread is ready to process the queued write requests.

当且仅当I/O线程立即执行请求的写操作时,返回true。当这个方法返回false时,任何写请求都会排队等待,直到I/O线程准备好处理排队的写请求。

 刚开始接触到它是因为服务端给我断连,再写入时必然是不可写报错的(当时没区分isActive和isWritable,看了前辈的代码直接使用的是isWritable,此时是没区分场景的)。

后来测试中发现,发送流量过大时,isWritable仍然会返回false,然后对它就进行更进一步了解

深入

debug通过源码看

通常情况下,我们会使用writeAndFlush发送消息。它的具体流程是写入时会生成 WriteTask,交由 IO 线程处理,write 操作将消息写入 ChannelOutboundBuffer,最后再将 ChannelOutboundBuffer 缓冲区写 入socket 的发送缓冲区;

在创建WriteTask时初始化会调用incrementPendingOutboundBytes方法,去判断更改isWritable中判断要素变量ChannelOutboundBuffer中的unwritable。判断要素则为可配置的WriteBufferHighWaterMark(高水位线)

以上就是原理,通俗来说就是如ChannelOutboundBuffer中有一个缓冲区,这个缓冲区设有高位线和低位线,当 buffer 的大小超过高水位线的时候对应 channel 的 isWritable 就会变成 false,当 buffer 的大小低于低水位线的时候,isWritable 就会变成 true。writeAndFlush时会增加缓冲区大小。

需要注意

每次writeAndFlush时可以不判断channel的isWritable状态,但是根据我们通过简介也知道。当isWritable()方法返回false时,这意味着缓冲区已经被填满,无法再写入更多数据,此时如果强制写入数据会导致阻塞,一直阻塞,数据量特别大时会造成OOM。

对待超SIZE情况开源项目怎么做

我简单查看了以下github和资料,大致有以下做法,简单看了看,有错误请指出。

其中不乏有不处理只打印日志的,单总感觉差点意思。

1、seata中

Netty中Channel的isWritable方法理解_第1张图片

Netty中Channel的isWritable方法理解_第2张图片

 异步加阻塞方式

2、SUMMER中

Netty中Channel的isWritable方法理解_第3张图片

Netty中Channel的isWritable方法理解_第4张图片 阻塞队列,在监听write事件上,再处理。

3、一些资料中

出处:如何解决 Netty Channel.isWritable 返回 false-CSDN博客

Netty中Channel的isWritable方法理解_第5张图片

 总结

对待超BUFFER情况,还是要根据业务具体分析,合理计算、配置资源,比如限流什么的。

你可能感兴趣的:(NIO,java,netty)