歡迎光臨
每天分享高質量文章

Dotnet全平臺下APM-Trace探索

隨著支撐的內部業務系統越來越多,向著服務化架構進化,在整個迭代過程中,會逐漸暴露出以下問題。

  1. 傳統依賴於應用服務器日誌等手段的排除故障原因的複雜度越來越高,傳統的監控服務已經無法滿足需求。

    終端--> Nginx --> IIS --> Asp.net 管道 --> [資料快取]->[HTTP呼叫]->[DB讀寫]
    
    在以上呼叫鏈路上,我們以往勉強能從 Nginx 日誌中分析出 客戶端呼叫時長,Nginx 呼叫API服務時長。
    但是到了應用程式代碼,對於[資料快取]->[HTTP呼叫]->[DB讀寫]等操作,變成了鏈路呼叫黑盒。
  2. 在出現性能問題定位,也嚴重依賴高級工程師經驗,定位困難,指標不明確。
  3. 在分析整個應用呼叫鏈路,不能清晰、直觀的分析展現。

 

0|1度量(Metrics),跟蹤(Tracing),日誌(Logging)

 

 

Logging,Metrics 和 Tracing 有各自專註的部分。

  • Logging – 用於記錄離散的事件。例如,應用程式的除錯信息或錯誤信息。它是我們診斷問題的依據。
  • Metrics – 用於記錄可聚合的資料。例如,佇列的當前深度可被定義為一個度量值,在元素入隊或出隊時被更新;HTTP 請求個數可被定義為一個計數器,新請求到來時進行累加。
  • Tracing – 用於記錄請求範圍內的信息。例如,一次遠程方法呼叫的執行過程和耗時。它是我們排查系統性能問題的利器。

詳細閱讀,參考度量(Metrics),跟蹤(Tracing),日誌(Logging)

這三者的交集,才是對於我們分析應用程式運行狀態及呼叫鏈路分析,有這直觀重要的意義。

日誌(Logging),可以使用ELK技術棧,解決我們的應用程式日誌查詢分析的大部分需求。

度量(Metrics),可以使用AppMetrics 和 Prometheus 來滿足一部分需求。

跟蹤(Tracing),全鏈路的呼叫分析追蹤,目前解決方案大部分也是商業解決方案,如Application Insights、OneAPM、聽雲、Datadog等,開源方案,如SkyAPM (.net core適用)

目前,針對 .net 平臺下探針的解決方案進行調研,大部分是付費,開源方案大部分針對 .net core。

有沒有一種可能,我們使用開源技術,搭建自己的全鏈路呼叫分析的解決方案,這是本篇博文需要探索的議題。

我們將帶著以下幾個問題,進行探索解決方案

  1. 我們基於什麼標準規範來收集指標?
  2. 出於保護企業現有投資的情況下,我們需要針對Full Framework(.net Framework、.net core)下進行支持,也可以考慮公有雲應用監控。
  • 代碼級定位性能問題
  • 記錄應用錯誤過程
  • 檢測慢SQL陳述句
  • 檢測外部呼叫API耗時
  • 檢測呼叫外部HTTP請求耗時,請求信息記錄
  • 請求/RPC 呼叫關係拓撲
  1. 基於什麼架構來搭建,有哪些組件可用,能不能達到商業解決方案的相差無幾的解決方案?
  2. 用什麼的技術來實現?

跟蹤(Tracing)標準 OpenTracking

OpenTracking 為監測提供了一組標準的框架無關、廠商無關的標準規範,這意味著開發者能夠很方便的添加/切換跟蹤系統

簡單說,OpenTracking 提供了一組規範,也是分佈式跟蹤系統的標準的抽象,來解決不同的分佈式追蹤系統的API標準的不兼容問題。OpenTracing 是一個輕量級的標準化層,它位於應用程式/類庫和追蹤或日誌分析程式之間。

更多關於 OpenTracing 資料模型的知識,請參考 OpenTracing語意標準。

技術探索

分佈式追蹤系統,由追蹤器(Tracker)、追蹤信息收集代理(Agent)、追蹤信息儲存分析服務(APM Server)組成。

追蹤器(Tracker):負責應用程式監控(代碼級別執行時間、異常呼叫)
追蹤信息收集代理(Agent):負責應用程式監控信息上報
追蹤信息儲存分析服務(APM Server):負責儲存應用程式監控信息儲存分析展示等服務

追蹤器(Tracker)

代碼埋點是實現Tracker重要一步。

如果在業務代碼中實現追蹤埋點,不但工程量大,而且代碼入侵嚴重。

var tracker = Tracker.Instance;

using(var context = tracker.Begin())
{    context.SetSpan("name of span");    
    /// some business logic
    
    context.EndSpan();
    
    tracker.Send(context); 
    
}

為了實現dotnet全平臺下(Framework、dotcore)追蹤,我們需要清楚C#代碼是如何變成機器可運行的代碼。

  • 第一步,C# 編譯生成中間語言 IL
  • 第二步,中間語言IL 通過CLR的即時編譯JIT,編譯成Native Code

我們只能通過,在CLR即時編譯 IL之前,修改已生成的IL,來實現代碼埋點。這樣以來,我們便可以輕鬆的實現零入侵業務代碼。

如何實現修改已生成的IL ? 我們通過實現CLR公共語言運行時ICorProfilerCallback 中重寫JITCompilationStarted 方法即可實現。

在dotnet core 下通過DiagnosticSource 實現,應用程式性能診斷

DiagnosticSource VS EventSource

  • EventSource,只支持Windows,主要記錄可序列化的資料,被行程意外的消費。
  • DiagnosticSource,支持 .net core下,主要在行程內處理資料,可以支持非序列化的物件,比如HttpConext,HttpResponse。
  • 如果在 EventSource 中獲取 DiagnosticSource 中的事件資料,可以通過 DiagnosticSourceEventSource 這個物件來進行資料橋接。

 

0|1Further Reading

 

 

  • Apache SkyWalking 為.NET Core帶來開箱即用的分佈式追蹤和應用性能監控
  • 開放分佈式追蹤(OpenTracing)入門與 Jaeger 實現
  • 幾種分佈式呼叫鏈監控組件的實踐與比較(一)實踐
  • 在 .NET Core 中使用 DiagnosticSource 記錄跟蹤信息
  • CLR公共運行時下性能分析Profiling
  • .NET ClrProfiler ILRewrite實現對應用的跟蹤和分析
  • .NET運行時中的監測和可觀測性 [英文版]
  • Jaeger vs Apache Skywalking
  • Profiling API PR

原文地址:https://www.cnblogs.com/yankliu-vip/p/how-to-implement-apm-tracer-on-dotnet.html


.NET社區新聞,深度好文,歡迎訪問公眾號文章彙總 http://www.csharpkit.com


 

    閱讀原文

    赞(0)

    分享創造快樂