iis worker process内存占用大_NodeJS在cluster模式下内存超限重启

aa18444d03e42755d88b4e584023d565.png

为何要进行内存超限重启

在代码层面,我们有很多种方式来防止NodeJS在执行的过程中出现内存泄露。但是当业务逻辑复杂的情况下,很难做到完全无内存泄露。这时候,一个偷懒的办法就是要让服务进程在超过一定内存阈值的时候重启。

直接杀死进程的方式是不推荐的,因为会影响正在处理中的 request。在 cluster 模式下,node对每一个 fork 出的子进程提供了优雅的退出方式:

cluster

他会保证子进程退出前处理完所有正在进行中的 request。

所以,我们可以在内存超出一定阈值的时候,调用disconnect方法。

如何检测子进程内存占用量

使用usage模块可以检测进程内存占用量(PS,在 node 0.12 版本下未能安装,在 4.x 版本下可以):

usage.lookup(process.pid, function(err, result) {

if 

});

在内存超限时重启

在内存超过一定阈值的情况下重启子进程的 cluster 模式下的进程管理的代码如下:

//in memory.js

代码里有两个注意点:

注意点A

其实这里是参考了 domain 的文档:Node.js v7.9.0 Documentation,我们这里设置若干秒后将进程推出。

但是我们发现,这里调用了 killtimer.unref(),这里是为了防止定时器的存在阻止程序退出(PS:国内几乎所有的书都在说 unref 的作用是阻止回调调用,其实不然,timer 的 unref 函数)。

注意点B

disconnect调用时,我们就要 fork 出新的子进程,但是有些情况下,进程会意外退出。在意外退出时,我们也要 fork 新的子进程补位,这时候就要区分到底是意外退出还是程序退出,否则就会 fork 冗余的子进程。

cluster 的官方文档有说明可以通过worker.suicide和worker.exitedAfterDisconnect来判断进程是否是意外退出,但遗憾的是,node 的某些中间版本因为 bug (比如 4.x)失去了对这两个flag的支持,所以这里我们通过自己设置标志位isSuicide来判断是否意外退出。

使用方法

直接调用 export 出的 run 方法,设置超限阈值,设置子进程服务,设置重启回调:

var 

这里要注意的是,内存的阈值要低于总内存/进程数,要给重启时 fork 的新进程(因为那时候的老进程还未退出)以及系统上的其他服务留有内存空间。

最后一句话:重启大法虽然好,但是也要防止内存泄露。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值