Elastic APM 教學與性能監控 實作 Nodejs 狀態感知與系統瓶頸分析之優化路徑

me
林彥成
2020-09-12 | 5 min.
文章目錄
  1. 1. 什麼是應用程式性能監控 (APM)?
  2. 2. Elastic APM 基礎教學
    1. 2.1. Node.js 實作範例
    2. 2.2. 運用 Kibana 監看 APM
    3. 2.3. 應用程式層級監控
  3. 3. Elastic APM 深入理解
    1. 3.1. APM Data Modal
    2. 3.2. APM Server
    3. 3.3. APM Agents
  4. 4. FAQ:應用程式監控常見問題
    1. 4.1. Q1:安裝 APM Agent 會導致應用程式變慢嗎?
    2. 4.2. Q2:Transactions 與 Spans 的層級關係是什麼?
    3. 4.3. Q3:為什麼建議將 APM Agent 放在程式的最頂端載入?

什麼是應用程式性能監控 (APM)?

應用程式性能監控 (Application Performance Monitoring, APM) 是一套用於即時追蹤、分析並優化軟體應用效能與可用性的技術體系。其核心價值在於提供「深度的可觀測性」:透過在程式中植入 APM Agents,開發者能精確擷取每一次 HTTP 請求的 Transactions (事務) 與具體的 Spans (跨度) 執行時間。

與傳統的日誌監控不同,APM 專注於識別「哪些 API 響應過慢」以及「錯誤發生在程式碼的哪一行」。結合 Elasticsearch 儲存與 Kibana 可視化,APM 能協助 DevOps 團隊在使用者察覺前,快速定位資料庫查詢、第三方 API 調用或程式邏輯中的效能瓶頸,是維持現代微服務系統高可用性的必備工具。


在現代的微服務架構與複雜應用中,應用程式性能監控工具 (APM) 已成為確保系統穩定與高效運行的關鍵。Elastic APM 教學系列深入探討如何有效利用這項工具,特別針對 APM 監控 Node.js 等主流開發框架,提供實時的性能數據與洞察。

Elastic APM 基礎教學

這篇文章將簡介如何運用 Elastic APM client 和 server 端的函式庫來進行監控。示範如何安裝並使用 APM 監控 Node.js 服務狀態,將數據傳送至 Elasticsearch,並利用 Kibana 進行監看。

為什麼服務監控至關重要?同一台主機上可能運行多個服務,了解各服務的資源消耗(CPU、記憶體、流量)是優化的關鍵。Elastic APM 解決的痛點:

  • 方便分析服務資源消耗。
  • 快速識別耗時過長的 API 端點。
  • 記錄流程面(非系統崩潰)的應用程式錯誤。
    Elastic APM 錯誤捕獲範例

Node.js 實作範例

Server 端實作步驟:

  1. npm install express --save
  2. 開設 API:包含一般 API、回應慢的 API、與會拋錯的 API。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const app = require("express")();
const apm = require("elastic-apm-node").start({
serviceName: "my-service",
secretToken: "your-token",
serverUrl: "https://your-apm-server:443",
});

app.get("/", (req, res) => res.json("Hello World!"));

app.get("/slow", (req, res) => {
setTimeout(() => res.json("Slow response"), 50);
});

app.get("/error", (req, res) => {
var err = new Error("Ups, something broke!");
apm.captureError(err);
res.status(500).send("Error occurred");
});

app.listen(3000);

Client 端測試腳本:

1
2
3
4
5
6
7
function test() {
for (let index = 0; index < 999; index++) {
fetch("/");
fetch("/slow");
if (index % 17 === 0) fetch("/error");
}
}

運用 Kibana 監看 APM

Kibana 的 Observability 模組提供了強大功能:

  • Transactions: 記錄 API 耗時趨勢。

  • Errors: 追蹤錯誤發生的具體程式碼行數。

  • Metrics: 監控 CPU、記憶體等硬體資源。

  • Service Map: 直觀呈現服務間的調用關係。

    時間維度的圖表
    Elastic APM Transaction 響應時間趨勢圖
    各 API 分析,Slow 明顯比較慢
    Elastic APM Performance 監控:API 響應時間分析
    可以看出發生的行數
    Elastic APM Errors 錯誤追蹤介面

    監控 CPU、記憶體等硬體資源
    Elastic APM Metrics 基礎硬體資源監控

    服務間的調用關係
    Elastic APM Service Map 服務關係圖


應用程式層級監控

在使用者操作前端網頁時,如果發生了不可預期的錯誤,我們該怎麼記錄起來? 在還沒有使用其他工具前,如果要監控並記錄錯誤,直觀通常就是寫出像是底下的程式,透過實作 logMyErrors 及搭配的後端 API 來協助。這也是應用程式性能監控工具的一部分。

  • 連線不正常: 先存 storage 下次使用者重新進入網頁時偷偷打 API 送回後端資料庫
  • 連線正常: 直接打 API 傳回去 DB 存
1
2
3
4
5
6
7
8
let data;
try {
// 需要測試的語句
data = getData(); // 可拋出例外的函數
} catch (e) {
data = "unknown";
logMyErrors(e); // 把例外物件傳給錯誤處理器
}

Elastic APM 深入理解

