Trace 链路追踪

简介: Trace 链路追踪

http 慢日志只能展示出根据开发者设置的 apdex 值计算得出的不能容忍的请求的一些基本信息,包括 host、url、status code、耗时以及发生的时间等信息。

但是绝大部分时候,这些信息不能帮助开发者定位到实际的请求耗时操作,所以提供了这样的一个慢链路追踪模块,旨在帮助开发者能以更清晰的方式解决慢 HTTP 请求问题。

此功能已经正式上线,欢迎大家使用并提出反馈意见。

用法

I. 升级 @alicloud/agenthub

首先执行如下命令重新安装 @alicloud/agenthub 模块来升级最新的 agentx 依赖:

npm install @alicloud/agenthub

需要确认下上一步全局安装的 agenthub 依赖的 agentx 版本 >=1.10.1,才能正常使用 tracing 功能。

安装完成后,按照原来的方式重启下 agenthub 即可生效。

II. 使用 @alicloud/opentracing 埋点

目前需要开发者使用 @alicloud/opentracing 这个模块在整个 HTTP 请求的耗时操作(一般是异步调用)前后进行手动埋点来串联起整个调用链路,下面是此模块的用法。

1. 安装

npm install @alicloud/opentracing

2. 使用

公共类:Tracer(name[, option][, reporter]):

a. 参数:

  • name String - tracer 的名称
  • optionObject - 可选
  • limit Number - 每分钟限制记录落盘的数据条数限制,防止大量异常的情况下大量日志写入文件造成磁盘溢出
  • logger Object - 日志句柄,最小需要实现 info、log、warn 和 error 方法,默认采用 console
  • reporter Object - 自定义发送方法,需要实现 report 方法,入参为 span

b. 成员方法:startSpan(spanName[, option])

  • spanName String - span 的名称,用来标记此 span 下的异步调用
  • optionObject - 可选
  • childOf Object - 传入当前 span 的父级 span 实例
  • 返回值 Object - 返回内置的类 Span 的实例

内置类:Span

a. 成员方法:setTag(tag, value)

  • tag String - Tag 名称,可以自定义,一般从 opentracing.Tags 中获取(里面定义了常见的 host、url、statusCode 等链路信息 Key)
  • value String - Tag 名称对应的值

b. 成员方法:log(key, value)

  • key String - 自定义的日志键
  • value String - 自定义的日志值

c. 成员方法:finish(req)

  • req Object - http 请求的 request 对象

完整例子

下面是一个给 express 应用中间件埋点的使用完整样例,模拟了并发的异步耗时调用,和顺序的异步耗时调用:

注意: 有效的 root span(即能在控制台正常看到的慢链路)中的 tags 信息必须包含 **HTTP_METHOD **、HTTP_URLHTTP_STATUS_CODE,否则会被服务端过滤掉!

'use strict';
const express = require('express');
const app = express();
const opentracing = require('@alicloud/opentracing');
const tracer = new opentracing.Tracer('测试链路');
// 模拟耗时的异步操作
function delay(time, req) {
  let child = tracer.startSpan('子模块 1: 随机并发延迟', { childOf: req.parentSpan });
  child.setTag('timeout', time);
  child.log({ state: 'timer1' });
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve();
      child.finish(req);
    }, time);
  });
}
// 在所有中间件之前,开启一个根 span,记录下 hostname、method、url,以及收到 end 事件后的
app.use(function (req, res, next) {
  req.parentSpan = tracer.startSpan('根模块');
  req.parentSpan.setTag(opentracing.Tags.PEER_HOSTNAME, req.hostname);
  req.parentSpan.setTag(opentracing.Tags.HTTP_METHOD, req.method.toUpperCase());
  req.parentSpan.setTag(opentracing.Tags.HTTP_URL, req.url);
  next();
  res.once('finish', () => {
    req.parentSpan.setTag(opentracing.Tags.HTTP_STATUS_CODE, res.statusCode);
    req.parentSpan.finish(req);
  });
});
// 模拟并发的耗时异步操作
app.use(function (req, res, next) {
  Promise.all([
    delay(Math.random() * 10 * 1000, req),
    delay(Math.random() * 10 * 1000, req)
  ]).then(() => next());
});
// 继续模拟一个顺序的 3s 耗时异步操作
app.use(function (req, res, next) {
  let child = tracer.startSpan('子模块 2: 延迟 3s', { childOf: req.parentSpan });
  child.setTag('timeout', '3s');
  child.log({ state: 'timer2' });
  // 3s call
  setTimeout(() => {
    child.finish(req);
    next()
  }, 3000);
});
// 响应页面
app.get('*', function (req, res) {
  res.send('Hello Node.js Performance Platform!');
});
app.listen(3000);

在浏览器请求 http://localhost:3000/delay, 等待约 1min 后,可以在控制台的相应 Tab 页看到:

点击 请求信息 栏下面对应的字符串或者长条可以看到开发者自行记录的当前请求详情,比如例子中在随机延迟中分别用 tag 和 log 记录了当前延迟 ms 数和定时器名称,那么点开 子模块1 对应的请求信息栏中的长条后可以看到如下内容:

