菜单
文档breadcrumb arrow Grafana Alloybreadcrumb arrow 参考breadcrumb arrow 组件breadcrumb arrow otelcolbreadcrumb arrow otelcol.exporter.loadbalancing
开源

otlcol.exporter.loadbalancing

otelcol.exporter.loadbalancing 接收来自其他 otelcol 组件的日志和跟踪,并使用 OpenTelemetry 协议(OTLP)在网络中写入。

注意

otelcol.exporter.loadbalancing 是上游 OpenTelemetry Collector loadbalancing 导出器的包装器。如有必要,错误报告或功能请求将被重定向到上游存储库。

可以通过为它们提供不同的标签来指定多个 otelcol.exporter.loadbalancing 组件。

选择后端的决定取决于跟踪 ID 或服务名称。后端负载不会影响选择。即使这个负载均衡器不会进行轮询平衡批次,后端之间的负载分配也应该非常相似,在当前配置下标准差小于 5%。

otelcol.exporter.loadbalancing 对于使用基于尾部采样器配置的后端尤其有用,这些采样器根据完整跟踪视图选择后端。

当后端列表更新时,一些信号将被重新路由到不同的后端。大约 R/N 的“路由”将被重新路由,其中

  • “路由”是指映射到特定后端的跟踪 ID 或服务名称。
  • “R”是路由的总数。
  • “N”是后端的总数。

这对于大多数情况来说应该足够稳定,后端数量越多,它应该造成的干扰就越小。

使用方法

alloy
otelcol.exporter.loadbalancing "LABEL" {
  resolver {
    ...
  }
  protocol {
    otlp {
      client {}
    }
  }
}

参数

otelcol.exporter.loadbalancing 支持以下参数

名称类型描述默认值必需
routing_keystring负载均衡的路由策略。"traceID"

routing_key 属性确定如何跨端点路由信号。其值可以是以下之一

  • "service": 具有相同 service.name 的跨度将被导出到相同后端。当使用像跨度指标这样的处理器时,这很有用,因为每个服务的所有跨度都会发送到一致的 Alloy 实例进行指标收集。否则,相同服务的指标将发送到不同的实例,导致聚合不准确。
  • "traceID": 属于同一 traceID 的跨度将被导出到相同后端。

以下块在 otelcol.exporter.loadbalancing 的定义中受支持

层次结构描述必需
resolverresolver配置发现要导出的端点。
resolver > staticstatic要导出的端点的静态列表。
resolver > dnsdns要导出的端点的 DNS 来源列表。
resolver > kuberneteskubernetes要导出的端点的 Kubernetes 来源列表。
resolver > aws_cloud_mapaws_cloud_map要导出的端点的 AWS CloudMap 来源列表。
protocolprotocol协议设置。目前仅支持 OTLP。
protocol > otlpotlp配置 OTLP 导出器。
protocol > otlp > clientclient配置导出器 gRPC 客户端。
protocol > otlp > client > tlstls为 gRPC 客户端配置 TLS。
protocol > otlp > client > keepalivekeepalive为 gRPC 客户端配置 keepalive 设置。
protocol > otlp > queuequeue在发送之前配置数据批处理。
protocol > otlp > retryretry为失败的请求配置重试机制。
debug_metricsdebug_metrics配置此组件生成的指标以监视其状态。

> 符号表示更深的嵌套级别。例如,resolver > static 指的是在 resolver 块内定义的 static 块。

resolver 块

resolver 块配置如何检索此导出器将发送数据的端点。

resolver 块内部,应指定 dns 块或 static 块。如果同时指定了 dnsstatic,则 dns 优先。

static 块

static 块配置此导出器将发送数据的端点列表。

以下参数受支持

名称类型描述默认值必需
hostnameslist(string)要导出的端点列表。

dns 块

dns块会定期通过DNS的hostname属性解析IP地址。然后,将使用这个IP地址以及通过port属性指定的端口,作为gRPC导出器导出数据的目标端点。

以下参数受支持

名称类型描述默认值必需
hostnamestring要解析的DNS主机名。
interval持续时间解析器间隔。"5s"
timeout持续时间解析器超时。"1s"
portstring用于通过DNS主机名解析的IP地址的端口。"4317"

kubernetes块

可以使用kubernetes块在Kubernetes服务的Pod之间进行负载均衡。Kubernetes API会在服务中添加或移除新的Pod时通知Alloy。由于不需要轮询,因此kubernetes解析器的响应时间比dns解析器快得多。

以下参数受支持

名称类型描述默认值必需
servicestring要解析的Kubernetes服务。
portslist(number)与从service解析的IP地址一起使用的端口。[4317]
timeout持续时间解析器超时。"1s"

