乐趣区

关于node.js:Nodejs-应用高-CPU-占用率的分析方法

咱们在本地运行 Node.js 利用,应用 --inspect 标记启动应用程序,再次执行负载测试,在 Chrome 浏览器中关上 chrome://inspect:

单击利用下方的 inspect 按钮,而后开始 CPU 占用率剖析:

期待一段时间后,就能看到 CPU profile 的后果:

如何采集生产零碎上的 Node.js 利用性能数据呢?

在大多数状况下,如果性能问题只能在生产零碎重现,那么这种问题剖析起来的确很辣手,因为咱们须要雷同的环境配置、雷同的数据库、缓存等数据。性能问题可能只针对某些类别的用户,因为他们有特定的数据。

在生产环境开启调试模式?这不是一个好的抉择,因为在调试模式下 Node.js 过程会耗费更多资源,而且不平安。

然而有一个更好的办法,应用查看器模块 https://nodejs.org/api/inspec… 按需获取配置文件。它是一个 Node.js 内置模块,开发人员不用装置任何额定的依赖项,但倡议应用 inspector-api .

它是一个带有 Promise 反对的简略包装器。让咱们创立一个记录 CPU 配置文件的端点。

上面是为 NestJS 创立一个示例,对于其余框架,它看起来十分类似:

代码如下:

import {Controller, Post} from '@nestjs/common'
import {promisify} from 'util'
import Inspector from 'inspector-api'

const profileRecordTime = 10000

@Controller('/profile')
export class ProfileController {@Post('/cpu')
  async cpu() {
    // don't wait till recording is finished
    setImmediate(async () => {
      // cpu profile will be saved in temp dir
      const inspector = new Inspector({storage: { type: 'fs'} })
      // enabling and starting profiling
      await inspector.profiler.enable()
      await inspector.profiler.start()
      // wait for 10 seconds and stop
      await promisify(setTimeout)(profileRecordTime)
      await inspector.profiler.stop()
      console.log('CPU profile has been written')
      await inspector.profiler.disable()})

    return true
  }
}

所有代码都用 setImmediate 包裹,因为咱们不须要等到录制完结。让咱们用 curl 测试一下:

curl -X POST http://127.0.0.1/profile/cpu

10 秒之后,咱们在 temp 文件夹失去了 CPU profile 的采集后果:

如果不想将此性能增加为 HTTP 端点,则能够将它们包装在过程信号处理程序中,如下所示:

import {promisify} from 'util'
import Inspector from 'inspector-api'

const profileRecordTime = 10000

process.on('SIGUSR1', async () => {const inspector = new Inspector({ storage: { type: 'fs'} })
  await inspector.profiler.enable()
  await inspector.profiler.start()
  await promisify(setTimeout)(profileRecordTime)
  await inspector.profiler.stop()
  console.log('CPU profile has been written')
  await inspector.profiler.disable()})

process.on('SIGUSR2', async () => {const inspector = new Inspector({ storage: { type: 'fs'} })
  await inspector.heap.enable()
  await inspector.heap.startSampling()
  await promisify(setTimeout)(profileRecordTime)
  await inspector.heap.stopSampling()
  console.log('CPU profile has been written')
  await inspector.heap.disable()})

而后应用 kill 命令发送信号:

  • kill -USR1 ${pid} // for CPU
  • kill -USR2 ${pid} // for Heap
退出移动版