examlab .net 用最有效率的方法,考取最有價值的認證
Vol. I
本篇導覽 約 32 分鐘

AWS X-Ray 分散式追蹤與除錯

6,400 字 · 約 32 分鐘閱讀 ·

DVA-C02 完整學習指南:AWS X-Ray 分散式追蹤與除錯,涵蓋追蹤、區段、子區段、annotation 與 metadata 的差異、預設每秒 1 筆加 5% 取樣規則、自訂取樣、Node/Python/Java/Go/.NET/Ruby 的 X-Ray SDK、EC2/ECS 上的 X-Ray daemon 與 Lambda 直接上傳模式、Lambda 的 Active 與 PassThrough 追蹤、API Gateway+Lambda+DynamoDB 自動儀器化、服務圖、延遲分佈……

立即做 20 題練習 → 免費 · 不用註冊 · DVA-C02

AWS X-Ray 是分散式追蹤服務,能將單一使用者請求跨越 API Gateway、AWS Lambda、Amazon DynamoDB、下游 HTTP API 和 SQS queue 所經過的每一個節點串連起來,並呈現每個節點的延遲、錯誤與故障狀況。在 DVA-C02 考試中,任務說明 4.1「協助執行根本原因分析」直接點名 AWS X-Ray。考題會問你:要加哪個 annotation 才能讓篩選表達式找到某位使用者的失敗請求、針對特定 AWS Lambda 設定應選 Active 追蹤還是 PassThrough 追蹤、為何預設 AWS X-Ray 取樣每秒只抓一筆請求,以及何時該選 ADOT 而非 AWS X-Ray SDK。本章節訓練你辨識 DVA-C02 考試可能考到的每一個 AWS X-Ray 概念。AWS X-Ray、CloudWatch ServiceLens、CloudWatch Transaction Search 與 ADOT 合計占 Domain 4 評分面大約三分之一——精通 AWS X-Ray 與本章的除錯模式,Domain 4 就會成為你的主場優勢。

什麼是 AWS X-Ray?

AWS X-Ray 是受管的分散式追蹤服務,收集你的應用程式所服務的請求資料,並用這些資料產生服務圖、延遲分佈,以及個別請求的詳細追蹤時間軸。AWS X-Ray 的運作方式是:將唯一的追蹤 ID(trace ID)傳遞到請求的每個節點、從接觸該請求的每個服務收集計時區段(segment),再於後端將它們合併成一棵完整的追蹤樹。AWS X-Ray 是 AWS 原生的 OpenTracing 風格可觀察性解決方案,依每筆追蹤的記錄次數與取回次數計費,因此取樣是頭等重要的設計。

AWS X-Ray 在 DVA-C02 考試地圖中的位置

在 DVA-C02 中,AWS X-Ray 橫跨多個任務說明:

  • 任務 4.1(根本原因分析):AWS X-Ray 服務圖、追蹤檢查、篩選表達式、用來定位故障的 annotation。
  • 任務 4.2(為可觀察性進行程式碼儀器化):AWS X-Ray SDK、ADOT、Active 與 PassThrough 追蹤、取樣規則調整。
  • 任務 1.2(開發 Lambda 程式碼)任務 1.1(AWS 上的應用程式):在 AWS Lambda、API Gateway 和 AWS SDK 上啟用 AWS X-Ray。
  • 任務 2.2(加密):AWS X-Ray 靜態加密(預設使用 AWS 管理的 KMS 金鑰;視需求可改用客戶管理的 KMS 金鑰)。

任何要求你「找出緩慢的服務」、「定位節流來源」或「將使用者 ID 關聯到失敗呼叫」的題目,都是 AWS X-Ray 題目。

從高空俯瞰 AWS X-Ray 的資料流

每一筆 AWS X-Ray 追蹤都遵循相同的流程:(1)第一個接收到請求的服務不是收到 X-Amzn-Trace-Id 標頭,就是自己產生一個;(2)每個已儀器化的服務將自己的工作記錄為一個區段(子操作則記錄為子區段);(3)區段被送到 AWS X-Ray API——透過本地 AWS X-Ray daemon 以 UDP 傳輸,或直接以 HTTPS 傳輸;(4)AWS X-Ray 將所有共用相同追蹤 ID 的區段縫合成一棵追蹤樹;(5)主控台呈現服務圖與追蹤時間軸。理解這個流程能解鎖考試上每一道 AWS X-Ray 題目,因為取樣、annotation、daemon 部署位置和 ADOT 相容性都源自於此。

白話文解釋 AWS X-Ray and Debugging

AWS X-Ray 講白了就是「給你的分散式系統裝一台行車紀錄器」。用下面三種類比,AWS X-Ray 的幾個抽象概念一次就記牢。

類比一 — 超商宅配的追蹤碼

把每一個進入你服務的請求想成一件超商宅配包裹。每件包裹都有一個追蹤碼(trace ID),從收件(API Gateway)、轉運站(AWS Lambda)、倉庫(DynamoDB)、海關(外部 HTTP API)到最後一哩配送(SQS),每一關都會刷條碼。每一次刷條碼就是一段區段(segment);倉庫內部的分揀動作就是子區段(subsegment)。你想知道「我今天上午寄的那件包裹為什麼晚到?」只要輸入追蹤碼,AWS X-Ray 就把所有關卡的時間戳全攤給你看,一眼就能指出是海關卡了 2 秒還是配送車塞車。

AWS X-Ray = 全島快遞追蹤系統,讓分散式系統的每一步「可追可查」。

類比二 — 醫院的病歷表

AWS X-Ray 也像醫院的病歷。病人(request)一進急診室就拿到一張病歷號(trace ID)。每個看過病人的科別——急診、放射、檢驗、外科——都會在病歷上寫下自己看診的時間區間(segment),科別內部若轉給不同醫師(subsegment)也一層一層記。主治醫師翻病歷只要看一張表就知道:病人先看急診 5 分鐘,放射花了 40 分鐘(瓶頸),外科開刀 1 小時。annotation 就像病歷的關鍵欄位(血型、藥物過敏)——建立索引可被搜尋;metadata 就像手寫備註(病人自述的症狀)——存著但不被篩選表達式查到。

