Nuxt SSR Axios v0.21 内存泄漏问题排查
最近同事反馈官网的 SSR 应用又有了 OOM 现象。
运行一段时间之后内存占用上升,直至重启。
异常现象
-
容器内打印了很多包含异常的日志,其中存在很多代理的 error。
-
很多超时日志。
初步排查
由于之前尝试接入过 alinode 但是需要定制容器,而且更新缓慢,并且 node 的某个版本存在内存泄漏的问题,故自建一个开源的内存监控。
应用接入监控后,过了大概2天,内存打到1.4g 。
让运维新启用一个新实例,导入流量到新实例。
在监控平台保存 heapsnapshot 和 heapprofile 。
发现 processTicksAndRejectionsinternal 和 zlib_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"
相关链接
特别鸣谢
感谢以下用户对本文的支持与鼓励