相关实践学习
分布式链路追踪Skywalking
Skywalking是一个基于分布式跟踪的应用程序性能监控系统,用于从服务和云原生等基础设施中收集、分析、聚合以及可视化数据,提供了一种简便的方式来清晰地观测分布式系统,具有分布式追踪、性能指标分析、应用和服务依赖分析等功能。 分布式追踪系统发展很快,种类繁多,给我们带来很大的方便。但在数据采集过程中,有时需要侵入用户代码,并且不同系统的 API 并不兼容,这就导致了如果希望切换追踪系统,往往会带来较大改动。OpenTracing为了解决不同的分布式追踪系统 API 不兼容的问题,诞生了 OpenTracing 规范。OpenTracing 是一个轻量级的标准化层,它位于应用程序/类库和追踪或日志分析程序之间。Skywalking基于OpenTracing规范开发,具有性能好,支持多语言探针,无侵入性等优势,可以帮助我们准确快速的定位到线上故障和性能瓶颈。 在本套课程中,我们将全面的讲解Skywalking相关的知识。从APM系统、分布式调用链等基础概念的学习加深对Skywalking的理解,从0开始搭建一套完整的Skywalking环境,学会对各类应用进行监控,学习Skywalking常用插件。Skywalking原理章节中,将会对Skywalking使用的agent探针技术进行深度剖析,除此之外还会对OpenTracing规范作整体上的介绍。通过对本套课程的学习,不止能学会如何使用Skywalking,还将对其底层原理和分布式架构有更深的理解。本课程由黑马程序员提供。
相关文章
|
消息中间件 监控 NoSQL
工作用Go: 异步任务怎么写4 | Trace: 异步任务还能进行链路追踪么?
工作用Go: 异步任务怎么写4 | Trace: 异步任务还能进行链路追踪么?
465 0
工作用Go: 异步任务怎么写4 | Trace: 异步任务还能进行链路追踪么?
|
存储 Java 应用服务中间件
SpringBoot 如何在日志中增加 trace id 用于链路追踪
SpringBoot 如何在日志中增加 trace id 用于链路追踪
5184 0
SpringBoot 如何在日志中增加 trace id 用于链路追踪
|
监控 网络协议 Java
分布式链路追踪- SkyWalking使用手册
分布式链路追踪- SkyWalking使用手册
1002 0
分布式链路追踪- SkyWalking使用手册
|
1月前
|
消息中间件 SpringCloudAlibaba Java
【Springcloud Alibaba微服务分布式架构 | Spring Cloud】之学习笔记(八)Config服务配置+bus消息总线+stream消息驱动+Sleuth链路追踪
【Springcloud Alibaba微服务分布式架构 | Spring Cloud】之学习笔记(八)Config服务配置+bus消息总线+stream消息驱动+Sleuth链路追踪
812 0
|
7月前
|
存储 监控 数据可视化
Golang链路追踪:实现高效可靠的分布式系统监控
Golang链路追踪:实现高效可靠的分布式系统监控
|
7月前
|
消息中间件 监控 安全
RocketMQ x OpenTelemetry 分布式全链路追踪最佳实践(3)
RocketMQ x OpenTelemetry 分布式全链路追踪最佳实践
79 0
RocketMQ x OpenTelemetry 分布式全链路追踪最佳实践(3)
|
7月前
|
消息中间件 Java Kafka
RocketMQ x OpenTelemetry 分布式全链路追踪最佳实践(2)
RocketMQ x OpenTelemetry 分布式全链路追踪最佳实践(2)
70 0
RocketMQ x OpenTelemetry 分布式全链路追踪最佳实践(2)
|
7月前
|
消息中间件 Cloud Native Apache
RocketMQ x OpenTelemetry 分布式全链路追踪最佳实践(1)
RocketMQ x OpenTelemetry 分布式全链路追踪最佳实践
52 0
RocketMQ x OpenTelemetry 分布式全链路追踪最佳实践(1)
|
11月前
|
SpringCloudAlibaba 算法 Java
Spring Boot项目如何实现分布式日志链路追踪
作为一名后端开发工程师,排查系统问题用得最多的手段之一就是查看系统日志,在当下主要的分布式集群环境中一般使用ELK(Elasticsearch , Logstash, Kibana)来统一收集日志,以便后续查看日志定位追踪相关问题。但是在并发情况下,大量的系统用户即多线程并发访问后端服务导致同一个请求的日志记录不再是连续相邻的,此时多个请求的日志是一起串行输出到文件中,所以我们筛选出指定请求的全部相关日志还是比较麻烦的,同时当后端异步处理功能逻辑以及微服务的下游服务调用日志追踪也有着相同的问题。
|
消息中间件 数据可视化 JavaScript
什么是链路追踪?分布式系统如何实现链路追踪?
什么是链路追踪?分布式系统如何实现链路追踪?

热门文章

最新文章