在.NET Core 中收集数据的几种方式
APM是一種應(yīng)用性能監(jiān)控工具,可以幫助理解系統(tǒng)行為, 用于分析性能問題的工具,以便發(fā)生故障的時候,能夠快速定位和解決問題, 通過匯聚業(yè)務(wù)系統(tǒng)各處理環(huán)節(jié)的實時數(shù)據(jù),分析業(yè)務(wù)系統(tǒng)各事務(wù)處理的交易路徑和處理時間,實現(xiàn)對應(yīng)用的全鏈路性能監(jiān)測。
[1]
組成結(jié)構(gòu)
?
探針(Agent):負(fù)責(zé)在客戶端程序運行時搜索服務(wù)調(diào)用鏈路信息,發(fā)送給收集器
?
收集器(Collector):負(fù)責(zé)將數(shù)據(jù)格式化,保存到存儲器
?
存儲器(Storage):保存程序數(shù)據(jù)
?
UI界面(Dashboard):多維度展示數(shù)據(jù)
本文會主要針對 探針 (Agent), 分享下在.NET 程序中收集程序數(shù)據(jù)的幾種方式,如果需要自研 APM 系統(tǒng)或者收集數(shù)據(jù)來進(jìn)行系統(tǒng)分析,希望能可以給大家一些幫助,以下幾種方式,大家可以針對自己的場景去選擇,我們的目的只是收集數(shù)據(jù)。
手動埋點
手動埋點比較簡單,我們需要在一些操作前后可以手動包裹我們的埋點代碼,比如 Http,RPC,DB, MQ 等調(diào)用,非常靈活,可以在任意的地方添加我們的埋點信息,然后匯總數(shù)據(jù),按批發(fā)送,缺點是對程序的侵入性較高,不太優(yōu)雅。
Middleware 中間件 & 過濾器 Filter
得益于 .NET Core 優(yōu)秀的框架設(shè)計, 它具有一個極具擴(kuò)展性的請求處理管道,我們可以通過這個管道的定制來滿足各種場景下的HTTP處理需求。ASP. NET Core應(yīng)用的很多特性,比如路由、認(rèn)證、會話、緩存等,也同時定制消息處理管道來實現(xiàn)的,所以我們需要編寫自定義的攔截中間件 InterceptMiddleware,獲取到請求上下文 HttpContext, 來攔截所有的Http請求收集數(shù)據(jù),注意這里中間件的位置要放到 UseEndpoints() 的上面,同樣可以借助 過濾器 AcitonFilter,來完成同樣的效果, 但是這種方式可獲取的信息有限,只能攔截到 Http 請求的一些信息
DiagnosticSource
實現(xiàn):SkyApm-dotnet https://github.com/SkyAPM/SkyAPM-dotnet HttpReports APM https://github.com/dotnetcore/HttpReports
診斷 DiagnosticSource 我們不經(jīng)常用,可能都有點陌生,但是它的功能是非常強(qiáng)大的,它本身是一個基于發(fā)布訂閱模式的工作模式,我們可以異步的去收集信息,比如 中間件的進(jìn)入和退出,HttpClient 調(diào)用的開始和結(jié)束,并且有很多第三方的庫都支持了 DiagnosticSource,這也是微軟目前推薦的方式,在改動極少代碼的情況下,采集到豐富的運行數(shù)據(jù)。
引用 AOP
額,面向切面編程,這個需要在我們的 .NET 程序中引用 AOP 框架,如果是內(nèi)部系統(tǒng)的話,我覺的還是可以接受的,常見的框架 AspectCore, Castle.Core, 通過 AOP 的特性,我們可以攔截需要獲取數(shù)據(jù)的方法,如果你在項目中,普遍使用依賴注入的話,可以達(dá)到方法級別的監(jiān)控,獲取到的信息非常可觀,另外需要注意的是,獲取的信息越詳細(xì),數(shù)據(jù)量也越大,是全量采集數(shù)據(jù)還是抽樣采集也是要考慮的點
EWT(Event Tracing for Windows)
ETW是Event Tracing for Windows的簡稱,它是Windows提供的原生的事件跟蹤日志系統(tǒng)。由于采用內(nèi)核(Kernel)層面的緩沖和日志記錄機(jī)制,所以ETW提供了一種非常高效的事件跟蹤日志解決方案。這個庫我還沒怎么用過,生而為人,我很抱歉 〒▽〒
Mono.Cecil
Mono.Cecil:一個可加載并瀏覽現(xiàn)有程序集并進(jìn)行動態(tài)修改并保存的.NET框架, Mono Cecil十分強(qiáng)大,可以靜態(tài)注入程序集(注入后生成新的dll程序集)和動態(tài)注入程序集(注入后不改變目標(biāo)程序集,只在運行時改變程序集行為,騰訊開源的Unity熱更解決方案xLua有一個非常吸引人的特性就是Hotfix,其原理是使用Mono.Cecil庫對進(jìn)行C#層編譯出來的dll程序集進(jìn)行IL代碼注入。
CLR Profiling API
實現(xiàn) 聽云APM(商業(yè))OneAPM (商業(yè))Datadog (商業(yè))
https://docs.microsoft.com/en-us/archive/blogs/yirutang/clr-profiling-api
這個真的是一個很棒的方案,你可以看到,很多的 商業(yè)APM 系統(tǒng),都采用了這種方式,因為它是一種無侵入的收集方式,CLR Profiling (分析) API 是CLR中最酷的東西之一, 分析 API 提供 CLR 中發(fā)生的各種事件和操作的相關(guān)信息, 你可以使用此信息來監(jiān)視進(jìn)程的內(nèi)部工作情況,也可分析 .NET 應(yīng)用程序的性能
支持的功能如下:
?CLR 啟動和關(guān)閉事件。?應(yīng)用程序域創(chuàng)建和關(guān)閉事件。?程序集加載和卸載事件。?模塊加載和卸載事件。?COM vtable 創(chuàng)建和析構(gòu)事件。?實時 (JIT) 編譯和代碼間距調(diào)整事件。?類加載和卸載事件。?線程創(chuàng)建和析構(gòu)事件。?函數(shù)入口和退出事件。?異常。?托管和非托管代碼執(zhí)行之間的轉(zhuǎn)換。?不同運行時上下文之間的轉(zhuǎn)換。?有關(guān)運行時掛起的信息。?有關(guān)運行時內(nèi)存堆和垃圾回收活動的信息。
這可能要求你掌握 C++ 和 C#, 另外需要注意的是,Profiler 是一個非托管的 DLL 庫,會在應(yīng)用運行時被加載到 CLR 中并與應(yīng)用處于同一進(jìn)程空間下,所以 Profiler DLL 實質(zhì)上是不受托管代碼的訪問控制的,還有,Profiler DLL 作為 CLR 的一個插件,其運行錯誤可能會引起 CLR 本身的崩潰,所以你必須要知道這些風(fēng)險,并且足夠小心,最后祝你好運
另外
HttpReports 是針對.Net Core 開發(fā)的APM系統(tǒng), 基于MIT開源協(xié)議,針對于微服務(wù)場景,感興趣的同學(xué)可以點個 Star 支持下,謝謝
Github:https://github.com/dotnetcore/HttpReports
?
總結(jié)
以上是生活随笔為你收集整理的在.NET Core 中收集数据的几种方式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一次Task.Run异常问题的排查
- 下一篇: 改进你的代码-扩展了一下IEnumera