WEBKT

OpenTelemetry 如何在遗留系统和非 HTTP 协议中传递 Context?

71 0 0 0

OpenTelemetry 的 Context 传递机制是其核心功能之一,它允许跨服务追踪请求,从而实现可观测性。在 HTTP 协议下,Context 传递相对简单,通常通过 HTTP Header 实现。但在面对遗留系统和各种非 HTTP 协议时,情况会变得复杂。下面详细解释 OpenTelemetry 如何处理这些情况:

1. HTTP 协议的 Context 传递:

  • 原理: OpenTelemetry 使用 W3C Trace Context 标准,将 Trace ID 和 Span ID 等信息放入 HTTP Header 中。
  • 实现: SDK 自动完成 Header 的注入和提取。例如,发起 HTTP 请求时,SDK 会将必要的 Context 信息注入到 Header 中;接收请求时,SDK 会从 Header 中提取 Context 信息,并将其设置为当前 Span 的父 Context。
  • 优点: 标准化、自动化,对应用代码的侵入性较小。

2. 非 HTTP 协议的 Context 传递:

  • 挑战: 非 HTTP 协议没有统一的 Header 规范,需要自定义 Context 传递机制。
  • 解决方案:
    • Carrier 接口: OpenTelemetry 提供了 TextMapPropagator 接口,允许自定义 Context 的序列化和反序列化方式,以及 Context 信息在消息中的存储位置。你需要实现 SetterGetter 接口,分别用于将 Context 注入到消息中和从消息中提取 Context。
    • 手动注入和提取: 在发送消息之前,使用 TextMapPropagator.inject() 方法将 Context 注入到消息中;在接收消息之后,使用 TextMapPropagator.extract() 方法从消息中提取 Context。
    • 示例(以 RabbitMQ 为例):
      // 注入 Context
      TextMapPropagator propagator = GlobalOpenTelemetry.getPropagators().getTextMapPropagator();
      Map<String, String> headers = new HashMap<>();
      propagator.inject(Context.current(), headers, (carrier, key, value) -> carrier.put(key, value));
      AMQP.BasicProperties properties = new AMQP.BasicProperties.Builder()
              .headers(headers)
              .build();
      channel.basicPublish(exchangeName, routingKey, properties, messageBodyBytes);
      
      // 提取 Context
      AMQP.BasicProperties properties = delivery.getProperties();
      Map<String, Object> headers = properties.getHeaders();
      Context context = propagator.extract(Context.current(), headers, (carrier, key) -> {
          Object value = carrier.get(key);
          return value == null ? null : value.toString();
      });
      
  • 注意事项:
    • 选择合适的 Context 存储位置:根据协议的特点,选择一个合适的位置来存储 Context 信息,例如消息头、消息体等。
    • 考虑性能影响:Context 的序列化和反序列化会带来一定的性能开销,需要根据实际情况进行优化。
    • 保持一致性:确保在所有服务中使用相同的 Context 传递机制,避免出现兼容性问题。

3. 遗留系统的集成:

  • 适配器模式: 为遗留系统编写适配器,将 OpenTelemetry 的 Context 传递机制集成到遗留系统中。
  • 代理模式: 在遗留系统和 OpenTelemetry 之间添加一个代理层,负责 Context 的注入和提取。
  • 逐步迁移: 逐步将遗留系统迁移到 OpenTelemetry,而不是一次性完成。

总结:

OpenTelemetry 提供了灵活的 Context 传递机制,可以适应各种不同的协议和系统。虽然在非 HTTP 协议和遗留系统集成时需要进行一些额外的工作,但通过自定义 TextMapPropagator 和采用适配器/代理模式,可以实现无缝集成和可靠传递。关键在于理解 OpenTelemetry 的核心概念,并根据实际情况选择合适的集成方案。在评估 OpenTelemetry 时,需要充分考虑其灵活性和可扩展性,以及对现有系统的潜在影响。

OTelFan Context传递遗留系统

评论点评