5 個快速的 Node.js 應用效能提示

oschina發表於2015-11-03

本系列文章涵蓋許多基礎性內容:它給出了應用程式效能管理(APM)的總體概述;指明瞭實現一個 APM 策略的主要挑戰;提出了衡量,評估一個企業級 Node.js 應用程式執行狀況的最重要的 5 條指標;並提出了通過 AppDynamics 方式構建一個 APM 解決方案。在文章的最後部分,還提出了一些提示和技巧類以幫助您實現最佳的 APM 策略。具體地說,本文討論了以下主題:

  • 業務交易優化
  • 快照調優
  • 閾值調優
  • 層級管理
  • 上下文資訊捕獲

1.業務交易優化

本文章系列裡,我會不斷重複強調的就是監控方案裡的業務交易優化一環。要最有效地利用業務交易監控,您需要做到以下幾項:

  • 恰當地命名業務交易以配合您的業務功能
  • 正確識別您的業務交易
  • 通過排除您並不關心的業務交易來降低噪音

AppDynamics 可以為您自動識別業務交易,並且儘可能給出最優的命名。不過這樣取決於您的應用是如何編寫的,應用名可能可以如實反映業務交易,也可能不可以。例如,您可能有一個業務交易叫做“POST/payment”,對應著檢驗流程。那麼如果將其命名為“Checkout”的話,就更能如實反映業務功能,這將更利於操作人員操作,也便與生成報表與執行人員檢視。

下面,如果您有多個業務交易,卻只有一個入口的話,你需要花一些時間將其分割為獨立的業務單元。以下幾個可能發生的例子,包含如下特點:

  •  多個 URL 都路由到相同的 MVC 控制器和動作
  • 根據有效負載的制定業務交易功能
  •  根據 GET 引數制定業務交易功能
  •  複雜的 URL 路徑

如果一個入口卻對應著多個業務功能,那麼就需要根據不同的指標配置業務交易。例如,如果 body 裡有一個”operation“元素對應著”operation“操作的話,那麼就需要根據”operaiton“對交易進行分割。又如果有一個”execute“動作接受一個”command“URL 引數,那麼就需要根據”command“欄位對交易進行分割。最後,URL 模式可能會因應用不同而不同,所以您需要與您的應用最匹配的形式。例如,AppDynamics 會根據兩段式自動為您的 URL 定義業務交易,例如 one/two。大多數 Node.js MVC 框架都會自動路由到對應的應用控制器和動作。如果您的應用使用的是一段式,或者四段式,那麼您需要根據命名規則來定義業務交易。

命名和識別業務交易單元可以確保您捕捉到了正確的業務功能,但是儘可能多的減噪也同樣重要。您是否有些並不關心的業務交易呢?比如,會不會有一個網頁遊戲會每隔幾秒就檢查對高分呢?又或者如果有一個每晚都執行的 Node.js 的 CLI 作業,每次都執行很長時間,但是由於離線執行,它並不影響終端使用者,您不關心麼? 如果是的話,排除這些交易,以便減少分析噪音。

2. 快照調優

正如在前面文章提到的,AppDynamics 每隔一段時間就會智慧捕獲效能快照,並可以逐漸縮小每次效能會話裡快照的個數。由於這兩個值都是可以調整的,所以有利於調優。

AppDynamics 直接捕獲整個程式的呼叫關係圖,同時去掉配置閾值以下的記錄。如果你只對“大的”效能問題感興趣,那麼你可能不需要精確到 10 毫秒以下。如果你把間隔時間增加到 50 毫秒,你會丟失粒度。如果你想微調應用程式,你可能需要 10 毫秒的粒度,但是如果你不打算讓方法在 50 毫秒內執行完畢,為什麼需要那種級別的粒度呢?問題在於你應該分析需求然後做相應的調整。

接下來,觀察你的產品故障排除模式,然後判斷 AppDynamics 捕獲的程式快照數在你當前狀況下是否合適。如果你發現每分鐘捕獲 2 個快照太多了,那麼你可以配置 AppDynamics 來調整快照間隔。嘗試配置 AppDynamics 讓其每分鐘最多捕獲一個快照。另外如果你只對系統性問題感興趣,你可以把最大快照數降低至 5 個。這會顯著地減少持續的消耗,但代價是可能會導致捕捉不到有代表性的快照。

3. 閾值調優

AppDynamics 設計了一套通用的監控解決方案,並且對於比正常情況慢兩個標準差的業務事務提供警告。這在大多數情況下是有效的,但是你需要知道你的應用程式響應時間有多不穩定,以便確定這對你的業務需求來說是否為最佳配置。

根據業務事務對比基準線的估算值,AppDynamics 定義了三種閾值:

  • 標準差: 比較業務事務的響應時間與基準線的幾個標準差
  • 百分比: 比較業務事務的響應時間與基準線的差值百分比
  • 靜態 SLA: 比較業務事務的響應時間和靜態值,比如2秒

如果您的應用程式的響應時間不穩定,那麼預設的兩個標準差臨界值可能導致太多的錯誤警報。在這種情況下,您可能希望增加更多的標準差或換一種方式來處理。如果您的應用程式的響應時間比較穩定,你就會想減少你的臨界值提前發出警告。此外,如果你有提供給特殊協定使用者的服務或 API(應用程式介面),你應該為此業務設定一個穩定的協定值。AppDynamics(應用效能管理)會提供給你個人或企業業務定義警報規則的靈活性。

你需要分析你的應用程式的行為,並相應地配置報警引擎。

4. 分層調優