AWS X-Ray = 系統版的醫院病歷,把單一請求的每一步時間與決策都記下來。

類比三 — 機場塔台的螢幕

AWS X-Ray 的服務圖(service map)像機場塔台的監控螢幕。塔台不畫每一架飛機的完整航線,而是畫所有飛機共用的跑道、滑行道、登機門(服務節點),每條路線上標示「平均延遲」、「錯誤率」、「故障率」。取樣規則就像塔台規定:每秒至少錄一架起降(reservoir 1 req/s),其餘再抽 5%(fixed rate 5%)——不全錄是因為儲存空間有限,但永遠留一份「代表樣本」。Insights 像塔台的異常偵測員,發現某條跑道延誤暴增就亮紅燈。CloudWatch ServiceLens 則是把塔台螢幕、氣象雷達(metrics)、通訊紀錄(logs)合在同一個儀表板。

三個類比串起來,AWS X-Ray 的「trace ID 串連 × 服務地圖 × 取樣控管 × 指標/日誌關聯」四大特性就全清晰了。

一筆 AWS X-Ray 追蹤(trace)是共用同一個 trace ID 的所有區段的完整集合——也就是所有服務為處理一個端對端請求所做的全部工作。追蹤在 AWS X-Ray 主控台以時間軸形式呈現,並在服務圖中顯示為單一節點路徑。追蹤資料預設保留 30 天。 Reference: https://docs.aws.amazon.com/xray/latest/devguide/xray-concepts.html

AWS X-Ray 核心概念:追蹤、區段、子區段

在你能夠進行儀器化、篩選或除錯之前,必須先搞清楚這三個名詞。DVA-C02 對三者都有精確的考法。

追蹤(Trace)

追蹤是 AWS X-Ray 資料的最外層單位:一個請求,一個追蹤 ID。AWS X-Ray 追蹤 ID 的格式像 1-58406520-a006649127e371903a2de979——1 是版本號,58406520 是十六進位的 Unix epoch,其餘是 96 位元的唯一識別碼。追蹤 ID 透過 HTTP 標頭 X-Amzn-Trace-Id 傳遞。每個區段和子區段都帶著這個追蹤 ID,AWS X-Ray 才能將它們縫合在一起。

區段(Segment)

區段是單一服務針對某次追蹤所發出的工作記錄。若 API Gateway、AWS Lambda 和 DynamoDB 都碰了同一個請求,你就會得到三個區段(API Gateway 的區段、AWS Lambda 函式的區段,以及 AWS SDK 儀器化所呈現的 DynamoDB 起始區段)。一個區段包含:

  • 服務名稱(name)、服務類型及 AWS 帳號。
  • 開始時間和結束時間(即持續時間)。
  • 資源 ARN(適用於 AWS Lambda、ECS、EC2 等)。
  • HTTP 請求資訊(若適用)。
  • 錯誤(Error)/故障(Fault)/節流(Throttle)旗標。
  • Annotation 和 metadata(詳見下方說明)。
  • 一份子區段列表。

子區段(Subsegment)

子區段是區段內部更細粒度的計時工作塊。在一個呼叫 DynamoDB、寫入 S3、並呼叫第三方 HTTP API 的 AWS Lambda 函式中,你通常會看到該函式區段內有三個子區段。AWS X-Ray SDK 會自動儀器化 AWS SDK 和 HTTP 程式庫,使每個對外呼叫都成為一個子區段。你也可以手動建立自訂子區段來計時任意程式碼區塊——這是考試常見的陷阱。

追蹤 = 一個請求的完整旅程(一個追蹤 ID,跨多個服務)。區段 = 一個服務對該追蹤的工作記錄。子區段 = 一個服務內部的一項操作(下游呼叫、資料庫查詢、計時程式碼區塊)。「請求 → 服務 → 操作」與「追蹤 → 區段 → 子區段」一一對應。記住這個三層模型,90% 的 AWS X-Ray 題目都能迎刃而解。 Reference: https://docs.aws.amazon.com/xray/latest/devguide/xray-concepts.html

AWS X-Ray Annotation 與 Metadata

這是 DVA-C02 最常考的 AWS X-Ray 區別。Annotation 和 metadata 都會將額外的鍵值資料附加到區段或子區段——但只有一種會建立索引。

Annotation:有索引,可篩選

Annotation 是簡單的鍵值對(字串、數字或布林值),AWS X-Ray 會為其建立索引以供篩選表達式使用。你可以將想搜尋的欄位加上 annotation:customer_idtenantproduct_skudeployment_color。在 AWS X-Ray 主控台的篩選列中,你可以輸入 annotation.customer_id = "A123" 來取得該客戶的所有追蹤。每個區段最多可持有 50 個 annotation

Metadata:不索引,僅附帶儲存

Metadata 是任意鍵值對(包括巢狀物件、陣列),與區段一起儲存但不建立索引。你無法透過 metadata 篩選追蹤。使用 metadata 承載的是:當你已在查看特定追蹤時有用的情境資訊——完整請求內容(已遮蔽)、快取命中/未命中狀態、功能旗標值。Metadata 以命名空間組織,可以是 AWSdefault 或你自訂的命名空間如 my-app

如何選擇 Annotation 還是 Metadata

問自己一個問題:「我以後會需要用這個欄位來搜尋追蹤嗎?」如果是,就用 annotation。如果只是想在人工開啟追蹤時看到這筆資料,就用 metadata。Annotation 的寫入成本較高(需建立索引)且每個區段上限 50 個;metadata 成本低,且每個區段允許的資料量也較大。

