分布式跟踪编辑

分布式跟踪使您能够在一个视图中分析整个微服务架构的性能。这是通过跟踪所有请求来实现的,从最初的 Web 请求到前端服务,再到后端服务的查询。这使得在整个应用程序中查找可能的瓶颈变得更加容易和快捷。

Elastic APM 自动支持分布式跟踪,但在某些情况下(如下所述),需要进行额外的设置。

真实用户监控 (RUM) 关联编辑

如果您的后端服务动态生成 HTML 页面,则必须在初始化 RUM 代理时将跟踪 ID 和父级 span ID 注入页面。这可确保 Web 浏览器的页面加载显示为跟踪的根,并允许您分析在浏览器中与在后端服务中花费的时间。

要启用 JavaScript RUM 代理,请将类似于此的代码段添加到 HTML 页面的正文中,最好在其他 JavaScript 库之前

elasticApm.init({
  serviceName: 'my-frontend-app', // Name of your frontend app
  serverUrl: 'https://example.com:8200', // APM Server host
  pageLoadTraceId: '${transaction.traceId}',
  pageLoadSpanId: '${transaction.ensureParentId()}',
  pageLoadSampled: ${transaction.sampled}
})

有关更多信息,请参阅 transaction.ensureParentId()

自定义协议编辑

HTTP/HTTPS 自动支持分布式跟踪。如果您使用的是其他协议,例如 TCP、UDP、WebSocket 或 Protocol Buffers,则必须遵循一些手动设置步骤。

在分布式跟踪中,多个事务通过 traceparent 链接在一起。要创建自己的分布式跟踪,您必须将当前的 traceparent 从传出服务传递到接收服务,并将新事务创建为该 traceparent 的子级

  1. 在一个服务中,使用 apm.startTransaction() 启动事务,或使用 apm.startSpan() 启动 span。
  2. 使用 apm.currentTraceparent 获取已启动事务/span 的序列化 traceparent 字符串。
  3. traceparent 进行编码,并在常规请求中将其发送到接收服务。
  4. 在接收服务中解码并存储 traceparent
  5. 使用 apm.startTransaction() 手动启动作为接收到的 traceparent 子级的新事务。将 traceparent 作为 childOf 选项传入。

示例编辑

考虑一个场景,您正在使用原始 UDP 在两个服务 A 和 B 之间进行通信

服务 A

服务 A 启动一个事务,并获取当前的 traceparent

agent.startTransaction('my-service-a-transaction')
const traceparent = agent.currentTraceparent

然后,服务 A 将 traceparent 作为“标头”发送到服务 B。

// Pseudocode for sending data
sendMetadata(`traceparent: ${traceparent}\n`)

服务 B

服务 B 从传入请求中读取 traceparent

// Pseudocode for reading incoming request
const traceparent = readTraceparentFromUDPPacket()

服务 B 使用 traceparent 初始化作为原始 traceparent 子级的新事务。

agent.startTransaction('my-service-b-transaction', { childOf: traceparent })