Netty 流控和流量整形

阅读数:315 评论数:0

跳转到新版页面

分类

python/Java

正文

一、netty客户端流控

1、这几种情况下,如果客户端没有流控保护,很容易发生内存泄露。

(1)网络瓶颈,当客户端发送速度超过网络链路处理能力,会导致客户端发送队列积压。

(2)当对端读取速度小于已方发送速度,导致自身TCP发送缓冲区满,频繁发生write 0字节,待发送消息会在netty发送队列中排队。

(3)当netty服务端并发压力过大,超过服务并发压力过大,超过服务端的处理能力时,channel的消息服务不能及时消费,这时channel堵塞,客户端消息就会堆积在发送队列中。

2、Netty提供了一个高低水位机制,可以实现客户端精准的流控。

io.netty.channel.ChannelConfig#setWriteBufferHighWaterMark 高水位
io.netty.channel.ChannelConfig#setWriteBufferLowWaterMark 低水位
当发送队列待发送的字节数组达到高水位时,对应的channel就变为不可写状态,由于高水位并不影响业务线程调用write方法把消息加入到待发送队列,因此在消息发送时要先对channel的状态进行判断(ctx.channel().isWritable)。
 
当消息队列中积压的待发送消息总字节数到达高水位时,修改Channel的状态为不可写,并发送通知事件;当消息发送完成后,对低水位进行判断,如果当前积压的待发送字节数低于低水位时,则修改channel状态为可写,并发送通知事件

二、netty服务端 流量整形

1、原理

拦截channel的read和write方法,计算当前需要发送的消息大小,对读取和发送阈值进行判断,如果达到了阈值,则暂停读取和发送消息,待下一个周期继续处理,以实现在某个周期内对消息读写进行控制。

2、使用

Netty内置了三种流量整形功能:

(1)单个链路的流量整形

ChannelTrafficShapingHandler,可以对某个链路的消息发送和读取速度进行控制。

(2)全局流量整形

GlobalTrafficShapingHandler,针对某个进程所有链路的消息发送和读取速度的总和进行控制。

(3)综合流量整形

GlobalChannelTrafficShapingHandler,同时对全局和单个链路的消息发送和读取速度进行控制。

3、注意事项

(1)GlobalChannelTrafficShapingHandler和GlobalTrafficShapingHandler是全局共享的,因此实例只需要创建一次,添加到不同的ChannelPipeline即可,不需要创建多个实例,否则流量整形将失效。

(2)流量整形参数调整不要过于频繁。

(3)通过流量整形可以控制发送速度,但是它的控制原理是将待发送的消息封装成Task放入消息队列,等待执行时间到达后继续发送,所以如果业务线程不判断channel的可用状态,就可能导致OOM问题。




相关推荐

Java NIO根据操作系统不同,比如macosx是KQueueSelectorProvider、windows有WindowsSelectorProvider、Linux有EPollSelec

Netty提供了丰富的解码器抽象基类:主要分为两类: (1)解码字节到消息(ByteToMessageDecoder和ReplayingDecoder) (2)解码消

一、概述 Netty的强大的地方,是他能方便的实现自定义协议的网络传输。Netty基于Reactor模式:http://1024s.top/mbstudy/mbBlog/blogDetail?blog

netty提供了6种不同的websocket类型: (1)BinaryWebsocketFrame,二进制数据类型 (2)TextWebSocketFrame,文本数

一、概述 在计算机中,我们以字节为单位,一个字节为8bit。 而数据存储中的字节顺序多取决于硬件设计,即所谓的大端存储和小端存储。Intel处理器使用小端存储,PowerPc的处理器采用大端存储。 当

一、Channel的四大类型 1、FileChannel FileChannel是操作文件的Channel,可以通过FileChannel从一个文件中读取数据,也

ByteBuf是对字节的封装,有基于堆内存和直接内存。若是堆内存,应用程序无需考虑什么时候释放,因为GC是帮助做,如果是直接内存,那么需要主动释放。 每个ByteBuf对象都有一个引用计数,当这个数值

Netty中的HashedWheelTimer可以用于提交延迟任务,Java里的Time组件也具备相同的功能,不过Time是基于执行是基于优先队列实现的,相当于需要对所有的任务基于执行的时间排个

LineBasedFrameDecoder以换行符\n或\r\n作为依据,遇到\r\n都认为是一条完整的消息。 而DelimiterBasedFrameDecoder允许我们指定任

HttpServerCodec HtttpServerCodec只能处理像http get的请求,也就是数据带在url问号后面的http请求。 GET请求包括两部