问题

最近在公司维护nuxt项目时,线上遇到了一个问题——访问网站,网站会报502或者JS、css资源报502。

去运维那一查pm2,项目node服务器的CPU达到了100%,实际上这段时间并没有人访问,那是为什么CPU会100%从而导致node服务器无法正常运行?

 

分析

太多的分析就不说了,期间向几个方向都排查过:

  • nuxt社区有人说是nuxt框架问题,某些版本会出现node服务端内存泄漏。
  • 第三方组件未在destroy时进行释放,或者事件监听,页面关闭后未解绑事件。
  • 代码的书写问题,闭包引起的内存泄漏。
  • 用谷歌浏览器工具分析网站内存使用情况,发现大量Vue.component组件未释放。
  • 官网说SSR最好不要使用Vue.use()和 Vue.component(),这会导致内存泄漏(官网链接)。

我们可以得出大概率是node服务端内存泄漏,导致CPU缓慢升高,每请求一次网站页面都会造成重复的代码块积累在服务端,并且不会释放。

 

解决

我们找到项目中使用Vue.use()的地方,并打log查看。

import Vue from 'vue'
import Errors from '@/components/custom/Errors'

export default () => {
  Vue.use(Errors)
  console.log(Vue, 'logVue');
}

多次刷新页面,我们可以看到在控制台看到node服务端的log情况。搜索Errors,有大量重复的Errors组件,实际上只需要一个Errors组件就够了。

找到了问题,接下来就好办了。在Vue.use() 注册时检查服务端是否注册过,如果注册过,就不再注册:

import Vue from 'vue'
import Errors from '@/components/custom/Errors'

export default () => {
  if (Vue._use_components) {return}
  Vue._use_components = true
  Vue.use(Errors)
  console.log(Vue, 'logVue');
}

可以看到打印出来的log,多次刷新请求服务器,Errors组件也不会被多次注册了。

 

总结

1、用到第三方组件在页面生命周期结束前destroy释放,

2、事件监听,生命周期结束前解绑事件。

3、接下来只需要将用到 Vue.use()和Vue.component()地方的代码加上判断优化。

4、冗余保护:因为我们的CPU设置的是1024M,所以我们在pm2加上:

"max_memory_restart": "1000M"

如果CPU达到1000M内存阈值,则重新启动。

优化后项目CPU运行情况:

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