掘金 后端 ( ) • 2024-05-09 10:58

一、问题暴露

有个worker服务(非web server 的常驻进程),收到了监控系统的内存使用告警

Xnip2024-04-21_15-23-36.jpg 从代码中没看出问题(未排查最近的commit,因为这个有内存泄露有段时间了),然后就接入easymonitor排查内存使用。

二、问题定位

  1. 在easymonitor中对实例生成堆快照

image.png 注意:一台机器上有多个进程的话,如果已经确定是哪个进程存在内存泄露,请在右侧进程列表中切换进程

  1. 使用easymonitor中的分析功能

这个cache对象后面还有非常多的属性,看起来是一直在写入但没有释放(或者没有及时释放)。出于对项目的了解,从properties的html这里大概了解到是什么功能模块的问题了,但还需要进一步定位代码。

  1. 使用devtools查看堆快照文件

其他的properties也都指向了这个文件,那我们去看一下这个文件吧

三、问题解决

先查看mustache index.js源码

mustache中就cache对象,源码也有这个对象的作用说明,看起来好像也合理。 我们的项目中是如何使用mustache的?

到这里,如果只看代码,问题还不太明显。结合业务来看,mustache会缓存template,但我们的场景,可以认为每次传入的template都是不同的,没有什么缓存的价值。而且template的数量很大,每天有接近2万条,字符串的长度也不小。这时候整体来看mustache的缓存设置,就有些不合理了,内部只有主动增加缓存,没有主动释放缓存。这就需要工具的使用者,根据使用情况,自行管理缓存。 我们要如何释放mustache的缓存?

mustache对外提供了一个清理缓存的方法,需要我们自行调用。

鉴于我们的template没什么缓存的必要,直接在模板渲染后清理缓存就行

我们使用的是mustache v3,最新版本是v4,都是需要使用方自行清理缓存,就先不升级了。

当然,更换一个不缓存的模板工具也可以,可能有更适合这个场景的工具,但就可能涉及到模板、参数的变化,没有太大动力。

发布修复后的版本,后续的内存使用情况如下图: Xnip2024-05-08_21-35-48.jpg