Nestjs教程使用OpenTelemetry进行分布式追踪
我正在学习使用Nestjs和OpenTelemetry实现分布式追踪,但在实践中遇到了一些问题:
-
如何正确地在Nestjs项目中集成OpenTelemetry?官方文档看起来有点分散,有没有具体的配置示例?
-
在微服务架构中,如何确保跨服务的trace能够正确关联?特别是当使用不同技术栈的服务时,该如何处理?
-
OpenTelemetry的采样率设置有什么最佳实践吗?在高并发生产环境中应该如何配置?
-
有没有推荐的可视化工具来查看这些分布式追踪数据?除了Jaeger和Zipkin之外,还有其他选择吗?
-
在Nestjs中,如何为特定的业务逻辑添加自定义span?比如想追踪某个复杂计算过程的耗时。
希望能得到有实际经验的朋友的指导,谢谢!
NestJS 结合 OpenTelemetry 实现分布式追踪的步骤如下:
-
安装依赖
首先需要安装 NestJS 的 OpenTelemetry 支持包和相关的 tracer:npm install [@opentelemetry](/user/opentelemetry)/api [@opentelemetry](/user/opentelemetry)/sdk-trace-web [@opentelemetry](/user/opentelemetry)/exporter-jaeger [@nestjs](/user/nestjs)/telemetry
-
配置 OpenTelemetry
创建一个全局的 TracerProvider 配置文件(如tracer.provider.ts
):import { registerAs } from '[@nestjs](/user/nestjs)/config'; import { NodeTracerProvider } from '[@opentelemetry](/user/opentelemetry)/sdk-trace-node'; import { JaegerExporter } from '[@opentelemetry](/user/opentelemetry)/exporter-jaeger'; export const tracerProviderConfig = registerAs('opentelemetry', () => { const provider = new NodeTracerProvider(); const exporter = new JaegerExporter({ endpoint: 'http://localhost:14268/api/traces', }); provider.addExporter(exporter); provider.register(); return { isActive: true, }; });
-
集成到 NestJS
在app.module.ts
中引入 OpenTelemetry 提供器:import { Module } from '[@nestjs](/user/nestjs)/common'; import { APP_INTERCEPTOR } from '[@nestjs](/user/nestjs)/core'; import { TracingInterceptor } from '[@nestjs](/user/nestjs)/telemetry'; import { tracerProviderConfig } from './tracer.provider'; [@Module](/user/Module)({ imports: [], providers: [ { provide: APP_INTERCEPTOR, useClass: TracingInterceptor, }, ], }) export class AppModule {}
-
启动 Jaeger 服务
使用 Docker 启动 Jaeger:docker run -d --name jaeger \ -e COLLECTOR_ZIPKIN_HTTP_PORT=9411 \ -p 5775:5775/udp \ -p 6831:6831/udp \ -p 6832:6832/udp \ -p 5778:5778 \ -p 16686:16686 \ -p 14268:14268 \ -p 14250:14250 \ -p 9411:9411 \ jaegertracing/all-in-one:latest
-
验证追踪
启动 NestJS 应用后,Jaeger UI 将显示应用的调用链路。访问http://localhost:16686
查看 Trace 数据。
这样就完成了 NestJS 的分布式追踪配置。
以下是一个简单的NestJS项目结合OpenTelemetry实现分布式追踪的步骤:
- 初始化NestJS项目:
npm i -g @nestjs/cli
nest new my-app
cd my-app
- 安装OpenTelemetry相关依赖:
npm install --save @opentelemetry/api @opentelemetry/sdk-trace-web @opentelemetry/exporter-jaeger
- 配置OpenTelemetry:
创建
src/trace.ts
文件:
import { registerAs } from '@nestjs/config';
import * as opentelemetry from '@opentelemetry/api';
export const traceConfig = registerAs('trace', () => ({
serviceName: 'my-nest-app',
}));
export function setupOpenTelemetry() {
const tracerProvider = new opentelemetry.NodeTracerProvider();
// 设置导出器(这里以Jaeger为例)
const jaegerExporter = new opentelemetry.exporter.JaegerExporter({
endpoint: 'http://localhost:14268/api/traces',
});
tracerProvider.addSpanProcessor(new opentelemetry.SimpleSpanProcessor(jaegerExporter));
tracerProvider.register();
}
- 在主模块中初始化:
在
main.ts
中添加:
import { setupOpenTelemetry } from './trace';
async function bootstrap() {
setupOpenTelemetry(); // 初始化OpenTelemetry
const app = await NestFactory.create(AppModule);
await app.listen(3000);
}
bootstrap();
- 创建服务并生成Trace:
例如,在
src/app.service.ts
中:
import { Injectable, Trace } from '@nestjs/common';
import { tracer } from '@opentelemetry/api';
@Injectable()
export class AppService {
getHello(): string {
const span = tracer.trace('app.service.getHello');
span.setAttribute('key', 'value');
span.end();
return 'Hello World!';
}
}
- 启动Jaeger:
docker run -d --name jaeger \
-e COLLECTOR_ZIPKIN_HTTP_PORT=9411 \
-p 5775:5775/udp \
-p 6831:6831/udp \
-p 6832:6832/udp \
-p 5778:5778 \
-p 16686:16686 \
-p 14268:14268 \
-p 14250:14250 \
-p 9411:9411 \
jaegertracing/all-in-one:latest
- 访问
http://localhost:16686
查看分布式追踪数据。
NestJS 使用 OpenTelemetry 进行分布式追踪指南
OpenTelemetry 是一个开源的可观测性框架,用于生成、收集和导出分布式追踪数据。在 NestJS 中使用 OpenTelemetry 可以帮助你监控微服务架构中的请求流程。
基本设置步骤
- 安装必要依赖
npm install @opentelemetry/sdk-node
npm install @opentelemetry/auto-instrumentations-node
npm install @opentelemetry/exporter-trace-otlp-grpc
- 创建 tracing.ts 配置文件
import { NodeSDK } from '@opentelemetry/sdk-node';
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-grpc';
const sdk = new NodeSDK({
traceExporter: new OTLPTraceExporter({
url: 'your-collector-endpoint' // 例如: 'http://localhost:4317'
}),
instrumentations: [getNodeAutoInstrumentations()]
});
sdk.start();
- 在 main.ts 中导入
import './tracing';
import { NestFactory } from '@nestjs/core';
// ...其余应用代码
自定义追踪
你可以创建自定义的跨度来追踪特定业务逻辑:
import { trace } from '@opentelemetry/api';
async function myBusinessLogic() {
const tracer = trace.getTracer('my-service');
return tracer.startActiveSpan('business-logic', async (span) => {
try {
// 你的业务逻辑
span.setAttribute('custom.attribute', 'value');
return result;
} finally {
span.end();
}
});
}
与Jaeger/Zipkin集成
如果你使用Jaeger或Zipkin作为后端:
// 使用Jaeger exporter
import { JaegerExporter } from '@opentelemetry/exporter-jaeger';
const sdk = new NodeSDK({
traceExporter: new JaegerExporter({
endpoint: 'http://localhost:14268/api/traces'
}),
// ...其他配置
});
最佳实践
- 确保在微服务环境中传递追踪上下文(通过HTTP头或消息属性)
- 为关键业务操作添加自定义跨度
- 合理设置采样率以平衡性能和可观测性
- 使用语义约定的属性名称
记得根据你的实际环境和需求调整配置,特别是收集器地址和采样策略。