如果service内部没有指定命名空间,将尝试推断此Alloy的命名空间。如果失败,将使用default命名空间。

ports中列出的每个端口都将与从service解析的每个IP地址一起使用。

解析器要正常工作,必须在Kubernetes中授予“get”、“list”和“watch”角色

aws_cloud_map块

aws_cloud_map块允许用户在AWS基础设施中使用EKS上的ECS时使用otelcol.exporter.loadbalancing

以下参数受支持

名称类型描述默认值必需
namespacestring服务注册的CloudMap命名空间。
service_namestring在注册实例时指定的服务名称。
interval持续时间解析器间隔。"30s"
timeout持续时间解析器超时。"5s"
health_statusstring与从service解析的IP地址一起使用的端口。"HEALTHY"
portnumber用于将跟踪导出到从service解析的地址的端口。null

health_status可以设置为以下之一

  • HEALTHY:仅返回健康的实例。
  • UNHEALTHY:仅返回不健康的实例。
  • ALL:返回所有实例,无论其健康状态如何。
  • HEALTHY_OR_ELSE_ALL:返回健康的实例,除非没有报告健康状态的实例。在这种情况下,返回所有实例。这也称为失败打开。

如果没有设置port,将使用CloudMap中定义的默认端口。

注意

aws_cloud_map解析器返回的最大主机数为100。一个功能请求旨在为这种情况提供分页。

protocol块

protocol块配置导出协议相关的设置。目前仅支持OTLP协议。

otlp块

otlp块配置导出OTLP相关的设置。

client块

client块配置组件使用的gRPC客户端。客户端块使用的端点是来自resolver块的端点

以下参数受支持

名称类型描述默认值必需
compressionstring用于请求的压缩机制。"gzip"
read_buffer_sizestringgRPC客户端用于读取服务器响应的读取缓冲区大小。
write_buffer_sizestringgRPC客户端用于写入请求的写入缓冲区大小。"512KiB"
wait_for_ready布尔值在发送数据之前等待gRPC连接处于READY状态。false
headersmap(string)与请求一起发送的附加头。{}
balancer_namestring用于请求的哪个gRPC客户端端点负载均衡器。round_robin
authoritystring覆盖gRPC客户端请求中的默认:authority头。
authcapsule(otelcol.Handler)用于验证请求的来自 otelcol.auth 组件的处理程序。

默认情况下,请求使用 Gzip 进行压缩。compression 参数控制使用哪种压缩机制。支持的字符串有

  • "gzip"
  • "zlib"
  • "deflate"
  • "snappy"
  • "zstd"

如果您将 compression 设置为 "none" 或空字符串 "",则请求不会被压缩。

balancer_name 的支持值列在 gRPC 文档的 负载均衡 部分中。

  • pick_first:尝试连接到第一个地址,如果连接成功,则使用它进行所有 RPC,如果失败,则尝试下一个地址(并继续这样做,直到成功连接)。因此,所有 RPC 都将发送到同一后端。
  • round_robin:连接到它看到的所有地址,并按顺序将 RPC 发送到每个后端。例如,第一个 RPC 发送到后端-1,第二个 RPC 发送到后端-2,第三个 RPC 发送到后端-1。

gRPC 中的 :authority 标头指定请求发送到的主机。它与 HTTP 请求中的 Host 标头 类似。默认情况下,:authority 的值是从用于 gRPC 调用的端点 URL 中派生的。当使用像 Envoy 这样的代理路由流量时,覆盖 :authority 可能很有用,因为 Envoy 根据 :authority 标头的值进行路由决策。

您可以使用以下环境变量配置 HTTP 代理

  • HTTPS_PROXY
  • NO_PROXY

HTTPS_PROXY 环境变量指定用于代理请求的 URL。通过 HTTP CONNECT 方法 建立 proxy 连接。

NO_PROXY 环境变量是可选的,包含以逗号分隔的主机名列表,对于这些主机名,HTTPS 代理不应使用。每个主机名可以是 IP 地址(1.2.3.4)、CIDR 表示法中的 IP 地址(1.2.3.4/8)、域名(example.com)或 *。域名匹配该域名及其所有子域名。以点开头的域名(.example.com)仅匹配子域名。当设置 HTTPS_PROXY 时,才会读取 NO_PROXY

由于 otelcol.exporter.loadbalancing 使用 gRPC,因此配置的代理服务器必须能够处理和代理 HTTP/2 流量。

tls 块

tls 块配置用于连接到 gRPC 服务器的 TLS 设置。

