Netty 流控和流量整形
阅读数:429 评论数: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 低水位
二、netty服务端 流量整形
1、原理
拦截channel的read和write方法,计算当前需要发送的消息大小,对读取和发送阈值进行判断,如果达到了阈值,则暂停读取和发送消息,待下一个周期继续处理,以实现在某个周期内对消息读写进行控制。
2、使用
Netty内置了三种流量整形功能:
(1)单个链路的流量整形
ChannelTrafficShapingHandler,可以对某个链路的消息发送和读取速度进行控制。
(2)全局流量整形
GlobalTrafficShapingHandler,针对某个进程所有链路的消息发送和读取速度的总和进行控制。
(3)综合流量整形
GlobalChannelTrafficShapingHandler,同时对全局和单个链路的消息发送和读取速度进行控制。
3、注意事项
(1)GlobalChannelTrafficShapingHandler和GlobalTrafficShapingHandler是全局共享的,因此实例只需要创建一次,添加到不同的ChannelPipeline即可,不需要创建多个实例,否则流量整形将失效。
(2)流量整形参数调整不要过于频繁。
(3)通过流量整形可以控制发送速度,但是它的控制原理是将待发送的消息封装成Task放入消息队列,等待执行时间到达后继续发送,所以如果业务线程不判断channel的可用状态,就可能导致OOM问题。