Netty发送队列积压导致内存泄露怎么办

发布时间:2021-12-28 15:39:59 作者:小新
来源:亿速云 阅读:380

这篇文章主要为大家展示了“Netty发送队列积压导致内存泄露怎么办”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Netty发送队列积压导致内存泄露怎么办”这篇文章吧。   

正文

导致Netty内存泄漏的原因有很多,例如,使用内存池创建的对象忘记释放,或者对端系统服务压力过大导致发送队列积压。

尽管Netty采用NIO非阻塞通信,I/O往往不是系统性能的瓶颈,但是如果服务端处理速度有限,客户端发送数据量很大,没有做好流控,同样会导致内存溢出。

对某个业务做性能压测,基于Netty开发的多个客户端并发链接一个服务端,客户端运行一段时间后,内存、CPU占用率居高不下,响应越来越慢,最后自动宕机。

Netty发送队列积压导致内存泄露怎么办


为了方便分析,这里简化代码,这里用一个死循环向服务端发送消息,模拟压测环境,客户端代码如下:

Netty发送队列积压导致内存泄露怎么办


Netty发送队列积压导致内存泄露怎么办                  

Netty发送数据源码分析

业务调用ChannelHandlerContext.write方法后,经过ChannelPipeline责任链处理,消息被投递到了发送缓冲区中待发送,调用flush后才真正发送。

writeAndFlush方法,内部调用的是write方法,代码如下

Netty发送队列积压导致内存泄露怎么办


跟进write()方法,处理逻辑如下,首先判断当前线程是否是NioEventLoop,如果不是,将发送的数据封装成一个WriteTask,放入NioEventLoop的任务队列由NioEventLoop线程执行。

Netty发送队列积压导致内存泄露怎么办

Netty发送队列积压导致内存泄露怎么办


在execute里做同样的判断后,在这里走的是else分支,调用addTask()后,将任务添加到任务队列中

Netty发送队列积压导致内存泄露怎么办


Netty的NioEventLoop线程内部维护了一个Queue<Runnable> taskQueue,除了处理网络I/O读写事件,同时还负责网络读写相关的Task。

Netty发送队列积压导致内存泄露怎么办


经过一系列处理后,消费端在拿到数据后,最终会调用ChannelOutboundBuffer的addMessage方法,将消息加入到发送队列。学过数据结构的同学,可以很清楚的看到,这个发送队列是基于链表组织起来的。

Netty发送队列积压导致内存泄露怎么办


请注意方法结尾调用的incrementPendingOutboundByte方法,会在后面分析。文章开头描述的现象与此方法有关。

Netty发送队列积压导致内存泄露怎么办                  

如何防止发送队列积压

为了防止高并发场景下,由服务端处理慢导致客户端消息积压,除了服务端做流控外,客户端也需要做流控,自身保护,方法是,设置待发送队列的高低水位。

方法有两种,第一种是在启动类里设置option属性

Netty发送队列积压导致内存泄露怎么办

第二种是

Netty发送队列积压导致内存泄露怎么办

当发送队列到达高水位时,对应的Channel就会变为不可写状态。由于高水位并不影响业务线程调用write方法把消息写入待发送队列,因此必须在消息发送时对Channel的状态进行判断。


为了对待发送队列发送速度的控制,Netty提供了高低水位的机制,当积压消息量达到高水位时,修改Channel为不可写状态,在ChannelOutboundBuffer类

Netty发送队列积压导致内存泄露怎么办


修改Channel状态后,调用ChannelPipeline发送通知消息

Netty发送队列积压导致内存泄露怎么办


当积压消息发送完成后,对低水位进行判断,如果待发送字节数到达或低于低水位,修改Channel状态为可写,并发送通知事件。代码如下

Netty发送队列积压导致内存泄露怎么办


针对上述分析后,再回头看文章开头描述的问题,我们修改代码为如下格式然后再压测,允许一段时间后 ,系统稳定。

Netty发送队列积压导致内存泄露怎么办


内存消耗如下,可见运行非常稳定

Netty发送队列积压导致内存泄露怎么办

以上是“Netty发送队列积压导致内存泄露怎么办”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注亿速云行业资讯频道!

推荐阅读:
  1. 查看kafka消息队列的积压情况
  2. Exchange 2016 邮件在队列中不能发送

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

netty

上一篇:如何使用netty开发

下一篇:Netty每次读取客户端数量有多少

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》