Annotation 有索引且可篩選(適用於 customer_id、tenant、關聯鍵)。Metadata 有儲存但無索引(適用於偵錯情境,如請求內容快照或快取狀態)。若題目說「我需要找出客戶 A123 的所有失敗追蹤」,答案是「將 customer_id 加為 annotation」。若題目說「我想附加一份完整的 JSON 請求快照」,答案是「將它加為 metadata」。這一條規則解答了 DVA-C02 上最常出現的 AWS X-Ray 題目。 Reference: https://docs.aws.amazon.com/xray/latest/devguide/xray-api-segmentdocuments.html

AWS X-Ray 取樣規則

AWS X-Ray 取樣控制有多少請求實際產生追蹤。取樣的存在是因為在大流量下追蹤每一筆請求既昂貴又雜亂。

預設取樣規則:每秒 1 筆 + 5%

每個啟用 AWS X-Ray 的服務都從預設取樣規則開始:

  • Reservoir = 每秒 1 筆請求 — AWS X-Ray 永遠追蹤每秒的第一筆請求,確保在流量平靜期也不失去能見度。
  • Fixed rate = 5% — 該秒內其餘每筆請求,有 5% 會被取樣。

所以在 100 req/s 的情況下,你每秒大約得到 1 + (99 × 0.05) ≈ 6 筆追蹤,而不是 100 筆。請記住「1 + 5%」就是預設值。

自訂取樣規則

