在工作中很少能够碰到内存泄漏的问题,但是一旦遇到了,就是一个比较难解的问题, 本文旨在记录这次在问题排查的过程中,一些思路和排查方向
收到告警后,笔者先登录到告警机器中,
top
命令查看此时此刻的各个应用程序占用的内存大小,
这里其实有两个指标可以查看,
virt是虚拟内存,而 res是进程实际分配的物理内存。一般通过res查看应用内存的物理占用量, 但是你会发现,如果把每个应用程序的res加一起很有可能超过机器总内存,这是因为不同应用程序有可能引用同一个库,此时这个库被缓存,那么这两个应用程序都会将这个库所占用的内存算进去。
这时候发现,我们的node服务占用的内存是在正常范围中。
于是我们又free -g
看了下,发现used占用的内存并不多,但是buffer/cached占用的内存,超过了80%。
buffer/cached 是机器帮我们缓存的文件内容,当内存不足时,有一部分缓存是会被机器给释放掉的,也就是说,机器真正的可用内存应该是
aviliable = free + buffers + cached - 不可清空的缓存
所以不会影响业务,笔者也就长舒了一口气,可以喝杯茶再解决这个问题了。
我们目前已经知道了,是由于我们缓存区内存占用过多的问题,导致了告警,那么其实,想解决这个问题并不难,我们只需要手动释放这一部分缓存的内存就好了。
echo 3 > /proc/sys/vm/drop_caches
但是这并没有真正的解决问题,因为缓存内存过多,大概率是我们代码程序中频繁读取不同的文件,导致系统帮我们缓存下来了。
因为无法直接打印出buffers/cached中缓存的内容,于是笔者开始分析代码中有可能频繁读取文件程序。
我们的程序中有一个任务是,接收不同的url,然后调用puppeteer去分析不同的页面性能。有可能是因为puppeteer在分析网页性能时,将文件缓存了下来。
于是我们想看下是否是puppeteer占用了大量的内存,我们将puppeteer装在了docker镜像中,来解决线上线下puppeteer版本的一致性以及降低线上不同机器安装puppeteer的成本。
于是我们docker ps
后拿到docker的容器id,
/sys/fs/cgroup/memory/docker/[containerid]/memory.usage_in_bytes
查看这个容器id所占用的内存并不多,发现并不是这个问题引起的。
既然cached中缓存文件过多,那么我们应该能够通过磁盘被占用的大小找出被缓存的文件,进而找到有问题的程序,毕竟12g的文件不是那么好藏的。
于是笔者在根目录下
du -sh *
发现log目录下的文件有6g,因此笔者怀疑有可能是linux将log文件缓存了下来,于是笔者将backup的log文件删除掉了,发现cached并没有减少。
问题排查到这里,笔者其实也没有什么思路了,但是这排查过程中,有两个问题,还需要确认
strace pid
跟踪一个node进程id,看看一个任务进入后,会发生什么。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。