前言
netty通过设置autoread,和高低水位设置iswritable控制客户端服务端读写速率。
一.控制速率原理
netty的io不适合做耗时长的操作,由于注册到同一个eventLoop中的io连接共同使用线程池,这样耗时的连接会影响其他连接的读写。一般会将耗时的操作添加到业务线程池执行,不阻塞io线程。当读写频率过高,线程池处理不过来时,需要关掉读取事件,避免造成数据丢失(线程池拒绝策略)。
此时,autoread设置为fasle可以取消掉通道上的读事件,此时只是不会从socket内核层的read buffer中处理数据,客户端还在写数据时,read buffer就会满了。因为TCP默认就是带flow control的,read buffer变小之后,向对端发送ACK的时候,就会降低窗口大小,直至变成0,这样对端就会自动的降低发送数据的速率了。等到我们又可以处理数据了,我们就可以将autoread又打开这样数据又源源不断的到来了。
相对于客户端还在写数据,前文《netty的pipeline和数据读写》提到会写入到ChannelOutboundBuffer中,如果由于服务端autoread为false,会导致客户端写不出数据,然后堆积在ChannelOutboundBuffer中,导致内存暂用过多甚至OOM。此时,可以通过前文说到的bootstrap.childOption(WRITE_BUFFER_HIGH_WATER_MARK, 1024)控制链表(ChannelOutboundBuffer)的大小,大于高水位时isWritable为false,判断这个标志位时停止写入。
二.源码分析
1.autoread控制
2.iswritable控制