在前面我已經提到過,AppDynamics 不僅能夠捕獲業務事務效能的基準,同時它也能捕獲一個業務事務在不同服務層上的效能基準。打個比方,如果你的業務事務呼叫了一個規則引擎提供的服務,那麼AppDynamics將正確捕獲你的業務事務對規則引擎部分的呼叫數以及規則引擎的平均響應時間,並且將會把這些資料正確反映到業務事務的效能基準中。正是因為 AppDynamics 的這個特性,因此在你的整個系統中最好能夠清晰定義所有的服務層,這樣你可以得到一個非常清晰而且優秀的業務事務效能基準。

如果你沒有明確指定系統的服務層次,那麼AppDynamics將根據一定的規則(不同的協議棧)自動分析你的應用的服務層次。比如,它將自動把你的應用分解成 HTTP 服務層,JMS 服務層,JDBC 服務層。舉一個具體的例子,如果 AppDynamics 發現你的程式碼中有一個對 Database 的操作,那麼它就會假設你的整個業務邏輯中存在一個資料庫訪問層,因此它就會自動計算你的業務邏輯用在資料庫訪問上的時間。這個對於調優你的業務邏輯是非常重要的,因為你不希望在效能基準中只是看到一個資訊說你的 ORM class 中的 save 方法執行的非常慢,相反的你希望能夠看到更具體的資訊,比如說 save 方法花了多少時間把資料儲存到資料庫中,又花了多少時間執行其他的任務。

如果在你的系統中,所有的 service 呼叫都使用的是通用協議棧(比如 HTTP 協議), 那麼 AppDynamics 將非常完美的分析出你的系統的服務層次,但是如果你的系統使用了一個非通用協議棧和後端系統進行通訊,AppDynamics 就無能為力了。舉例來說,目前我在一個保險公司工作,這個保險公司使用一個 AS/400 機器提供詢價服務。在我們的系統中,我們使用了一個私有庫來和 AS/400 通訊,這個庫使用了一個私有的基於 socket 的通訊協議連結到 AS/400 上。在這種情況下,很明顯 AppDynamics 不可能知道系統使用了基於 socket 的通訊協議,也不可能知道這 個socket 通訊協議是如何工作的。因此,我們需要告訴 AppDynamics 是哪個方法實現了和 AS/400 之間的通訊,並且標記這個方法為定製化的後端資源。這樣一來,AppDynamics 就會將這個方法識別成一個新的服務層次,接下來 AppDynamics 就可以對這個新的服務層次進行呼叫計數,並計算它的平均響應時間了。

在大部分情況下,你可以使用 AppDynamics 的內建功能來分析系統的服務層次,但是如果你有特定的要求,AppDynamics 也提供了 Node.js API,讓你自己定義系統的服務層次。

5. 獲取上下文資訊

但效能問題發生的時候,有時候問題只發生在某個瀏覽器或者移動裝置上,有時候只發生在客戶端傳送了特定的請求內容。在這種情況下,由於問題並不總是能夠重現,那麼我們怎麼來定位這些問題呢?

答案就是在建立快照的時候,同時獲得上下文資訊。你可以通過檢視上下文資訊,看來發現一些共性。需要捕獲上下文資訊可能有以下這些:

  • HTTP 請求頭資訊,比如瀏覽器型別(user-agent ),cookies 和 referrer
  • HTTP GET 請求傳送的引數
  • 被呼叫方法的引數
  • 應用中定義的變數以及變數的值

我們下面就舉一些例子來說明對於一個效能不好的 Node.js 事務,你將如何應用上面說的這些上下文資訊來查詢和發現問題。比如,如果你捕獲了 User-Agent HTTP 請求頭資訊,那麼你就可以知道使用者是在哪個瀏覽器上執行商業事務。如果你提供的 HTTP 服務支援 GET 方法,那麼你可能想通過檢查Query String 裡面某個或者多個變數的值來知道使用者想查詢什麼內容。再進一步,如果你知道應用的程式碼是如何工作,你可能就想知道一個具體引數的值。

你可以通過配置讓 AppDynamics 獲取上下文資訊並且加入到快照中,可以被捕獲的上下文資訊在上一節中已經詳細介紹了。下面我們簡單的介紹一下 AppDynamics 獲取上下文資訊的過程:

  • AppDynamics 發現了一個執行緩慢的業務事務
  • 於是 AppDynamics 開始建立一個快照
  • 在建立快照的過程中,AppDynamics 根據你配置的資訊,獲取相應的上下文資訊並放入快照中

結果就是當你找到一個可以反映你試圖解決的問題的快照的時候,你可以在 AppDynamics 為你捕獲的上下文資訊中檢視是否有有用的資訊。

當你使用上下文資訊捕獲功能的時候,因為 AppDynamics 使用侵入式程式碼來獲取方法的引數值,這將造成原始程式碼執行效率有一些下降。因此,只在確實需要的地方使用這個功能。

結束語

應用效能管理的難處在於它需要在獲取儘量少的資料的情況下,能夠讓開發人員分析出導致效能瓶頸的真正原因。 對於一個 APM 工具,都應該能夠提供一系列的配置選項,以便開發人員可以在應用程式執行過程中,以儘量小的代價獲得足夠的效能分析資料。 這篇文章主要介紹了一下這些在實現 APM 策略的時候需要思考的核心點,這些核心點包括:

  • 業務事務優化
  • 快照調優
  • 閥值調優
  • 服務層次管理
  • 獲取上下文資訊

實現一個 APM 系統是非常困難的,但是象 AppDynamics 這樣的系統就極大的簡化了 APM 的實現。通過使用 AppDynamics, 開發人員可以很方便的在應用中實現 APM,而不會對應用本身造成很大的影響( APM 程式碼的引入也是會造成一定的效能下降的)。

相關文章