nodejs+docker 内存泄露问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
yuyuyu
V2EX    Node.js

nodejs+docker 内存泄露问题

  •  
  •   yuyuyu 2017-03-23 13:38:29 +08:00 4682 次点击
    这是一个创建于 3200 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我有一个 centos 的容器里面运行的是 pm2-docker ,然后 pm2-docker 运行了一个 nodejs 程序,现在时不时会出现系统内存被吃光的问题,看 top 里 node 的内存占用 10%左右, pm2 list 看启动的 nodejs 程序也只有 100M 左右,实际系统已经被吃掉 90%的内存开始出现性能警告了,只要我重启下这个容器,系统内存就降下来正常了,这种情况是什么造成了内存泄露?我写的 nodejs 么?

    27 条回复    2018-04-11 10:53:39 +08:00
    hpeng
        1
    hpeng  
       2017-03-23 13:48:19 +08:00 via iPhone
    一般来说是的,你可以 docker 启动限制容器内存
    yuyuyu
        2
    yuyuyu  
    OP
       2017-03-23 13:55:05 +08:00
    @hpeng 我是想找出内存泄露,限制内存重启容器都不是解决方法……
    xujialiang
        3
    xujialiang  
       2017-03-23 13:57:44 +08:00
    那你试试不要用 pm2 docker ,我容器跑 nodejs ,貌似没发生这种问题。
    yuyuyu
        4
    yuyuyu  
    OP
       2017-03-23 14:00:11 +08:00
    @xujialiang 我试试 , google 过 nodejs 内存相关的东西,都是 top 和 pm2 list 就能看到内存暴涨,但我这里的情况是 top 和 pm2 list 看内存占用都非常正常,比较迷
    unclechan
        5
    unclechan  
       2017-03-23 15:37:09 +08:00
    有可能是 pm2 本身占用内存过多,我以前遇到过 pm2 莫名占用 cpu 很高的问题,不知道是不是 bug
    chairuosen
        6
    chairuosen  
       2017-03-23 15:41:28 +08:00
    我遇到过 pm2 自己 cpu 太高崩掉的问题,发现是 0.10node 时装的 pm2 跑在 6.几 node 里导致的,更新了 Pm2 就好了
    WildCat
        7
    WildCat  
       2017-03-23 15:43:29 +08:00
    既然用 docker 了,最佳实践应该直接启动 node app 而不是用 pm2 吧?
    (新手
    WildCat
        8
    WildCat  
       2017-03-23 15:43:37 +08:00
    (我是新手
    otakustay
        9
    otakustay  
       2017-03-23 15:43:41 +08:00
    用 top 看内存正常说明这些内存已经和 node 这个进程无关了,就算用 profile 都查不出来,只能瞎猜了,先去掉 pm2 看看能不能正常,不行再去掉几个功能模块半分法找?
    yuyuyu
        10
    yuyuyu  
    OP
       2017-03-23 15:52:18 +08:00
    @unclechan
    @chairuosen

    我没有去掉 pm2 ,在执行 docker exec web pm2 restart all 以后内存恢复正常……大概还是我的程序有问题吧

    @otakustay

    我也找不到其他占用内存多的程序……那泄露的内存就完全看不到到哪去了?

    我现在试试 heapdump
    fyibmsd
        11
    fyibmsd  
       2017-03-23 16:30:14 +08:00
    docker 里为啥还要用 pm2
    otakustay
        12
    otakustay  
       2017-03-23 18:57:55 +08:00
    @fyibmsd pm2 深入进程的监控能提供很多操作系统层面拿不到的信息
    yuyuyu
        13
    yuyuyu  
    OP
       2017-03-23 19:53:10 +08:00 via Android
    @otakustay 能详细说说么
    yuyuyu
        14
    yuyuyu  
    OP
       2017-03-23 21:38:14 +08:00
    通过 heapdump 收集了内存快照,在内存暴涨的时候, heapdump 出来的快照最多也就 22M ,里面最大的 shallow size 也只有几 M ,引用的包就这些:
    ```
    "dependencies": {
    "babel-runtime": "6.x.x",
    "bluebird": "3.3.5",
    "heapdump": "^0.3.7",
    "log4js": "^0.6.37",
    "mysql": "^2.11.1",
    "sequelize": "^3.23.3"
    },
    ```
    对,用了 babel+bluebird ,然后程序里很多 await
    denghongcai
        15
    denghongcai  
       2017-03-23 22:36:55 +08:00
    你是不是跑在 docker 里打日志了? docker 版本多少?
    yuyuyu
        16
    yuyuyu  
    OP
       2017-03-23 22:41:59 +08:00
    @denghongcai
    确实会打日志 Docker 版本 Docker version 1.13.1, build 092cba3
    yuyuyu
        17
    yuyuyu  
    OP
       2017-03-23 22:47:47 +08:00
    @denghongcai 我只是直接通过 console.log 输出日志
    mooncakejs
        18
    mooncakejs  
       2017-03-23 23:24:28 +08:00 via iPhone
    echo 1 > /proc/sys/vm/drop_caches 可以释放掉。应该是内存碎片吧
    yuyuyu
        19
    yuyuyu  
    OP
       2017-03-23 23:26:06 +08:00
    @mooncakejs 试了下内存丝毫没变, 2 、 3 也试过
    mooncakejs
        20
    mooncakejs  
       2017-03-23 23:46:37 +08:00 via iPhone
    @yuyuyu 在宿主机里使用的?
    mooncakejs
        21
    mooncakejs  
       2017-03-23 23:47:09 +08:00 via iPhone
    @yuyuyu 我碰到过吃内存的情况。宿主机里可以清掉
    yunshansimon
        22
    yunshansimon  
       2017-03-24 00:21:03 +08:00
    nodejs 如果创建了独立的子进程,子进程内有 listener 之类的,它不会在完成任务后主动关闭,需要父进程发信号关闭。如果父进程在关闭自己的子进程之前就被关闭了,子进程就变成孤单的进程了,它会自己运行,谁都不属于,被占的内存也不会被释放。因此,必须在创建子进程的父进程内建立子进程列表,在父进程关闭前,向所有子进程发送强制关闭的消息。所以,子进程就跟名字一样,谁生的,谁必须负责到底。
    yuyuyu
        23
    yuyuyu  
    OP
       2017-03-24 08:23:13 +08:00 via Android
    @mooncakejs 嗯,是在宿主机执行的
    yuyuyu
        24
    yuyuyu  
    OP
       2017-03-24 08:27:01 +08:00 via Android
    @yunshansimon 但是我这没有创建任何子进程,整个程序很简单就一个 httpserver ,然后会执行 http.request 去请求数据返回给客户端,就是业务内部的一个 http 中转程序
    denghongcai
        25
    denghongcai  
       2017-03-27 09:53:05 +08:00
    Node 进程内存占用不大,但是 Docker 进程占用大吧

    把 console.log 改成向文件输出日志,在 Docker 容器了往 stdout 打日志会内存泄露,我时常碰到,但是每次 Docker 那边都没修好
    yuyuyu
        26
    yuyuyu  
    OP
       2017-03-27 10:39:44 +08:00
    @denghongcai 没有, docker 进程内存也正常,没有哪个进程占用很大的内存,都挺正常的,给我的感觉就是内存消失了……然而只要重启 nodejs 的那个容器内存就回来了,打日志的我也去掉了,问题依旧
    lyzlyz
        27
    lyzlyz  
       2018-04-11 10:53:39 +08:00
    请问这个问题解决了吗?我跟你遇到了一摸一样的问题,也是 docker 中使用 pm2 运行 nodejs,内存会缓慢的上升直到 100%
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5169 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 07:43 PVG 15:43 LAX 23:43 JFK 02:43
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86