猫猫说了算
理解是偶然,误解是常态。

Nuxt SSR Axios v0.21 内存泄漏问题排查

远浅发表于: 2021-05-24 21:33分类: 技术

最近同事反馈官网的 SSR 应用又有了 OOM 现象。

运行一段时间之后内存占用上升,直至重启。

异常现象

  1. 容器内打印了很多包含异常的日志,其中存在很多代理的 error。

  2. 很多超时日志。

初步排查

由于之前尝试接入过 alinode 但是需要定制容器,而且更新缓慢,并且 node 的某个版本存在内存泄漏的问题,故自建一个开源的内存监控。

应用接入监控后,过了大概2天,内存打到1.4g 。

让运维新启用一个新实例,导入流量到新实例。

在监控平台保存 heapsnapshot 和 heapprofile 。

发现 processTicksAndRejectionsinternalzlib_memory 在分析工具中资源占用了极高的比重。

初步怀疑是 SSR 渲染过程中请求数据出现了太多异常,累积之后导致 OOM。

初步修复

由于之前应用中日志太多导致无法定位问题,于是使用了一个 babel 插件清空了没必要的日志输出。

同时排查发现应用在 store 的 nuxtServerInit 中请求了过多的数据,并且没做容错处理。

于是迁移了部分数据到组件内部进行请求,减少了没必要的消耗。

继续修复

经过初步修复之后,内存泄漏的问题有所缓解,但是还是存在。

并且惊奇的发现,服务端还是会输出一些异常日志。

error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason:

Error: timeout of 10000ms exceeded

    at createError (/usr/src/app/node_modules/axios/lib/core/createError.js:16:15)

    at RedirectableRequest.handleRequestTimeout (/usr/src/app/node_modules/axios/lib/adapters/http.js:280:16)

    at RedirectableRequest.emit (events.js:376:20)

    at RedirectableRequest.emit (domain.js:532:15)

    at Timeout._onTimeout (/usr/src/app/node_modules/follow-redirects/index.js:166:12)

    at listOnTimeout (internal/timers.js:555:17)

    at processTimers (internal/timers.js:498:7)



 ERROR  timeout of 10000ms exceeded

这个日志属于框架内部错误,非应用输出,且接口我都做了 catch 处理。

这个日志让我想到一种可能,就是 Axios 请求库在服务端可能存在内存泄漏的问题,socket内存泄漏?

只有当请求产生异常的时候才会发生,我们后端的接口经常超时可能放大了这个内存泄漏的问题。

于是随手复制了一下 follow-redirects 搜索这个库,发现这是 Axios 的底层依赖库。

然后发现了大量 memory leaks 相关主题。

并且在当前最新版 Axios v0.21 得到确认, 将会在 v0.22 得到修复。

问题解决方案

最好的方案当然是让接口快点响应。

嘻嘻嘻! 10秒钟都不响应的接口也是没谁了。

目前的临时方案是使用 npm resolutions 强制依赖 "follow-redirects": "1.14.1"

相关链接

follow-redirects/issues/156

axios/pull/3771

speedscope 可视化工具

赠人玫瑰, 手有余香。🌹
打赏
特别鸣谢
感谢以下用户对本文的支持与鼓励
加载打赏用户中
发表评论
文章评论
暂无任何评论,快去发表吧~