你可以定義自訂取樣規則(每個帳號最多 25 條),這些規則會在預設規則之前套用。每條規則依以下條件配對:

  • ServiceName(例如 api-prod)、ServiceType(例如 AWS::Lambda::Function)。
  • HTTPMethod(GET、POST……)和 URLPath(例如 /checkout/*)。
  • HostResourceARN

並套用其自訂的 reservoir + fixed rate。範例:結帳路徑需要完整能見度,因此你定義:

  • URLPath = /checkout/*,reservoir = 5,fixed rate = 100%。

規則依優先順序評估(數字越小越優先)。若沒有自訂規則配對,則套用預設規則。

取樣對帳單與能見度的影響

每筆取樣的追蹤在記錄時和取回時(GetTraceSummaries/BatchGetTraces)都會計費。過度取樣會讓你的 AWS X-Ray 帳單爆增並使追蹤索引過於龐大;取樣不足則會讓你對罕見錯誤視而不見。DVA-C02 很愛出這樣的情境:「生產流量為每秒 10,000 筆,帳單太高,如何在保留每秒最少一筆追蹤的前提下降低成本?」→ 答案:降低 fixed rate,保留 reservoir。

這是常見的生產問題:你的函式有 0.5% 的失敗率,但 AWS X-Ray 只抓到 5% 的請求,你幾乎不可能捕捉到一筆失敗追蹤。解決方案:針對特定錯誤路徑新增自訂取樣規則,或對低流量的關鍵端點提高 fixed rate。在 DVA-C02 中,若情境說「我們在 X-Ray 找不到那筆失敗請求」,答案通常是「為受影響的 URL 路徑建立 fixed rate 更高的自訂取樣規則」。 Reference: https://docs.aws.amazon.com/xray/latest/devguide/xray-console-sampling.html

AWS X-Ray SDK 各語言版本

AWS X-Ray SDK 是你加進應用程式程式碼的儀器化程式庫,讓程式能發出區段。它涵蓋 DVA-C02 範圍內的每一種執行環境。

Node.js SDK

aws-xray-sdkaws-xray-sdk-core 是對應的 npm 套件。你透過包裝的方式儀器化 HTTP client 和 AWS SDK v2/v3:

const AWSXRay = require('aws-xray-sdk');
const AWS = AWSXRay.captureAWS(require('aws-sdk'));
const https = AWSXRay.captureHTTPs(require('https'));

對 Express 應用程式,在頂端加上 AWSXRay.express.openSegment('my-service') middleware,底部加上 closeSegment()

Python SDK

aws-xray-sdk pip 套件提供 patch_all(),一行即可自動儀器化 boto3botocorerequestshttplibsqlite3mysqldb

from aws_xray_sdk.core import xray_recorder, patch_all
patch_all()

Flask 和 Django 整合會附加 middleware,在每個請求時開啟一個區段。

Java SDK

Java 版 AWS X-Ray SDK(aws-xray-recorder-sdk-core + aws-xray-recorder-sdk-aws-sdk-v2)透過 TracingInterceptor 儀器化 AWS SDK v2,並透過 AWSXRayServletFilter 儀器化 servlet 容器。Spring Boot 有專屬的整合模組。

Go SDK

Go 版 AWS X-Ray SDK(github.com/aws/aws-xray-sdk-go/xray)儀器化 AWS SDK v1 和 v2、net/http 用戶端與伺服器,以及 SQL 驅動程式。你用 xray.Handler(xray.NewFixedSegmentNamer("svc"), h) 包裝 handler。

.NET SDK

.NET SDK(AWSXRayRecorder.Core + AWSXRayRecorder.Handlers.AwsSdk + AWSXRayRecorder.Handlers.System.Net)儀器化 AWS SDK 呼叫、HTTP handler,以及透過 IApplicationBuilder 上的 UseXRay("svc") 擴充方法儀器化 ASP.NET Core。

Ruby SDK

Ruby 版 aws-xray-sdk 儀器化 aws-sdk 和 Rack/Rails。在 Rails 應用程式中,你在 config.ru 裡加上 use XRay::Rack::Middleware

AWS X-Ray SDK 在每種語言中都會自動儀器化三件事:AWS SDK(每個 client 呼叫都成為子區段)、HTTP client(對外的 HTTP 呼叫都成為子區段),以及網頁框架的請求生命週期(進來的請求開啟/關閉一個區段)。其他所有東西——你的業務邏輯、SDK 支援驅動程式以外的 SQL 呼叫——都需要透過 AWSXRay.captureAsyncFuncxray_recorder.in_subsegment 或對應方法手動建立子區段。在 DVA-C02 中,「如何為一段自訂程式碼計時?」的答案永遠是「手動建立子區段」。 Reference: https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk.html

AWS X-Ray Daemon 與直接 API 模式

在大多數執行環境中,AWS X-Ray SDK 不會直接與 AWS X-Ray API 通訊。它會在本地緩衝區段,再透過 AWS X-Ray daemon 傳送。

AWS X-Ray Daemon

AWS X-Ray daemon 是一個小型 Go 執行檔,監聽 UDP port 2000 以接收區段資料,將其緩衝後透過 HTTPS 沖出至 AWS X-Ray API。它使用執行個體的 IAM 角色(EC2 執行個體設定檔或 ECS 任務角色)來簽署 API 呼叫。你需要在以下環境自行安裝並執行 daemon:

  • EC2 — 安裝 daemon RPM 或執行 systemd unit。
  • ECS on EC2 — 以 sidecar 容器執行(amazon/aws-xray-daemon 映像)。
  • ECS on Fargate — 以 sidecar 容器執行。
  • EKS — 以 DaemonSet 或 sidecar 執行。
  • 地端(On-premises) — 在伺服器上執行,並明確設定 AWS 憑證。

為什麼要用 daemon 而不直接呼叫 API?因為 UDP 是「發送即忘」——就算 AWS X-Ray 短暫變慢,儀器化也不會阻塞你的應用程式。SDK 送出一個 UDP 封包就繼續執行;daemon 負責重試和批次處理。

AWS Lambda 直接 API 模式

AWS Lambda 是唯一一個你不需要自己執行 daemon 的執行環境。AWS Lambda 執行環境內建了 AWS X-Ray client(透過 Runtime API),當你啟用 Active 追蹤時,它會直接替你上傳區段到 AWS X-Ray API。你只需要:

  1. 在 AWS Lambda 函式上啟用 Active 追蹤(主控台、SAM 或 aws lambda update-function-configuration --tracing-config Mode=Active)。
  2. 若你想要自訂 annotation、子區段或 AWS SDK 自動儀器化,則在部署套件中包含 AWS X-Ray SDK。

EC2、ECS(EC2 和 Fargate)、EKS 和地端 → 你必須執行 AWS X-Ray daemon(UDP port 2000,透過執行個體/任務角色取得 IAM 授權,映像為 amazon/aws-xray-daemon)。AWS Lambda → 不需要 daemon,啟用 Active 追蹤後,執行環境直接與 AWS X-Ray 通訊。在 DVA-C02 中,「我的 Lambda 追蹤沒有出現在 X-Ray」通常表示 Active 追蹤未開啟;「我的 EC2 追蹤沒有出現」通常表示 daemon 未執行,或執行個體設定檔缺少 AWSXRayDaemonWriteAccess。 Reference: https://docs.aws.amazon.com/xray/latest/devguide/xray-daemon.html

AWS Lambda Active 追蹤與 PassThrough 追蹤

AWS Lambda 的 TracingConfig.Mode 有兩個值,DVA-C02 很愛考這個區別。

Active 追蹤

設定 Mode=Active 時,AWS Lambda 永遠依取樣規則進行取樣,為每次符合取樣條件的呼叫建立追蹤,即使呼叫者未傳送 X-Amzn-Trace-Id 標頭也一樣。AWS Lambda 服務本身會成為一個 AWS::Lambda 區段,你的 handler(若使用 X-Ray SDK)會加入一個帶有子區段的 AWS::Lambda::Function 區段。這是開發期間以及作為追蹤進入點的任何函式應啟用的模式。

PassThrough 追蹤(預設值)

設定 Mode=PassThrough(未明確設定 Active 時的預設值)時,AWS Lambda 只在呼叫者於標頭中傳遞追蹤 ID 時才記錄追蹤。若上游呼叫者(API Gateway、另一個已追蹤的 Lambda 或已儀器化的 HTTP client)已開啟追蹤,AWS Lambda 就會參與其中。若沒有追蹤 ID 傳入,則不記錄任何追蹤。當上游沒有人在追蹤時,PassThrough 不產生額外費用。

什麼情況用哪種模式

  • 進入點 Lambda(在 API Gateway 後方、作為直接 SDK 呼叫目標、作為 S3 觸發器)Active。否則追蹤永遠不會開始。
  • 只被已追蹤服務呼叫的中間 LambdaPassThrough 就夠了,且在上游開始追蹤前不產生費用。
  • 非同步事件驅動的 Lambda → 通常使用 Active,因為非同步呼叫者(S3、SNS)不一定能可靠地傳遞追蹤情境。

Active = 永遠追蹤(依取樣規則)。PassThrough = 只在呼叫者傳遞追蹤 ID 時追蹤。若服務圖中缺少一個應該是進入點的 Lambda 函式,原因幾乎都是該函式的 Mode=PassThrough 而上游沒有人在追蹤。切換到 Active,區段就會出現。在 DVA-C02 中,「追蹤從地圖中間才開始出現」幾乎都意味著某個進入點 Lambda 處於 PassThrough 模式。 Reference: https://docs.aws.amazon.com/lambda/latest/dg/services-xray.html

API Gateway、Lambda 和 DynamoDB 自動儀器化

AWS X-Ray 的一大吸引力是:對於常見的 AWS 原生架構,你幾乎不需要寫任何程式碼。

API Gateway + X-Ray

在每個 API Gateway REST API 和 HTTP API 的階段(stage)上,只需勾選一個核取方塊或加上 --tracing-enabled 旗標即可啟用 X-Ray 追蹤。API Gateway 接著會:

  1. 為進入的請求產生追蹤 ID(若已有 X-Amzn-Trace-Id 則沿用)。
  2. 建立一個 AWS::ApiGateway::Stage 區段,記錄完整的請求時間(包含整合延遲)。
  3. 將追蹤 ID 傳遞給後端(Lambda、HTTP、AWS 服務整合)。

你不需要為 API Gateway 撰寫任何儀器化程式碼。只要在階段上啟用追蹤,區段就會自動出現。

Lambda + X-Ray

啟用 Active 追蹤後,AWS Lambda 會自動發出一個 AWS::Lambda 區段(服務視角,包含冷啟動的初始化時間)和一個 AWS::Lambda::Function 區段(handler 的執行時間)。若你包含了 AWS X-Ray SDK 並呼叫 patch_all()captureAWS(),handler 內每個 AWS SDK 呼叫都會成為以目標服務命名的子區段(例如 DynamoDBS3)。冷啟動時間會以獨立的 Initialization 子區段呈現——這對冷啟動除錯至關重要。

DynamoDB + X-Ray

DynamoDB 是個特殊案例:AWS SDK 儀器化會把每個 GetItemPutItemQueryTransactWriteItems 呼叫轉成一個子區段,並在服務圖中以 DynamoDB 節點顯示。這些子區段會呈現資料表名稱(來自請求)、消耗的容量,以及節流/錯誤狀態。你不需要在 DynamoDB 內部執行任何 X-Ray agent——追蹤到你的程式碼邊界就結束了。

其他已整合的服務

開箱即用的 X-Ray 整合包括:API Gateway、Lambda、App Runner、Elastic Beanstalk、ECS、EKS、SNS(發布端)、SQS(訊息屬性)、Step Functions、Amplify,以及任何在啟用自動儀器化的情況下透過 AWS SDK 存取的服務。服務圖會自動將這些服務呈現為節點。

服務圖、延遲分佈與篩選表達式

AWS X-Ray **服務圖(service map)**是拓樸視圖:圓圈代表服務(客戶端、伺服器、下游呼叫),邊代表它們之間的呼叫。每個圓圈以顏色標示健康狀態——綠色代表健康,黃色代表有些錯誤,紅色代表故障。

延遲分佈

點擊服務圖上的任意節點,你會看到按回應時間分組的延遲分佈直方圖,以及 OK 回應、4xx 錯誤、5xx 故障和節流的細分。這是「某個服務很慢」時第一個該看的地方——你能立即看出是長尾問題還是整體位移。

篩選表達式

在追蹤視圖中,你可以使用 AWS X-Ray 篩選表達式進行搜尋:

  • service("api-prod") { fault } — api-prod 服務中所有故障。
  • annotation.customer_id = "A123" — 帶有該客戶 annotation 的追蹤。
  • duration >= 3 — 超過 3 秒的追蹤。
  • http.status = 429 — 節流回應。
  • edge("api-prod", "ddb-orders") — 包含該特定邊的追蹤。
  • 布林運算:annotation.premium = true AND fault

篩選表達式就是 annotation(而非 metadata)要建立索引的原因——它們是搜尋鍵。

追蹤時間軸

單一追蹤視圖會將每個區段和子區段以水平條呈現在時間軸上。你可以看到冷啟動與熱啟動的差異、平行與串列的子區段執行,以及確切是哪個 AWS SDK 呼叫拋出錯誤。

X-Ray 群組與基於篩選的聚合

AWS X-Ray **群組(group)**是一個已儲存的篩選表達式,AWS X-Ray 將其視為頭等的服務圖切片。

為什麼需要群組

服務圖通常顯示所有流量。群組將服務圖限縮為「只顯示符合此篩選條件的流量」——例如只顯示結帳流量、只顯示付費客戶,或只顯示帶有 5xx 的追蹤。每個群組都有自己的服務圖、自己的延遲直方圖,以及自己的 CloudWatch 指標ApproximateTraceCountOKCountErrorCountFaultCountThrottleCount、延遲百分位)。你可以對這些指標設定警報。

建立群組

你以名稱和篩選表達式定義一個群組。範例:Premium-Errors,表達式為 annotation.tier = "premium" AND (error OR fault)。每筆符合條件的追蹤都會被聚合到該群組的指標中。

群組 vs 取樣規則

不要混淆這兩者。取樣規則決定哪些追蹤會被記錄。群組決定已記錄的追蹤如何被聚合以供檢視和警報。在群組能顯示追蹤之前,追蹤必須先存在(即已被取樣)。

X-Ray Insights:異常偵測

AWS X-Ray Insights 會自動偵測流量中的異常並開立事件單。

Insights 的運作方式

當你在群組上啟用 Insights 時,AWS X-Ray 會建立預期故障率和錯誤率的基準線。若實際比率出現顯著偏差(5xx 突然激增、延遲持續位移),Insights 會開立一個事件,並附上根本原因假設——包括地圖中哪個服務節點是異常源頭、哪些客戶端受影響,以及時間窗口。Insights 可透過 EventBridge 發出通知,再路由至 SNS、Slack 或 PagerDuty。

Insights 為你節省的工作

沒有 Insights 時,你得持續輪詢服務圖或監看 CloudWatch 警報。有了 Insights,AWS 自己做模式偵測——你得到的是一個預先準備好的根本原因候選,而不是一個充滿訊號的儀表板。

AWS X-Ray Insights 是按群組啟用的。你必須(1)以篩選表達式建立一個群組來限定感興趣的流量範圍,(2)在群組上勾選「啟用 Insights」。在預設群組上啟用 Insights 涵蓋所有流量;專用群組讓你能針對每個租戶/每條路徑/每個層級進行精準的異常偵測。 Reference: https://docs.aws.amazon.com/xray/latest/devguide/xray-console-insights.html

AWS X-Ray 資料加密

AWS X-Ray 對所有靜態追蹤資料進行加密。預設情況下,AWS X-Ray 使用 AWS 管理的金鑰,免費且透明。對於受規範的工作負載,你可以設定 AWS X-Ray 使用客戶管理的 KMS 金鑰(CMK)——你在帳號中選擇一個對稱 CMK,授予 kms:GenerateDataKeykms:Decrypt 給 AWS X-Ray 服務主體,再透過 PutEncryptionConfig 將其設定為加密金鑰。切換加密金鑰會在幾分鐘內生效;只要兩把金鑰都保持可存取,現有的追蹤仍可讀取。

AWS X-Ray 預設使用 AWS 管理的金鑰對靜態追蹤資料加密;當合規要求時,透過 PutEncryptionConfig 切換為帳號內的客戶管理 KMS 金鑰。沒有逐區段加密的選項。在 DVA-C02 中,「如何滿足所有遙測資料必須以我們自己的金鑰加密的合規要求?」→ 將 X-Ray 加密設定切換為帳號中的 CMK。 Reference: https://docs.aws.amazon.com/xray/latest/devguide/xray-console-encryption.html

ADOT:AWS Distro for OpenTelemetry

ADOT(AWS Distro for OpenTelemetry) 是 AWS 支持的、已簽署的開源 OpenTelemetry Collector 發行版,加上 ADOT SDK。ADOT 是 AWS 上儀器化的策略性前進方向——DVA-C02 v2.1 現在也考這部分。

ADOT 存在的原因

原始的 AWS X-Ray SDK 是 AWS 特定的。如果你的應用程式還需要將追蹤、指標或日誌匯出至 Prometheus、Grafana、Jaeger、Datadog、New Relic 或 Honeycomb,你要麼執行兩個 agent,要麼選擇 OpenTelemetry。ADOT 讓你一次儀器化(OpenTelemetry API),就能匯出到多個後端,包括 AWS X-Ray、Amazon Managed Prometheus、Amazon Managed Grafana 和 CloudWatch。

ADOT Collector

ADOT Collector 是一個廠商中立的 agent(基於 OTel Collector),透過 OTLP 協議接收追蹤和指標,再匯出到 AWS X-Ray、CloudWatch EMF、AMP 或外部後端。你可以這樣執行 Collector:

  • 在 ECS/EKS 上以 sidecar 執行。
  • Lambda layer 執行(ADOT Lambda Layer)——一個現成的 Collector-in-a-layer。
  • 在 EC2 上以 systemd 服務執行。
  • 整合進 App Runner 由 AWS 代管。

ADOT SDK 語言

ADOT 為 Java、Python、JavaScript(Node)、Go、.NET 提供已簽署的 SDK。它們與 OpenTelemetry 相容——你撰寫 OTel 程式碼,AWS 負責簽署並支援該發行版。

與 X-Ray 的互通性

ADOT → AWS X-Ray 的互通對追蹤資料是無損的。Collector 將 OTLP span 轉換為 AWS X-Ray 的區段和子區段,並在 AWS 服務邊界將 W3C Trace Context 標頭轉換為 X-Amzn-Trace-Id。你可以混合使用:某些服務執行傳統 X-Ray SDK,其他服務執行 ADOT,服務圖會將它們縫合成一個完整的拓樸。

ADOT + Amazon Managed Prometheus + Amazon Managed Grafana

ADOT 透過 Prometheus remote-write 協議將指標匯出至 Amazon Managed Prometheus(AMP),再由 Amazon Managed Grafana(AMG) 查詢 AMP 來顯示儀表板——這是一套全受管的可觀察性架構,以 Prometheus 風格的時間序列補充 X-Ray 的追蹤資料。

當遙測資料只留在 AWS 內且你想要最簡單的路徑時,使用 AWS X-Ray SDK。當你需要(a)為多雲環境標準化至 OpenTelemetry、(b)匯出至 Managed Prometheus/Managed Grafana/第三方後端,或(c)用單一 agent 同時處理指標與追蹤時,使用 ADOT(OpenTelemetry)。兩者都能產生有效的 X-Ray 追蹤;選擇的依據是可攜性與多後端匯出需求。 Reference: https://aws-otel.github.io/docs/introduction

AWS 已將 X-Ray 整合進 CloudWatch,以兩個主控台體驗呈現,DVA-C02 期望你能辨識這兩者。

CloudWatch ServiceLens

CloudWatch ServiceLens 是 CloudWatch 主控台視圖,將三種訊號整合到一個儀表板:

  1. AWS X-Ray 服務圖(拓樸 + 延遲 + 錯誤)。
  2. CloudWatch 指標(每個服務的 Lambda 持續時間、API Gateway 5xx、DynamoDB 節流)。
  3. CloudWatch Logs(每個服務節點的日誌群組,從追蹤一鍵跳到日誌)。

當題目問「哪個主控台能在同一個畫面看到追蹤、指標和日誌?」時,ServiceLens 就是答案。你不需要設定 ServiceLens;只要 X-Ray 和 CloudWatch Logs 都有資料,它就會自動出現。

CloudWatch Transaction Search 是 2024 年底新增的功能,可索引最多 100% 的追蹤 span——不只是 X-Ray 取樣的子集——並讓你按屬性搜尋。它解決了「取樣漏掉了那筆問題追蹤」的問題,做法是將每個 span 都攝入一個日誌式的索引儲存,並讓你對結構化 span 屬性執行類似日誌的查詢。Transaction Search 與 X-Ray 分開計費,是可觀察性的進階附加功能。

將 CloudWatch Logs 連結到 X-Ray 追蹤

讓 ServiceLens 運作的黏著劑是日誌行中的追蹤 ID。當你在 Lambda 函式中啟用 X-Ray 時,執行環境會將追蹤 ID 注入 logger 情境。結構化日誌(JSON)應包含 "aws_request_id""xray_trace_id" 欄位。如此一來:

  • 從 X-Ray 的追蹤 → 點擊「查看日誌」→ 跳至以追蹤 ID 篩選的 CloudWatch Logs Insights 查詢。
  • 從 CloudWatch 的日誌行 → 點擊追蹤 ID → 跳至 X-Ray 追蹤時間軸。

在 Python 搭配 aws_xray_sdk 時,xray_recorder.current_segment().trace_id 可取得追蹤 ID。在 Node 中,AWSXRay.getSegment().trace_id。在每一行日誌中發出追蹤 ID,關聯就變成一鍵完成。

在每一行結構化日誌中加入 X-Ray 追蹤 ID,成本幾乎為零,卻能讓你的日誌與追蹤成為一個可聯結的資料集。你可以撰寫跨追蹤聚合的 CloudWatch Logs Insights 查詢,也可以透過 ServiceLens 從任何緩慢的追蹤一鍵跳到其日誌。在 DVA-C02 中,「如何將追蹤關聯到其日誌?」的答案永遠是「在日誌行中加入追蹤 ID annotation」。 Reference: https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/ServiceLens.html

常見除錯模式

了解 X-Ray 概念是一回事;知道該用哪種模式則是另一回事——DVA-C02 很愛出情境題。

模式一 — N+1 資料庫查詢

症狀:一筆請求的追蹤顯示 30 個連續的 DynamoDB 子區段,每個 5 毫秒,總計 150 毫秒。 根本原因:對每個項目的迴圈呼叫了 GetItem,而非使用 BatchGetItemQuery修正方式:重構為 BatchGetItem(最多 100 個項目,一個子區段)或針對 GSI 使用 QueryX-Ray 如何找出問題:時間軸立即顯示堆疊的序列;無需程式碼審查。

模式二 — 緩慢的冷啟動

症狀:部分 Lambda 呼叫在 handler 子區段開始之前,有一個長達 1.5 秒的 Initialization 子區段。 根本原因:JVM/.NET 或大型 ZIP 套件的冷啟動。 修正方式:佈建並行(Provisioned Concurrency)、SnapStart(Java)、精簡套件、Arm64。 X-Ray 如何找出問題Initialization 子區段與 handler 分開標示,你能清楚看出多少延遲來自冷啟動,多少來自 handler 執行。

模式三 — 重試風暴

症狀:單一追蹤扇出成 8 個以上相同下游呼叫的子區段,每個都標示 fault,總計耗時 10 秒。 根本原因:SDK 預設重試(每次呼叫最多 3 次)與呼叫者重試(每次呼叫最多 3 次)疊加,對一個短暫的下游故障產生 9–27 倍的放大效應。 修正方式:對齊重試預算——要麼用呼叫者重試,要麼用 SDK 重試,不要兩者並用;加入抖動;在熔斷器訊號觸發時快速失敗。 X-Ray 如何找出問題:重複出現的相同名稱子區段加上 fault 旗標,讓放大效應一目了然。

模式四 — 節流歸因

症狀:DynamoDB 資料表正在節流;誰是元凶? 根本原因:某條呼叫路徑(某個客戶租戶?某個服務?)正在造成熱分區流量。 修正方式:在每個區段加上 annotation.tenant;用 throttle AND annotation.tenant = ? 篩選追蹤找出驅動者;重新分配負載。 X-Ray 如何找出問題:annotation 加上節流指標加上篩選表達式,幾秒內就能三角定位出肇事者。

模式五 — 遺失的區段

症狀:服務圖顯示 API Gateway → ???。Lambda 節點消失了。 根本原因:Lambda 的 TracingConfig.Mode = PassThrough 而上游未傳遞追蹤 ID,或執行角色缺少 AWSXRayDaemonWriteAccess(在 EC2/ECS 上),或 daemon 未執行。 修正方式:切換為 Active、附加受管政策、啟動 daemon。 X-Ray 如何找出問題:服務圖以懸掛的邊呈現缺口——這個視覺提示不可能被忽視。

AWS X-Ray 限制與服務邊界

DVA-C02 可能引用原始數字,請記住以下數據:

  • 追蹤保留期:30 天。
  • 區段文件大小:64 KB。
  • 每個區段的 annotation 數:50 個。
  • 每個帳號的自訂取樣規則數:25 條。
  • 子區段深度:無限制,但每個子區段是獨立的文件。
  • 追蹤 ID 格式1-{epoch-hex}-{96-bit-hex}
  • Daemon UDP port:2000。
  • 預設取樣:每秒 1 筆 reservoir + 5% fixed rate。

AWS X-Ray 與 CloudWatch Logs:互補而非競爭

一個常見的混淆:「我能不能直接記錄所有東西而跳過 X-Ray?」不行。

  • CloudWatch Logs 告訴你單一服務內部發生了什麼(每個服務一個日誌群組,每個執行個體/函式一條日誌串流)。
  • AWS X-Ray 告訴你針對一個請求,跨所有服務發生了什麼(每個請求一筆追蹤)。

日誌針對自由文字搜尋最佳化;X-Ray 針對時間軸視覺化與拓樸聚合最佳化。兩者都需要——而日誌行中的追蹤 ID 就是連結兩者的橋梁。

常見 DVA-C02 考試陷阱

  1. Annotation vs metadata — annotation 有索引,metadata 沒有。若題目說「搜尋/篩選/警報」,答案是 annotation。
  2. Active vs PassThrough 追蹤 — 進入點 Lambda 必須用 Active;PassThrough 只在呼叫者傳遞追蹤 ID 時才追蹤。
  3. 預設取樣會遺漏罕見錯誤 — 若題目是「我在 X-Ray 找不到那次故障」,答案是為該路徑建立 fixed rate 更高的自訂取樣規則。
  4. EC2/ECS 需要 daemon,Lambda 不需要 — Lambda 使用執行環境內建的 API 直接上傳;EC2/ECS 需要 daemon 和 AWSXRayDaemonWriteAccess 政策。
  5. AWS SDK 呼叫以外的子區段需手動建立 — 自動儀器化涵蓋 SDK + HTTP + 框架,其他什麼都不包含。
  6. X-Ray Insights 需要群組 — 啟用 Insights 是群組層級的設定,不是全域設定。
  7. 群組 vs 取樣規則 — 取樣決定什麼被記錄;群組決定已記錄的追蹤如何聚合。
  8. ADOT 用於多後端/OpenTelemetry 可攜性,X-Ray SDK 用於 AWS 限定的簡單情境。
  9. 日誌行中的追蹤 ID 是 ServiceLens 在日誌與追蹤之間點擊跳轉所需的橋梁。
  10. X-Ray 加密:預設為 AWS 管理的金鑰;當合規要求時透過 PutEncryptionConfig 改用客戶管理的 KMS 金鑰。

FAQ:AWS X-Ray 與除錯前 8 大問題

Q1:AWS X-Ray 的預設取樣規則是什麼?何時應該更改它?

AWS X-Ray 預設取樣規則是每秒 1 筆請求(reservoir)加上其餘請求的 5%(fixed rate)。在低流量時,幾乎每筆請求都會被取樣;在 1,000 req/s 時,你每秒大約得到 51 筆追蹤。在以下情況需要更改:(a)遺漏了罕見錯誤——為該 URL 路徑建立 fixed rate 更高的自訂規則;(b)帳單太高——為大流量雜訊路徑建立 fixed rate 更低的自訂規則;(c)特定端點基於合規需要 100% 覆蓋率——為該路徑建立 fixed rate 為 100% 的自訂規則。

Q2:AWS X-Ray 中 annotation 和 metadata 有什麼差異?

Annotation 是有索引的鍵值對(每個區段最多 50 個,僅支援字串/數字/布林值),可用於篩選表達式如 annotation.customer_id = "A123"Metadata 是無索引的任意資料(允許巢狀物件),隨追蹤一起儲存以供人工檢查,但無法篩選。對任何你會用來搜尋的欄位(租戶、客戶、關聯鍵)使用 annotation;對偵錯情境(請求內容快照、快取狀態)使用 metadata。

Q3:Lambda 函式何時應啟用 Active 追蹤,何時用 PassThrough?

對任何作為追蹤進入點的 Lambda 啟用 Active——API Gateway 後端、S3 觸發器、SNS 訂閱者、直接 SDK Invoke 目標。Active 永遠依取樣規則取樣,即使上游不存在追蹤 ID 也能開始追蹤。只對那些永遠由已追蹤的上游服務呼叫的 Lambda 使用 PassThrough(預設值)。若進入點 Lambda 處於 PassThrough 模式,追蹤永遠不會開始,服務圖會顯示遺失節點。

Q4:我需要在 AWS Lambda 上執行 X-Ray daemon 嗎?

不需要。AWS Lambda 使用直接 API 模式:Lambda 執行環境內建一個 X-Ray client,當 Active 追蹤啟用時,它會直接將區段上傳至 X-Ray API。你只需在 EC2、ECS(EC2 和 Fargate)、EKS 和地端主機上執行 X-Ray daemon(UDP port 2000)。對於 ECS/EKS,daemon 以使用 amazon/aws-xray-daemon 映像的 sidecar 容器執行,且任務角色需要 AWSXRayDaemonWriteAccess 受管政策。

Q5:如何將 CloudWatch Logs 條目連結到 X-Ray 追蹤?

在每一行日誌中以結構化欄位包含 X-Ray 追蹤 ID(例如 "xray_trace_id": "1-58406520-...")。在 Lambda 中,執行環境會將追蹤 ID 注入執行情境;透過 xray_recorder.current_segment().trace_id(Python)、AWSXRay.getSegment().trace_id(Node)或其他 SDK 中的對應方法存取。一旦追蹤 ID 出現在日誌中,CloudWatch ServiceLens 讓你能從任何追蹤點擊跳至其日誌,反之亦然。這個「日誌中含追蹤 ID」的模式是 ServiceLens 體驗的基礎。

Q6:ADOT 是什麼?何時應選擇它而非 AWS X-Ray SDK?

ADOT(AWS Distro for OpenTelemetry)是 AWS 已簽署的 OpenTelemetry SDK 和 Collector 發行版。當你需要 OpenTelemetry 標準化多後端匯出(X-Ray 加上 Prometheus 加上第三方),或用單一 agent 同時處理指標和追蹤時,選擇 ADOT。當你的遙測資料只留在 AWS 內且想要最小依賴的最簡路徑時,選擇 AWS X-Ray SDK。兩者最終都產生 X-Ray 追蹤;選擇的依據是可攜性和匯出目標的廣度。

Q7:X-Ray 如何幫我找到節流和重試風暴?

對於節流歸因,在每個區段加上 annotation.tenant(或 customer_idapi_client),再用 throttle AND annotation.tenant = ? 篩選追蹤——驅動節流的頂級租戶會立刻浮現。對於重試風暴,追蹤時間軸會顯示重複出現的同名子區段加上 fault 旗標;計算它們的數量就能揭示放大倍數。修正方式:對齊重試預算——要麼用 SDK 層級重試,要麼用呼叫者層級重試,不要兩者並用,再加上有抖動的退避策略。

Q8:CloudWatch Transaction Search 是什麼?它與 X-Ray 有何不同?

CloudWatch Transaction Search 是 2024 年新增的功能,可將最多 100% 的追蹤 span 索引到類似日誌的可搜尋儲存中,讓你能按屬性查詢(例如 customer_id = "A123"),不受 X-Ray 取樣的限制。傳統 X-Ray 永遠在取樣(預設 1 + 5%);Transaction Search 可以攝入每一個 span。當你需要保證覆蓋每一筆請求以供鑑識或合規用途,且願意接受額外成本時,使用 Transaction Search。當統計覆蓋率足夠用於一般持續監控時,使用 X-Ray 取樣。

摘要:精通 AWS X-Ray 與除錯

AWS X-Ray 提供你「針對一個請求,跨所有服務發生了什麼」的視圖,這是單靠日誌無法產生的。在 DVA-C02 中,精通 annotation 與 metadata 的區別、Active 與 PassThrough 追蹤、每秒 1 筆加 5% 的預設取樣規則、daemon 與直接 API 模式,以及 ADOT 在多後端可觀察性中的角色,就能讓你領先大多數考生。將 AWS X-Ray 與 CloudWatch Logs(追蹤 ID 關聯)、CloudWatch ServiceLens(統一主控台)以及四種除錯模式——N+1 查詢、緩慢冷啟動、重試風暴、節流歸因——搭配使用,你就準備好應對考試在任務 4.1 根本原因分析上丟出的任何情境題。AWS X-Ray 是開發者在黑暗分散式系統中的手電筒;在 DVA-C02 中,它也是你在最後備考衝刺階段效益最高的主題之一。

官方資料來源

更多 DVA-C02 主題