Dapper在gRPC服务中怎么用 Dapper与gRPC结合实例

10次阅读

OpenTelemetry.net 中实现分布式追踪的标准方案,取代了已不维护的 Dapper 概念;通过 OpenTelemetry.Instrumentation.AspNetCore、GrpcNetClient 和 OTLP 导出器,结合 gRPC 拦截器,可自动采集端到端调用链。

Dapper在gRPC服务中怎么用 Dapper与gRPC结合实例

Dapper 是 google 提出的分布式追踪系统理念,而实际在 .NET 生态中,“Dapper” 更常被误指为 OpenTelemetry(尤其是 .NET 的 OpenTelemetry.Trace 实现),因为原生 Dapper 已不维护,且 .NET 社区普遍用 OpenTelemetry 替代其实现链路追踪。gRPC 服务本身不内置追踪能力,需借助 OpenTelemetry + gRPC 拦截器(Interceptor)来实现端到端调用链采集。

为什么不是“Dapper”而是 OpenTelemetry?

.NET 中没有官方叫 “Dapper”的分布式追踪库;名字易混淆是因为:

  • “Dapper” 是 google 2010 年论文提出的概念模型(如 trace/span/annotation),不是具体 SDK;
  • microsoft 和 CNCF 推荐并深度集成的是 OpenTelemetry(OTel),它正是 Dapper 思想的现代开源实现;
  • gRPC .NET 官方文档和示例均基于 OpenTelemetry 构建追踪能力。

在 gRPC Server 中启用 OpenTelemetry 追踪

以 ASP.NET Core gRPC 服务为例,只需几处配置即可自动捕获 RPC 方法调用:

  • 安装 NuGet 包:OpenTelemetry.Instrumentation.GrpcNetClient(客户端)、OpenTelemetry.Instrumentation.AspNetCore(服务端 http 层)、OpenTelemetry.Exporter.OpenTelemetryProtocol(导出到 Jaeger/Zipkin/OTLP 后端);
  • Program.cs 中注册追踪器:

(C# 示例)

builder.Services.AddOpenTelemetry().WithTracing(tracerProviderBuilder =>
tracerProviderBuilder
.AddAspNetCoreInstrumentation() // 捕获 HTTP 入口(含 gRPC over HTTP/2)
.AddGrpcClientInstrumentation() // 自动注入 client 端 span
.AddOtlpExporter(opt => opt.Endpoint = new Uri("http://localhost:4317")); // 推送到 OTLP

✅ 效果:每个 gRPC 方法(如 SayHello)会自动生成 span,包含 method、status、duration、peer.address 等属性。

手动创建 Span 关联业务逻辑

若需追踪方法内部耗时操作(如 DB 查询、HTTP 调用),可在 service 实现中手动添加上下文感知的 span:

  • 通过 System.Diagnostics.ActivitySource 创建自定义 span;
  • 或使用 TracerProvider.Current.GetTracer(...).StartActiveSpan(...)
  • 关键:确保 span 设置 SetParentId(Activity.Current?.Id) 维持链路连续性。

例如在 GreeterService.SayHello 中记录数据库查询:

(片段示意)

using var dbSpan = tracer.StartActiveSpan("db.query.users", ActivityKind.internal);
try {
var user = await _userRepository.GetByIdAsync(request.Name);
dbSpan.SetAttribute("user.found", user != NULL);
} finally {
dbSpan.End();
}

客户端也需埋点才能形成完整链路

仅服务端埋点只能看到入向请求;要串联 client → server → downstream service,客户端 gRPC 调用也必须启用 OTel:

  • 创建 channel 时注入拦截器:GrpcChannel.ForAddress(..., new GrpcChannelOptions { Interceptors = { new OpenTelemetryInterceptor() } });
  • 确保 client 项目同样引用 OpenTelemetry.Instrumentation.GrpcNetClient 并注册;
  • 调用 stub.SayHelloAsync(...) 时,会自动携带 traceparent HTTP header,服务端自动解析并续接 span。

基本上就这些。不需要改业务代码结构,也不依赖特定框架——OpenTelemetry 是标准、轻量、可插拔的方案。只要 client/server 都开启 OTel + gRPC 拦截器,调用链就能自动串起来,再配上 Jaeger 或 prometheus + Tempo,就能可视化查看延迟瓶颈、错误分布和上下游依赖关系。

text=ZqhQzanResources