System.Net 連結庫中的分散式追蹤
分散式追蹤 是一種診斷技術,幫助工程師定位應用程式中的失敗和效能問題,尤其是在那些分佈於多台機器或多個進程中的系統。 這項技術會透過應用程式追蹤要求,方法是將不同元件所完成的工作相互關聯,並將它與應用程式可能針對並行要求執行的其他工作分開。 例如,負載平衡器可能會先收到對一般 Web 服務的要求,然後再轉送至 Web 伺服器進程,然後對資料庫進行數個查詢。 分散式追蹤可讓工程師區分這些步驟是否失敗,以及每個步驟花費的時間長度。 它也可以記錄每個步驟執行時所產生的訊息。
.NET 中的追蹤系統設計為使用 OpenTelemetry (OTel),並使用 OTel 將數據匯出至監視系統。 .NET 中的追蹤是使用 System.Diagnostics API 來實作,其中工作單位是由 System.Diagnostics.Activity 類別表示,其對應於 OTel 範圍。 OpenTelemetry 定義了一個跨活動及其屬性的全產業標準命名方案,被稱為 語意慣例。 .NET 遙測會盡可能使用現有的語意慣例。
注意
在本文中,詞彙 範圍 和 活動 是同義詞。 在 .NET 代碼範疇內,會引用 System.Diagnostics.Activity 實例。 請勿將 OTel 範圍與 System.Span<T>混淆。
提示
如需所有內建活動及其標籤/屬性的完整清單,請參閱 .NET 中的內建活動。
儀錶
要發出追蹤資訊,System.Net 程式庫經過內建 ActivitySource 來源的 檢測,以建立 Activity 物件來追蹤執行的工作。 只有在有監聽器訂閱 ActivitySource時,才會建立活動。
內建的工具會隨著 .NET 版本而演進。
- 在 .NET 8 和更早版本上,工具化僅限於建立空 HTTP 用戶端請求活動。 這表示用戶必須依賴
OpenTelemetry.Instrumentation.Http
函式庫,以填入活動所需的資訊(例如標籤)來發出有用的追蹤。 - .NET 9 根據 OTel HTTP 用戶端語意慣例,透過在 HTTP 用戶端請求活動中發出名稱、狀態、例外資訊及最重要的標籤,來擴展檢測功能。 這表示在 .NET 9+ 上,除非需要 擴充 等更進階的功能,否則可以省略
OpenTelemetry.Instrumentation.Http
相依性。 - .NET 9 也引進了 實驗性連接追蹤,在
System.Net
程式庫中新增新的活動,用於診斷連接問題。
收集 System.Net 追蹤記錄
最低層級支持追蹤收集,其方法是透過 AddActivityListener 方法來註冊包含使用者定義邏輯的 ActivityListener 物件。
不過,身為應用程式開發人員,您可能會想要依賴以 OpenTelemetry .NET SDK 所提供的功能為基礎的豐富生態系統, 來收集、導出和監視追蹤。
- 若要深入瞭解使用 OTel 的追蹤集合,請參閱我們的指南,瞭解如何使用 OpenTelemetry 收集追蹤。
- 針對 生產時間 追蹤收集與監視,您可以使用 OpenTelemetry 搭配 Prometheus、Grafana 和 Jaeger,或使用 Azure Monitor 和 Application Insights。 不過,這些工具相當複雜,而且在開發階段可能會不方便使用。
- 針對 開發時間 追蹤收集與監視,我們建議使用 .NET Aspire,提供簡單但可延伸的方式,在應用程式中啟動分散式追蹤,並在本機診斷問題。
- 您也可以 在沒有 Aspire 協調流程的情況下重複使用 Aspire 服務預設值 專案。 這是在您的 ASP.NET 項目中引進和設定 OpenTelemetry 追蹤和計量的便利方式。
使用 .NET Aspire 收集追蹤資料
在 ASP.NET 應用程式中收集追蹤和計量的簡單方法是使用 .NET Aspire。 .NET Aspire 是 .NET 的一組延伸模組,可讓您輕鬆地建立及使用分散式應用程式。 使用 .NET Aspire 的優點之一,就是使用適用於 .NET 的 OpenTelemetry 連結庫來內建遙測。
.NET Aspire 的預設專案範本包含 ServiceDefaults
專案。 .NET Aspire 解決方案中的每個服務都有服務預設值項目的參考。 服務會使用它來設定和配置 OTel。
服務預設值項目範本包含 OTel SDK、ASP.NET、HttpClient 和 Runtime Instrumentation 套件。 這些檢測元件是在 Extensions.cs 檔案中設定的。 為了支援 Aspire 儀錶板中的遙測視覺效果,服務預設值專案也預設包含 OTLP 導出工具。
Aspire 儀錶板的設計目的是將遙測資料觀察整合到本地除錯流程中,使開發人員能夠確保應用程式正在產生成遙測資料。 遙測視覺效果也有助於在本機診斷這些應用程式。 能夠觀察服務之間的呼叫在除錯時與在正式環境中一樣有用。 當您從 Visual Studio 啟動 F5 的 AppHost
專案,或從命令提示字元啟動 dotnet run
的 AppHost
專案時,.NET Aspire 儀錶板會自動啟動。
如需 .NET Aspire 的詳細資訊,請參閱:
不使用 .NET Aspire 協調流程時重複使用服務預設專案
Aspire Service Defaults 專案提供簡單的方法來設定 ASP.NET 專案的 OTel,即使不使用其他 .NET Aspire,例如 AppHost 來進行協調流程。 服務預設值專案可透過Visual Studio或 dotnet new
作為專案範本。 它會配置 OTel 並設置 OTLP 匯出器。 然後,您可以使用 OTel 環境變數 來設定 OTLP 端點來傳送遙測,並提供應用程式的資源屬性。
在 .NET Aspire 外部使用 ServiceDefaults 的步驟如下:
使用 Visual Studio 中的 [新增專案] 將 ServiceDefaults 專案新增至方案,或使用
dotnet new
:dotnet new aspire-servicedefaults --output ServiceDefaults
請從您的 ASP.NET 應用程式參考 ServiceDefaults 專案。 在 Visual Studio 中,選取 [新增>專案參考],然後選取 ServiceDefaults 專案。
呼叫 OpenTelemetry 安裝程式函式
ConfigureOpenTelemetry()
作為應用程式建立器初始化的一部分。var builder = WebApplication.CreateBuilder(args) builder.ConfigureOpenTelemetry(); // Extension method from ServiceDefaults. var app = builder.Build(); app.MapGet("/", () => "Hello World!"); app.Run();
如需完整指南,請參閱 範例:使用 OpenTelemetry 搭配 OTLP 和獨立 Aspire 儀錶板。
實驗性連線追蹤
針對 HttpClient
問題或瓶頸進行疑難解答時,查看傳送 HTTP 要求時所花費的時間可能很重要。 通常,此問題會在 HTTP 連線建立期間發生,這通常會細分為 DNS 查閱、TCP 連線和 TLS 交握。
.NET 9 引進了實驗性連線追蹤,並新增了一個 HTTP connection setup
範圍,其中包含三個子範圍,代表連線建立的 DNS、TCP 和 TLS 階段。 連線追蹤的 HTTP 部分會在 SocketsHttpHandler內實作,這表示活動模型必須遵守基礎連接共享行為。
注意
在 SocketsHttpHandler中,連線和要求具有獨立的生命週期。
集區連線 可以長時間運作,並處理許多請求。 提出要求時,如果連接集區中沒有立即可用的連線,要求就會新增至要求佇列以等候可用的連線。 等候要求與連線之間沒有直接關聯性。 當另一個連線可供使用時,可能會啟動連接過程,在這種情況下,將使用被釋放的連線。 因此,HTTP connection setup
範圍不會模型化為 HTTP client request
範圍的子系;相反地,會使用範圍連結。
.NET 9 引入了下列區段,以便收集詳細的連線資訊:
名字 | ActivitySource | 描述 |
---|---|---|
HTTP wait_for_connection |
Experimental.System.Net.Http.Connections |
HTTP client request 範圍的子範圍,代表請求在請求佇列中等待可用連線的時間段。 |
HTTP connection_setup |
Experimental.System.Net.Http.Connections |
表示 HTTP 連線的建立。 具備專屬的 TraceId 的單獨追蹤根範圍。
HTTP client request 範圍可能包含 HTTP connection_setup 的連結。 |
DNS lookup |
Experimental.System.Net.NameResolution |
Dns 類別所執行的 DNS 查詢。 |
socket connect |
Experimental.System.Net.Sockets |
建立 Socket 連接。 |
TLS handshake |
Experimental.System.Net.Security |
由 SslStream執行的 TLS 用戶端或伺服器交握。 |
注意
對應的 ActivitySource
名稱會以 Experimental
為前綴開頭,這是因為當我們更深入了解它們在生產環境中的運作後,這些範圍在未來版本中可能會變更。
在高負載的生產環境中全年無休使用時,這些跨度太過詳細且噪聲太多,一般不需要這樣的監控工具層級。 不過,如果您嘗試診斷連線問題,或深入瞭解網路和連線延遲如何影響您的服務,則它們會提供難以透過其他方式收集的深入解析。
開啟 Experimental.System.Net.Http.Connections
ActivitySource 時,HTTP client request
範圍包含對應至提供要求之連線之 HTTP connection_setup
範圍的連結。 由於 HTTP 連線可能長期存留,這可能會導致來自每個要求活動的連線範圍有許多連結。 某些 APM 監視工具會積極地在範圍之間穿梭連結,以建立其檢視模式,因此,包含此範圍時可能會導致工具在未設計來處理大量連結的情況下出現問題。
下圖示意範圍及其關聯性的行為。
逐步解說:在 .NET 9 中使用實驗性連線追蹤
本操作指南會使用 .NET 9 Aspire Starter App 來示範連線追蹤,但也應該能輕鬆地進行設置 其他監視工具。 關鍵步驟是啟用 ActivitySources。
使用
dotnet new
建立 .NET Aspire 9 入門版應用程式:dotnet new aspire-starter-9 --output ConnectionTracingDemo
或在 Visual Studio 中:
在
ServiceDefaults
專案中開啟Extensions.cs
,然後編輯ConfigureOpenTelemetry
方法,於追蹤配置回呼中新增活動來源,以進行連線:.WithTracing(tracing => { tracing.AddAspNetCoreInstrumentation() // Instead of using .AddHttpClientInstrumentation() // .NET 9 allows to add the ActivitySources directly. .AddSource("System.Net.Http") // Add the experimental connection tracking ActivitySources using a wildcard. .AddSource("Experimental.System.Net.*"); });
啟動解決方案。 這應該會開啟 .NET Aspire 儀錶板。
前往
webfrontend
應用程式的 [天氣] 頁面,以向apiservice
發送HttpClient
請求。返回儀錶板,並流覽至 追蹤 頁面。 開啟
webfrontend: GET /weather
追蹤。
啟用連線檢測的 HTTP 要求時,您應該會看到用戶端要求範圍的下列變更:
- 如果需要建立連線,或應用程式正在等候來自連線集區的連線,則會顯示額外的
HTTP wait_for_connection
範圍,這代表等待連線的延遲。 這有助於瞭解從程式碼中發出HttpClient
要求到實際開始處理該要求之間的延遲時間。 在上一個影像中:- 選取範圍是 HttpClient 要求。
- 以下範圍代表要求等候建立連線所花費的時間。
- 黃色的最後一個範圍來自處理要求的目的地。
- HttpClient 區段會有一個指向
HTTP connection_setup
區段的連結,該區段代表建立此要求所使用的 HTTP 連線的活動。
如先前所述,HTTP connection_setup
範圍是個別的跨度,具有自己的 TraceId
,因為它的存留期與每個個別用戶端要求無關。 這個範圍通常具有子範圍 DNS lookup
、(TCP) socket connect
和 TLS client handshake
。
富 集
在某些情況下,必須增強現有的 System.Net
追蹤功能。 這通常表示將其他標籤/屬性插入內建活動。 這稱為 擴充。
OpenTelemetry 檢測庫中的增強 API
若要將其他標籤/屬性新增至 HTTP 用戶端要求活動,最簡單的方法是使用 openTelemetry HttpClient 和 HttpWebRequest 檢測連結庫 HttpClient
擴充 API。 這需要仰賴 OpenTelemetry.Instrumentation.Http
套件。
手動擴充
您可以手動實作 HTTP client request
活動的擴充。 為此,您必須在要求活動範圍內執行的程式代碼中存取 Activity.Current,然後才能完成活動。 這可以藉由實作 IObserver<DiagnosticListener>
,並將它訂閱到 AllListeners,以接收來自網路活動發生時的回呼。 事實上,這就是 OpenTelemetry HttpClient 和 HttpWebRequest 儀表化庫 的實作方式。 如需程式碼範例,請參閱 DiagnosticSourceSubscriber.cs
中的訂閱代碼以及 HttpHandlerDiagnosticListener.cs 中負責委派通知的底層實作。
需要更多追蹤嗎?
如果您有其他可透過追蹤公開之實用資訊的建議,請建立 dotnet/runtime 問題。