一次 Node.js 内存溢出

作者:何方舟

现象

之前有发现,录播 node 有异常关闭的情况。

我们在1月3日有一次发布,而1月5日凌晨突然挂掉。

分析服务器内存曲线。

对应的详细内存

可以发现服务器内存达到最大值 8G 后就挂掉了,根据发布后内存有明显的上升趋势,且 GC 回收不明显,

初步判定是由于内存泄露导致。

内存分析

我们使用 heapdump 这个库来帮助我们查看内存变量的情况。临时创建一个创建快照的请求地址。

    server.route({
        method: ['GET', 'POST'],
        path: '/now.qq.com/p',
        handler: function (request, reply) {
            heapdump.writeSnapshot(function(err, filename) {  
              console.log('dump written to', filename);
            });
            reply('success')
        }
    });

heapdump 的 writeSnapshot 生成的内存快照文件,可以被 chrome 打开。

通过 ab 进行本地压测:

ab -X 127.0.0.1:8080 -n 1000 -c 100  'http://now.qq.com/h5/record.html?_wv=16778245&_bid=2380&vid=1055_42515315844044863100000000000000&nocache=1'

这些内存快照使用方法可以参考这篇文章:http://taobaofed.org/blog/2016/04/15/how-to-find-memory-leak/

我们对程序开始时和压测结合后的内存快照进行对比,发现存在大量的 string,array 变量未被回收,而其他对象都没有出现明显的堆积。是令人疑惑的是,分析相关的 string 后发现,这些变量并不存在泄露的可能。

考虑到 v8 gc 的方式:

  • 一种是对新生代区的 Scavenge算法,速度块,
  • 一种是对老生区的标记清除算法,由于单线程的原因会导致应用被阻塞。

这些变量依旧存在的原因只可能处于已移到老生区,暂时未被 gc。

分析未宕机前的内存图

内存有一个很健康的折线,可以看出并不存在泄露问题。

但是内存总量却在一个很高值,服务器内存上限是 8G,也就是说内存总量一直处于一个很危险的值。

但是为什么之前没有出现宕机问题呢?

结合 12.15,12.31,1.5 的pv视图。

31日由于活动的原因,录播 pv 涨了三倍,这时可以是因为内存溢出引起的宕机。

结论

因为内存上限设置不合理,引起的内存溢出问题。

之前压测时候只关注了是否存在内存泄露与cpu占用,而忽视了内存占用这个问题。

对于部署服务时,要根据机器的内存上限以及机器CPU核心数合理的设置单服务器的内存上限值。

原文链接:http://ivweb.io/topic/58b50896bd9e855ec2371729

相关推荐

ECMAScript 2015 (ES6) in Node.js(译)

nodejs中错误捕获的一些最佳实践

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Crossin的编程教室

【我问Crossin】编程应该养成那些好习惯?

1 安装好了 python 之后,在cmd 运行却出现这样的情况,该如何处理? ? 配置一下 环境变量即可,方法如下: 在 windows 系统下,依次点击 计...

3265
来自专栏孔德雨的专栏

Mongos 与集群均衡

Mongodb 可以以单复制集的方式运行,client 直连mongod读取数据。单复制集的方式下,数据的水平扩展的责任推给了业务层解决(分实例,分库分表),本...

8.9K3
来自专栏Kirito的技术分享

深入理解 RPC 之集群篇

上一篇文章分析了服务的注册与发现,这一篇文章着重分析下 RPC 框架都会用到的集群的相关知识。 集群(Cluster)本身并不具备太多知识点,在分布式系统中,...

3819
来自专栏Debian社区

协议介绍之深入了解 gRPC

经过很长一段时间的开发,TiDB 终于发了 RC3。RC3 版本对于 TiKV 来说最重要的功能就是支持了 gRPC,也就意味着后面大家可以非常方便的使用自己喜...

3184
来自专栏程序员宝库

从零开始写 PHP 扩展

PHP 是用 C 语言写的。对于每个 PHPer 来说,都有着内心的一种希望写扩展的冲动了吧。然而,缺乏一个很好的切入点。Google 上搜 PHP 扩展开发,...

3497
来自专栏杨建荣的学习笔记

orabbix结合python发送图形报表(二) (r6笔记第38天)

在之前的博文中分享过通过结合python来发送图形报表邮件的例子。 http://blog.itpub.net/23718752/viewspace-177...

3958
来自专栏偏前端工程师的驿站

JS魔法堂:精确判断IE的文档模式by特征嗅探

一、前言                                 苦逼的前端攻城狮都深受浏览器兼容之苦,再完成每一项功能前都要左顾右盼,生怕浏览器不支持...

2069
来自专栏点滴积累

geotrellis使用(三十二)大量GeoTiff文件实时发布TMS服务

前言 在上一篇文章中我讲了如何直接将Geotiff文件发布为TMS服务,在其中只讲了单幅Geotiff的操作,其实单幅这种量级的数据对Geotrellis来说就...

3197
来自专栏Petrichor的专栏

git:git commit 书写格式

  正如 git add 的作用是将文件放入暂存区, git commit 的作用是将修改提交到分支上。

4532
来自专栏马洪彪

Java设计模式(七)Decorate装饰器模式

一、场景描述 (一)问题 系统中最初使用Crystal Report(水晶报表)工具生成报表,并将报表发送给客户端查看,此时定义一CrystalReport工具...

4419

扫码关注云+社区

领取腾讯云代金券