當然也有其他工具像是最近幾年也蠻多人使用的 Sentry,不過這系列主要是討論 Elastic Stack,APM 的存在就是為了簡化實作的部分,提供了:

  • 應用程式層的監控
  • client 端相關效能監控 (real user monitoring),這是實時應用監控的一部分。

主要提供兩個大家會想知道的答案 (根本只有攻城獅才想知道?!!XDDD)

  • 每次 request 的回應時間
  • 服務在什麼時候出現哪些錯誤

一套完整的 APM 會由以下組成

  • APM Agents: 是一個 lib 需要寫進去我們的程式裡
  • APM Server:
    • beat framwork 實作的 http server
    • 協助驗證並轉換格式寫入 Elasticsearch
    • 資料灌爆來不及寫入的時候可以當 bufffer
    • 與使用者之間多了一層 server 對資料來說也更安全
    • 開 API 讓更多類型的 client 容易串接
  • Elasticsearch: 全文檢索的搜尋引擎
  • Kibana: 相當於 Elasticsearch 的後台 GUI

APM Data Modal

APM 記錄了不同類型的資訊,這對於性能瓶頸分析至關重要:

  • Spans: 算是最基礎的單位,紀錄的內容包含執行的行數,會記錄某個活動的開始到結束
    • transaction.id: 紀錄對應到哪個 transaction
    • parent.id: Span 可能被 Span 或 transaction 包含
    • start time and duration
    • name
    • type
    • stack trace (optional)
  • Transactions: 多加上一些特殊 attribute 的 span,通常紀錄像是打到 server 的 request、Batch 或背景任務,通常理論上就是看這個
    • 事件發生當下的 timestamp
    • unique id, type, name
    • 相關的執行環境
      • service: environment, framework, language
      • host: architecture, hostname, IP
      • process: args, PID, PPID
      • URL: full, domain, port, query
      • user: email, ID, username (如果有)
  • Errors: 原始的 exception 訊息
    • 例外發生時的訊息
    • 在哪裏發生的
    • 相關的 Transaction ID

APM Server

最重要的就是要先下載並安裝 APM server,裝在本機跑起來之後預設會是 http://localhost:8200,然後會傳到 http://localhost:9200 的 Elasticsearch,把 apm-server.yml 中的 apm-server.rum.enabled,使用 Elastic Cloud 的話就是要注意要記得選有 APM 的,選對就會看到如下圖,接著點 kibana 首頁的 Add APM 照著教學裡面自動帶入的參數使用即可。

確認選到有 APM 模組的
Elastic Cloud APM 模組選擇
按照下圖範例中自動帶入的連結、token
Kibana Add APM 設定範例

APM Agents

APM agents 主要分成 Server 端和 Client 端兩種,且都需要自行加入到專案中,依照常撰寫的語言進行下載配置即可,Server 端 Node.js 的實作在剛剛已經示範過了。這是Elastic APM 教學的實踐。

下面介紹的是 Client 端 JS 的部分,其中 serviceName 是用來分類用的,可自行命名。在 Client 端的實作也可以叫做 Real User Monitoring:

1
2
3
4
5
6
7
8
9
10
11
12
var apm = ininApm({
// Override service name from package.json
// Allowed characters: a-z, A-Z, 0-9, -, _, and space
serviceName: "virus-and-where-to-find-them",

// Use if APM Server requires a token
secretToken: "",

// Set custom APM Server URL (default: http://localhost:8200)
serverUrl:
"https://e9047bd2f1e84a619b8462911fe9378b.apm.asia-east1.gcp.elastic-cloud.com:443",
});

APM agents 在配置好後通常會自動蒐集相關可以蒐集的數據資訊,應該理論上就可以從這些 client 或 Server 中蒐集的數據找到程式的效能瓶頸,當然其他進階的部分還是要看相關 API 進行相關程式碼撰寫,初步可以看出的相關資訊可能如下:

  • Server 是否有 latency
  • 部分類似 GA 的統計

進行網頁操作後產生的數據範例
Elastic APM Transactions 數據範例


FAQ:應用程式監控常見問題

Q1:安裝 APM Agent 會導致應用程式變慢嗎?

A:影響極微。 APM Agent 設計為非同步運行,且數據通常是批次(Batch)傳送到 APM Server 的。雖然會有極小比例的 CPU 與記憶體開銷,但相對於它能幫您找出的效能瓶頸(如慢速 SQL),這點投資回報率極高。

Q2:Transactions 與 Spans 的層級關係是什麼?

A:您可以將 Transaction 想像成一個完整的「事件容器」(例如使用者完成一筆訂單的請求);而 Spans 則是該容器內各個具體「子步驟」的時間紀錄(例如連線資料庫、執行邏輯運算、調用金流 API)。一個 Transaction 通常包含多個 Spans。

Q3:為什麼建議將 APM Agent 放在程式的最頂端載入?

A:因為 APM Agent 需要「儀器化 (Instrumentation)」您的程式碼。它會攔截並封裝其他函式庫(如 http, express, mongoose)的行為以自動採集數據。如果載入順序太晚,Agent 將無法監控到那些在它之前已經初始化完成的服務。



喜歡這篇文章,請幫忙拍拍手喔 🤣