目录
初见
深入
需要注意
对待超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中
异步加阻塞方式
2、SUMMER中
阻塞队列,在监听write事件上,再处理。
3、一些资料中
出处:如何解决 Netty Channel.isWritable 返回 false-CSDN博客
总结
对待超BUFFER情况,还是要根据业务具体分析,合理计算、配置资源,比如限流什么的。