以下参数受支持

名称类型描述默认值必需
ca_filestringCA 文件路径。
ca_pemstring用于验证服务器的 CA PEM 编码文本。
cert_filestringTLS 证书路径。
cert_pemstring客户端身份验证的 PEM 编码证书文本。
insecure_skip_verify布尔值忽略不安全的服务器 TLS 证书。
include_system_ca_certs_pool布尔值是否在证书颁发机构旁边加载系统证书颁发机构池。false
insecure布尔值在连接到配置的服务器时禁用 TLS。
key_filestringTLS 证书密钥路径。
key_pemsecret客户端身份验证的 PEM 编码密钥文本。
max_versionstring连接可接受的 TLS 版本的最大值。"TLS 1.3"
min_versionstring连接的最小可接受TLS版本。"TLS 1.2"
cipher_suiteslist(string)TLS传输可使用的TLS加密套件列表。[]
reload_interval持续时间证书重新加载的时间间隔。"0s"
server_namestring当设置时,验证服务器证书的主机名。

如果服务器不支持TLS,您必须将insecure参数设置为true

要禁用与服务器连接的tls,请将insecure参数设置为true

如果reload_interval设置为"0s",则证书永远不会重新加载。

以下参数对互斥,不能同时设置

  • ca_pemca_file
  • cert_pemcert_file
  • key_pemkey_file

如果留空cipher_suites,则使用安全默认列表。有关支持的加密套件列表,请参阅Go TLS文档

keepalive block

配置gRPC客户端连接的keepalive设置。

以下参数受支持

名称类型描述默认值必需
ping_wait持续时间无活动后多久ping服务器。
ping_response_timeout持续时间在服务器未响应ping之前,等待关闭不活跃连接的时间。
ping_without_stream布尔值即使没有活跃的流请求,也要发送ping。

queue block

配置在将数据发送到gRPC服务器之前,数据在内存中的批次缓冲区。

以下参数受支持

名称类型描述默认值必需
enabled布尔值启用在向客户端发送数据之前的数据内存缓冲区。true
num_consumersnumber并行发送写入队列的批次读者的数量。10
queue_sizenumber同一时间允许在队列中的未写批次的最大数量。1000

enabledtrue时,数据首先写入内存缓冲区,然后再发送到配置的服务器。只要未发送批次的数量不超过配置的queue_size,发送到组件的input导出字段的批次就会添加到缓冲区。

queue_size决定了可以容忍的端点故障时间长度。假设每秒100个请求,默认队列大小1000提供大约10秒的故障容忍时间。要计算正确的queue_size值,将每秒平均发出的请求数乘以可容忍故障的时间(秒)。过高的值可能会导致内存不足(OOM)杀掉。

num_consumers参数控制有多少读者从缓冲区读取并发送数据。更大的num_consumers值可以更快地发送数据,但会增加网络流量。

retry block

配置对gRPC服务器的失败请求的重试。

以下参数受支持

名称类型描述默认值必需
enabled布尔值启用重试失败的请求。true
initial_interval持续时间在重试失败请求之前等待的初始时间。"5s"
max_elapsed_time持续时间在丢弃失败批次之前等待的最大时间。"5m"
max_interval持续时间重试之间等待的最大时间。"30s"
multipliernumber增长重试前等待时间的因子。1.5
randomization_factornumber随机化重试前等待时间的因子。0.5

enabledtrue 时,失败的批次将在给定的时间间隔后重试。initial_interval 参数指定在第一次重试尝试之前等待多长时间。如果请求继续失败,则重试之前等待的时间将按照 multiplier 参数指定的因子增加,该因子必须大于 1.0max_interval 参数指定重试之间等待时间的上限。

randomization_factor 参数对于在重试 Alloy 实例之间添加抖动很有用。如果 randomization_factor 大于 0,则重试之前的等待时间将乘以一个在范围 [ I - randomization_factor * I, I + randomization_factor * I] 内的随机因子,其中 I 是当前间隔。

如果一批数据没有成功发送,则在 max_elapsed_time 指定的时间过后就会被丢弃。如果将 max_elapsed_time 设置为 "0s",则失败的请求将无限期重试,直到成功。

debug_metrics 块

debug_metrics 块配置了此组件生成的指标,以监控其状态。

以下参数受支持

名称类型描述默认值必需
disable_high_cardinality_metrics布尔值是否禁用某些高基数指标。true
levelstring控制包装收集器生成的指标的详细程度。"detailed"

