ABP VNext + Elastic APM:微服務性能監控 🚀
📚目錄
- ABP VNext + Elastic APM:微服務性能監控 🚀
- 一、引言 ?
- 架構全景圖 🏗?
- 二、環境與依賴 📦
- 三、APM 服務器與 Kibana 快速部署 🐳
- Docker 網絡示意圖
- 四、在 ABP VNext 中集成 Elastic APM .NET Agent ??
- 4.1 安裝與注冊
- 配置來源
- 4.2 ABP 模塊中注冊中間件與標簽
- 4.3 自動采集范圍
- 4.4 URL 過濾 🚫
- 五、自定義打點與標簽 🎯
- 六、日志關聯 📝
- 6.1 Serilog
- 6.2 Microsoft.Extensions.Logging / NLog
- 七、Kibana APM 儀表盤構建 📊
- 7.1 創建儀表盤(Dashboard)
- 7.2 Transaction 概覽
- 響應時間分布(95th/99th 百分位)
- 吞吐量(TPS)
- 7.3 服務依賴圖(Service Map)
- 7.4 錯誤監控
- Error rate
- 異常類型聚合
- 7.5 原始 Trace 搜索
- 7.6 告警與通知
- 八、性能影響與采樣策略 ??
- 8.1 配置示例(`appsettings.json`)
- 8.2 性能調優要點
- 8.3 微基準測試
- 九、端到端演示示例 🎬
- 參考文檔 📖
一、引言 ?
TL;DR
- 🕵? 使用
Elastic.Apm.NetCoreAll
自動采集 HTTP、數據庫、外部調用與錯誤性能指標 - ?? 支持環境變量與
appsettings.json
雙重配置,零侵入式集成到 ABP VNext 微服務 - 🔗 在 ABP 模塊生命周期中注冊 APM 中間件,并注入租戶與用戶標簽(
SetLabel
API) - 📊 日志框架(Serilog、NLog、Microsoft.Extensions.Logging)一鍵關聯 TraceId/TransactionId
- 🧪 完整示例覆蓋 URL 過濾、自定義 Span、微基準測試與性能調優
背景與動機
在微服務架構下,跨服務調用鏈長、性能瓶頸定位困難。Elastic APM 提供從事務到 Span、從代碼層到基礎設施的一體化可觀察方案,能幫助我們在 Kibana 中實時查看響應分布、調用拓撲與錯誤熱點。結合 ABP VNext 的模塊化與多租戶能力,可快速搭建高性能、可復現的 APM 監控流水線。
架構全景圖 🏗?
二、環境與依賴 📦
-
平臺版本
- .NET 7/8
- ABP VNext 7.x
-
Elastic Stack
- Elasticsearch ≥ 8.x
- Kibana ≥ 8.x(內置 APM 應用)
- APM Server ≥ 8.x
-
NuGet 包
-
Elastic.Apm.NetCoreAll
—— 包含 HTTP、EF Core、SqlClient、Redis 等默認自動打點功能 -
可選:
Elastic.Apm.EntityFrameworkCore
(EF Core 細粒度支持)Elastic.Apm.SqlClient
(針對 MySQL.Data 或其他 ADO.NET 驅動的拓展)Elastic.Apm.SerilogEnricher
(Serilog 日志追蹤關聯)Elastic.Apm.Extensions.Logging
(Microsoft.Extensions.Logging 關聯)
-
三、APM 服務器與 Kibana 快速部署 🐳
version: '3'
services:elasticsearch:image: docker.elastic.co/elasticsearch/elasticsearch:8.5.0environment:- discovery.type=single-nodeports: ["9200:9200"]kibana:image: docker.elastic.co/kibana/kibana:8.5.0ports: ["5601:5601"]apm-server:image: docker.elastic.co/apm/apm-server:8.5.0depends_on: ["elasticsearch"]ports: ["8200:8200"]command: >apm-server -e-E output.elasticsearch.hosts=["elasticsearch:9200"]
執行 docker-compose up -d
后,訪問 http://localhost:5601/app/apm
確認 APM 界面可用。
Docker 網絡示意圖
四、在 ABP VNext 中集成 Elastic APM .NET Agent ??
4.1 安裝與注冊
dotnet add package Elastic.Apm.NetCoreAll
dotnet add package Elastic.Apm.SerilogEnricher
dotnet add package Elastic.Apm.Extensions.Logging
配置來源
-
環境變量(優先級最高)
export ELASTIC_APM_SERVER_URLS=http://localhost:8200 export ELASTIC_APM_SERVICE_NAME=OrderService export ELASTIC_APM_ENVIRONMENT=production export ELASTIC_APM_TRANSACTION_SAMPLE_RATE=1.0
-
appsettings.json
"ElasticApm": {"ServerUrls": "http://localhost:8200","ServiceName": "OrderService","Environment": "production","TransactionSampleRate": 1.0 }
在
Program.cs
中使用:builder.Services.AddAllElasticApm(builder.Configuration);
4.2 ABP 模塊中注冊中間件與標簽
public class OrderWebModule : AbpModule
{public override void OnApplicationInitialization(ApplicationInitializationContext context){var app = context.GetApplicationBuilder();// 1) 注入 APM 中間件app.UseElasticApm(context.GetConfiguration());// 2) 全局標簽注入:租戶 & 用戶Agent.Tracer.Subscribe(new LabelSubscriber(span =>{var tenant = context.ServiceProvider.GetService<ICurrentTenant>()?.Id?.ToString();var user = context.ServiceProvider.GetService<ICurrentUser>()?.Id?.ToString();if (span is Transaction txn){txn.SetLabel("tenantId", tenant);txn.SetLabel("userId", user);}}));// 3) ABP 默認管道app.UseAbpRequestLocalization();app.UseRouting();app.UseAuthentication();app.UseAuthorization();app.UseConfiguredEndpoints();}
}
💡 使用
SetLabel
與LabelSubscriber
,保證線程安全與一致性。
4.3 自動采集范圍
- HTTP/gRPC:自動創建 Transaction;
- SQL 調用:跟蹤
System.Data.SqlClient
/Microsoft.Data.SqlClient
(含 Dapper) ; - 其他 ADO.NET 驅動:可引入
Elastic.Apm.SqlClient
或 Profiler 模式; - 外部 HTTP:
HttpClient
自動跟蹤; - 未捕獲異常:自動上報 Error。
4.4 URL 過濾 🚫
"ElasticApm": {"TransactionIgnoreUrls": "/health*,/metrics*"
}
五、自定義打點與標簽 🎯
using Elastic.Apm;
using Elastic.Apm.Api;// 自定義事務
using var transaction = Agent.Tracer.StartTransaction("ProcessOrder", "order");try
{// 業務邏輯
}
catch (Exception ex)
{// 捕獲并上報異常Agent.Tracer.CurrentTransaction?.CaptureException(ex);throw;
}// 自定義 Span
transaction.CaptureSpan("CallPaymentGateway", "external", () =>
{// 第三方支付調用
});// 額外標簽
transaction.SetLabel("orderType", "Express");
💡 僅在關鍵路徑添加 Span,避免過度細分導致存儲與性能壓力。
六、日志關聯 📝
6.1 Serilog
using Serilog;
using Elastic.Apm.SerilogEnricher;Log.Logger = new LoggerConfiguration().Enrich.WithElasticApmCorrelationInfo().WriteTo.Console(outputTemplate: "[{ElasticApmTraceId} {ElasticApmTransactionId}] {Message:lj}{NewLine}{Exception}").CreateLogger();builder.Host.UseSerilog();
6.2 Microsoft.Extensions.Logging / NLog
builder.Logging.AddConsole().AddConfiguration(builder.Configuration.GetSection("Logging")).AddElasticApm(builder.Configuration);
📑 日志中包含 TraceId/TransactionId,便于跨系統日志與調用鏈關聯
七、Kibana APM 儀表盤構建 📊
7.1 創建儀表盤(Dashboard)
- 在 Kibana 左側菜單中,依次點擊 “Dashboard” → “Create dashboard”。
- 點擊 “Create new visualization”,選擇 “Lens” 作為可視化工具。
7.2 Transaction 概覽
響應時間分布(95th/99th 百分位)
- 在 Lens 中選擇 APM transaction duration 指標。
- 將 transaction.duration.us 拖到縱軸,設置聚合方式為 Percentile,并在右側設置 Percentiles 為
95,99
。 - 保存為 “響應時間分布(P95/P99)”,添加到 Dashboard。
吞吐量(TPS)
- 在 Lens 中選擇 APM transactions per minute(或用 count 并按分鐘做 X 軸)。
- 拖拽 @timestamp 到橫軸,聚合方式設為 Date histogram(interval: auto)。
- 拖拽 transaction.id 計數到縱軸(Count)。
- 保存為 “每分鐘吞吐量 (TPS)”,添加到 Dashboard。
7.3 服務依賴圖(Service Map)
- 在 Kibana 左側菜單點擊 “Observability” → “Service map”。
- 選擇目標服務(如
OrderService
),即可看到上下游依賴拓撲。 - 可切換時間范圍和環境過濾標簽,查看不同環境下的調用鏈。
7.4 錯誤監控
Error rate
- 新建 Visualization,選擇 Lens。
- 拖拽 Error count(apm.error.count)到縱軸,橫軸同樣用 Date histogram。
- 再拖一個 Transaction count(apm.transaction.duration.count),使用 Formula 計算
errors / transactions
。 - 保存為 “錯誤率(Error rate)”。
異常類型聚合
- 在 Lens 中,選擇 apm.error.exception.type 作為分組字段(Break down by)。
- 縱軸用 Count of errors。
- 保存為 “異常類型分布”。
7.5 原始 Trace 搜索
- 點擊左側 “Observability” → “APM” → “Traces”。
- 在上方搜索框輸入標簽或
transaction.id:<ID>
,點擊 Search。 - 瀏覽單次調用鏈,查看各個 Span 的詳細耗時和堆棧。
7.6 告警與通知
- 在 Kibana 菜單中選擇 “Alerting” → “Create rule”。
- 規則類型選擇 “APM transaction duration threshold”。
- 配置閾值(如平均響應時間 > 500 ms)、時間窗口和觸發條件。
- 添加動作(Email、Slack、Webhook 等)并啟用規則。
- 在 Dashboard 中可以直接用 “Add panel” 引入告警狀態監控。
八、性能影響與采樣策略 ??
8.1 配置示例(appsettings.json
)
"ElasticApm": {"TransactionSampleRate": 0.2,"SpanStackTraceMinDuration": "10ms","StackTraceLimit": 200,"CaptureBody": "errors","SanitizeFieldNames": ["password"],"TransactionIgnoreUrls": "/health*,/metrics*"
}
8.2 性能調優要點
- 🔽 降低采樣率可顯著提升吞吐與減少資源占用
- 🔧 調整堆棧閾值可降低內存與 GC 壓力
8.3 微基準測試
[MemoryDiagnoser]
public class ApmSamplingBenchmark
{private readonly HttpClient _client = new();[Params(1.0, 0.5, 0.2)]public double SampleRate;[GlobalSetup]public void Setup(){Environment.SetEnvironmentVariable("ELASTIC_APM_TRANSACTION_SAMPLE_RATE",SampleRate.ToString());// 重啟應用后執行 Benchmark}[Benchmark]public async Task CallOrderApi() =>await _client.GetAsync("https://localhost:5001/api/orders");
}
CI 跑分,僅供參考
SampleRate 吞吐 (ops/s) 內存 (MB) 覆蓋率 (%) 1.0 5200 155 100 0.5 6100 125 80 0.2 7300 98 40
九、端到端演示示例 🎬
- 🚀 啟動微服務集群與 Elastic Stack
- 🔄 調用下單接口,觸發數據庫與外部 HTTP
- 📈 在 Kibana 查看事務、錯誤與調用鏈
- 🐌 模擬慢查詢與異常,驗證告警與過濾規則
參考文檔 📖
- ABP VNext 官方文檔
- Elastic APM .NET Agent 快速上手
- Elastic APM .NET Agent Serilog 集成
- Elastic APM .NET Agent Logging 集成
- APM Server 安裝與配置
- Kibana APM 使用概覽
- BenchmarkDotNet 入門指南
- Elasticsearch 索引生命周期管理(ILM)
- Docker Compose 快速入門 Elastic Stack