你所未知的3種 Node.js 代碼優化方式

Node.js 程序的運行可能會受 CPU 或輸入輸出操做的限制而十分緩慢。從 CPU 角度看,程序運行緩慢的典型緣由之一就是未經優化的「熱點路徑」(一段常常被訪問的代碼)。從輸入輸出角度看,程序運行速度的侷限多是受底層操做系統影響,也多是出於 Node 自己的故障。更或者,一個運行緩慢的程序可能跟 Node 自己沒有任何關係,問題在於外部資源,好比數據庫查詢或是 API 調用緩慢,未通過優化處理。html

在本文中,咱們將重點識別並優化代碼庫中會致使 CPU 繁重運行的操做。同時,將探討生產應用的配置文件,分析並做出可提升運做效率的改動。node

因爲 Node 的單線程性質,避免繁重的 CPU 負載對服務器來講尤其重要。由於在 CPU 上消耗的時間會佔用響應其餘請求的時間。若是你注意到本身的應用響應速度緩慢,並且 CPU 在這個過程當中始終佔用率較高,分析你的程序有助於找出瓶頸,而且使程序恢復快速運行的狀態。git

##分析應用github

複製生產環境中出現的緩慢程序問題很是難解決,並且十分耗時。值得慶幸的是,你不須要親自作這些了。你能夠在生產服務器上收集配置文件數據,而後離線分析。下面讓咱們來看一下幾種分析方法。web

##一、使用內核級工具chrome

首先,你可使用內核級工具,好比 DTrace(Solaris, BSD),perf(Linux),或者 XPerf(Windows),從運行的進程中收集堆棧跟蹤信息,而後生成火焰圖。內核級分析對運行中的進程影響最小。火焰圖是根據調用棧生成的支持放大縮小查看的向量圖形。來自 Netflix 公司的 Yunong Xiao 針對 Linux 系統中 perf,發表過超讚的演講推文,幫助你加深對該技術的瞭解。若是你想在生產程序中保持高吞吐量,能夠參考使用這種方法。數據庫

enter image description here

###二、使用 V8 分析器npm

另外一個選項是直接使用 V8 分析器。這種方式會與程序共享進程,所以它會影響程序性能。基於這個緣由,請只在你遇到此類問題時運行 V8 分析器來捕獲相關輸出。該方法的好處是:你可使用 Chrome 的全部分析工具,結合其輸出結果(包括火焰圖),對程序進行調查。編程

請運行如下代碼來測試你的程序:瀏覽器

npm install v8-profiler --save

以後,在你的程序中添加如下代碼:

const profiler = require('v8-profiler')
const fs = require('fs')
var profilerRunning = false
function toggleProfiling () {
  if (profilerRunning) {
    const profile = profiler.stopProfiling()
    console.log('stopped profiling')
    profile.export()
      .pipe(fs.createWriteStream('./myapp-'+Date.now()+'.cpuprofile'))
      .once('error',  profiler.deleteAllProfiles)
      .once('finish', profiler.deleteAllProfiles)
    profilerRunning = false
    return
  }
  profiler.startProfiling()
  profilerRunning = true
  console.log('started profiling')
}
process.on('SIGUSR2', toggleProfiling)

只要你發送 SIGUSR2 信號到此進程,它就會開始分析。再次發送一個 SIGUSR2 信號能夠中止分析(代碼以下)。

kill -SIGUSR2 [pid]

該進程的分析結果將被寫入到當前工做路徑的文件中(請確保該路徑可被寫入)。因爲這是一個可編程接口,你能夠隨意觸發它(使用 web endpoint,IPC,等等)。若是你對程序在什麼時候變得緩慢有預感,你能夠在任一時期觸發該接口。創建自動觸發對避免持續監看程序是很是有用的,可是它要求你對捕獲時間以及捕獲時長有預測性認知。

一旦已經收集好配置文件數據,將它加載到Chrome開發工具中,開始分析吧!

enter image description here

##三、使用進程管理器

儘管直接使用 V8 分析器是很是有效且可定製的,可是它會進入你的代碼庫,而且會向項目添加又一項你可能不想要的依賴性條件。一種替代方式就是使用進程管理器,它能夠在你須要分析時,用各類工具將你的程序包裝起來。一種可選的工具是來自 StrongLoop 的 SLC 命令行工具。

首先,運行npm install strongloop –g,而後運行如下代碼:

slc start [/path/to/app]

上述代碼會在進程管理器中啓動你的程序,你能夠按需提取 CPU 分析數據。要想驗證並獲取應用程序 id,請運行:

slc ctl

你將獲得與下面相似的運行結果:

Service ID: 1
Service Name: my-sluggish-app
Environment variables:
    Name      Value
    NODE_ENV  production
Instances:
    Version  Agent version  Debugger version  Cluster size  Driver metadata
     5.0.1       2.0.2            1.0.0             1             N/A
Processes:
        ID      PID   WID  Listening Ports  Tracking objects?  CPU profiling?  Tracing?  Debugging?
    1.1.61022  61022   0
    1.1.61023  61023   1     0.0.0.0:3000

定位應用的進程 id。在此例中,id 爲1.1.61023。如今咱們就能在任意時間開始分析了,運行以下代碼便可:

slc ctl cpu-start 1.1.61023

當咱們以爲已經捕獲到了遲滯行爲,就能夠運行如下代碼來中止分析器:

slc ctl cpu-stop 1.1.61023

如下代碼將寫文件至硬盤:

CPU profile written to `node.1.1.61023.cpuprofile`, load into Chrome Dev Tools

好啦,就是這樣。你能夠像在 V8 分析器裏那樣把文件加載到 Chrome 裏面進一步分析。

##做出正確決定

在本文中,筆者展現了三種在 Node 中捕獲生產環境下 CPU 使用量的方式。那麼,你應該選用哪種呢?下面是一些幫助你縮小決策範圍的想法:

  1. 我須要分析很長一段時間:使用內核級工具。
  2. 我想用 Chrome 開發工具:使用 V8 分析器或者過程管理器。
  3. 我想捕獲應用中的特定行爲:使用 V8 分析器。
  4. 我不想影響到程序性能:使用內核級程序
  5. 我但願我不用挨個測試文件來獲取程序分析信息:使用過程管理器。

OneAPM 助您輕鬆鎖定 Node.js 應用性能瓶頸,經過強大的 Trace 記錄逐層分析,直至鎖定行級問題代碼。以用戶角度展現系統響應速度,以地域和瀏覽器維度統計用戶使用狀況。想閱讀更多技術文章,請訪問 OneAPM 官方博客 本文轉自 OneAPM 官方博客

原文地址:https://strongloop.com/strongblog/tips-optimizing-slow-code-in-nodejs/

相關文章
相關標籤/搜索