disable_high_cardinality_metrics 是 Grafana Alloy 在 OpenTelemetry Collector 中的 telemetry.disableHighCardinalityMetrics 功能开关的等价物。它删除可能导致高基数指标的属性。例如,从关于 HTTP 和 gRPC 连接的指标中删除具有 IP 地址和端口号的属性。

注意

如果配置了 disable_high_cardinality_metrics,则它仅适用于 otelcol.exporter.*otelcol.receiver.* 组件。

level 是 OpenTelemetry Collector 中的 telemetry.metrics.level 功能开关在 Alloy 中的等价物。可能的值有 "none""basic""normal""detailed"

导出字段

以下字段将被导出,并可以被其他组件引用

名称类型描述
inputotelcol.Consumer其他组件可以使用该值发送遥测数据。

input 接受 OTLP 格式的 otelcol.Consumer 数据,用于以下类型的遥测信号

  • logs
  • traces

选择负载均衡策略

不同的 Alloy 组件需要不同的负载均衡策略。使用 otelcol.exporter.loadbalancing 仅对于 有状态的组件 是必要的。

otelcol处理器尾部采样

给定 trace ID 的所有 span 都必须发送到同一个 tail sampling Alloy 实例。

  • 可以通过将 otelcol.exporter.loadbalancing 配置为 routing_key = "traceID" 来实现这一点。
  • 如果您没有配置 routing_key = "traceID",采样决策可能是不正确的。尾部采样器在做出采样决策时必须全面了解跟踪。例如,如果同一跟踪的 span 被分散到多个 Alloy 实例,则 rate_limiting 尾部采样策略可能错误地通过比预期更多的 span。

otlcol.connector.spanmetrics

给定 service.name 的所有 span 必须发送到同一个 spanmetrics Alloy。

  • 可以通过将 otelcol.exporter.loadbalancing 配置为 routing_key = "service" 来实现这一点。
  • 如果您未配置routing_key = "service",从跨度生成的指标可能会不正确。例如,如果相同service.name的类似跨度最终出现在不同的Alloy实例上,两个Alloy将具有计算跨度延迟、错误和请求数量相同的指标系列。当两个Alloy实例都尝试将指标写入数据库(如Mimir)时,系列可能会相互冲突。最好的情况是,这将在Alloy中导致错误并将指标数据库的写入拒绝。最坏的情况是,由于指标系列的样本重叠,可能导致数据不准确。

然而,有一些方法可以扩展otelcol.connector.spanmetrics,而无需负载均衡器

  1. 每个Alloy可以通过添加一个属性(如collector.id)来使其系列独特。例如,您可以使用sum by PromQL查询从不同的Alloys聚合指标。不幸的是,额外的collector.id属性有缺点,即存储在数据库中的指标将具有更高的基数
  2. Spanmetrics可以在后端数据库中生成,而不是在Alloy中。例如,跨度指标可以在Grafana Cloud中通过Tempo跟踪数据库生成

otlcol.connector.servicegraph

在多个Alloy实例上扩展otelcol.connector.servicegraph具有挑战性。为了使otelcol.connector.servicegraph正常工作,每个“客户端”跨度必须与一个“服务器”跨度配对以计算跨度持续时间等指标。如果一个“客户端”跨度到一个Alloy,但一个“服务器”跨度到另一个Alloy,那么没有任何单个Alloy能够配对跨度,并且不会生成指标。

otelcol.exporter.loadbalancing可以通过配置routing_key = "traceID"部分解决这个问题。然后,每个Alloy将能够为每个跟踪中的“客户端”/“服务器”对计算一个服务图。有可能在另一个跟踪中处理具有类似“服务器”/“客户端”值的跨度,由另一个Alloy处理。如果两个不同的Alloy实例处理相似的“服务器”/“客户端”跨度,它们将生成相同的服务图指标系列。如果两个Alloy的系列相同,在将它们写入后端数据库时将出现问题。您可以通过添加属性(如"collector.id")来区分系列。可以通过在后端指标数据库上使用PromQL查询聚合来自不同Alloy的系列。如果指标存储在Grafana Mimir中,可以使用自适应指标解决由于"collector.id"标签引起的基数问题。

在Alloy中生成服务图指标的简单、更可扩展的替代方法是完全在后端数据库中生成。例如,服务图可以在Grafana Cloud中通过Tempo跟踪数据库生成

混合有状态组件

不同的合金组件可能需要不同的 routing_key 来配置 otelcol.exporter.loadbalancing。例如,otelcol.processor.tail_sampling 需要配置 routing_key = "traceID",而 otelcol.connector.spanmetrics 需要配置 routing_key = "service"。为了平衡两种组件的负载,必须设置两组不同的负载均衡器

  • 一组配置了 routing_key = "traceID"otelcol.exporter.loadbalancing,将跨度发送到进行尾部采样而不进行跨度指标计算的合金。
  • 另一组配置了 routing_key = "service"otelcol.exporter.loadbalancing,将跨度发送到进行跨度指标计算而不进行服务图计算的合金。

不幸的是,这也可能导致副作用。例如,如果 otelcol.connector.spanmetrics 被配置为生成示例,则进行尾部采样的合金可能会丢弃示例指向的跟踪。尾部采样合金和跨度指标合金之间没有协调来确保示例的跟踪ID得到保留。

组件健康状态

otelcol.exporter.loadbalancing 只有在给出无效配置时才会报告为不健康。

调试信息

otelcol.exporter.loadbalancing 不公开任何特定组件的调试信息。

示例

静态解析器

本示例接受通过 gRPC 传输的 OTLP 日志和跟踪。然后以负载均衡的方式将它们发送到“localhost:55690”或“localhost:55700”。

alloy
otelcol.receiver.otlp "default" {
    grpc {}
    output {
        traces  = [otelcol.exporter.loadbalancing.default.input]
        logs    = [otelcol.exporter.loadbalancing.default.input]
    }
}

otelcol.exporter.loadbalancing "default" {
    resolver {
        static {
            hostnames = ["localhost:55690", "localhost:55700"]
        }
    }
    protocol {
        otlp {
            client {}
        }
    }
}

DNS 解析器

当配置了 dns 解析器时,otelcol.exporter.loadbalancing 将在常规时间间隔内进行 DNS 查询。跨度将导出为 DNS 查询返回的地址。

alloy
otelcol.exporter.loadbalancing "default" {
    resolver {
        dns {
            hostname = "alloy-traces-sampling.grafana-cloud-monitoring.svc.cluster.local"
            port     = "34621"
            interval = "5s"
            timeout  = "1s"
        }
    }
    protocol {
        otlp {
            client {}
        }
    }
}

以下示例显示了一个 Kubernetes 配置,该配置配置了两组合金

  • 负载均衡合金池
    • 通过 otelcol.receiver.otlp 接收来自已记录应用的跨度。
    • 通过 otelcol.exporter.loadbalancing 导出跨度。
  • 采样合金池
    • 采样合金运行在无头服务后面,以使负载均衡合金能够发现它们。
    • 通过 otelcol.receiver.otlp 接收来自负载均衡合金的跨度。
    • 通过 otelcol.processor.tail_sampling 采样跟踪。
    • 通过 otelcol.exporter.otlp 将跟踪导出到 OTLP 兼容的数据库,如 Tempo。

在运行示例之前,必须填写正确的 OTLP 凭据。您可以使用 k3d 启动示例

bash
k3d cluster create alloy-lb-test
kubectl apply -f kubernetes_config.yaml

要删除集群,请运行

bash
k3d cluster delete alloy-lb-test

Kubernetes 解析器

当您使用 kubernetes 解析器配置 otelcol.exporter.loadbalancing 时,Kubernetes API 会通知合金每当有新的 pod 添加到或从服务中删除时。跨度导出到 Kubernetes API 的地址,结合所有可能的 ports

alloy
otelcol.exporter.loadbalancing "default" {
    resolver {
        kubernetes {
            service = "alloy-traces-headless"
            ports   = [ 34621 ]
        }
    }
    protocol {
        otlp {
            client {}
        }
    }
}

以下示例展示了设置两套合金的Kubernetes配置。

  • 负载均衡合金池
    • 通过 otelcol.receiver.otlp 接收来自已记录应用的跨度。
    • 通过 otelcol.exporter.loadbalancing 导出跨度。
    • 负载均衡合金会在任何向采样合金池中添加或移除Pod时由Kubernetes API通知。
  • 采样合金池
    • 采样合金不需要运行在无头服务后面。
    • 通过 otelcol.receiver.otlp 接收来自负载均衡合金的跨度。
    • 通过 otelcol.processor.tail_sampling 采样跟踪。
    • 通过otelcol.exporter.otlp将跟踪导出到兼容OTLP的数据库,例如Tempo。

在运行示例之前,必须填写正确的 OTLP 凭据。您可以使用 k3d 启动示例

bash
k3d cluster create alloy-lb-test
kubectl apply -f kubernetes_config.yaml

要删除集群,请运行

bash
k3d cluster delete alloy-lb-test

兼容组件

otelcol.exporter.loadbalancing导出可以由以下组件消费

注意

连接某些组件可能没有意义,或者组件可能需要进一步配置才能正确连接。有关更多详细信息,请参阅链接文档。