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

otelcol.exporter.loadbalancing

otelcol.exporter.loadbalancing 接受来自其他 otelcol 组件的日志和追踪,并使用 OpenTelemetry Protocol (OTLP) 协议通过网络将其写入。

注意

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

可以通过为其指定不同的标签来指定多个 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"
timeoutduration在将请求标记为失败之前,等待 otlp > protocol exporter 的时间。"0s"

routing_key 属性决定了如何在端点之间路由信号。其值可以是以下之一:

  • "service":具有相同 service.name 的跨度、日志和指标将导出到同一个后端。这在使用 span metrics 等处理器时非常有用,这样每个服务的所有跨度都会发送到一致的 Alloy 实例进行指标收集。否则,同一服务的指标将发送到不同的实例,导致聚合不准确。
  • "traceID":属于同一 traceID 的跨度和日志将导出到同一个后端。
  • "resource":属于同一资源的指标将导出到同一个后端。
  • "metric":具有相同名称的指标将导出到同一个后端。
  • "streamID":具有相同 streamID 的指标将导出到同一个后端。

负载均衡器根据 routing_key 支持的信号类型配置 exporter。

timeout 参数类似于 otelcol.exporter.loadbalancing 本身顶层的 queue 和 retry 块。它有助于将数据重新路由到一组新的健康后端。这对于 Kubernetes 等高弹性环境特别有用,因为已解析端点列表会因部署和扩缩容事件而频繁更改。

实验性otelcol.exporter.loadbalancing 中的指标支持是一项实验性功能。实验性功能可能会频繁发生破坏性更改,并且可能会在没有等效替代方案的情况下被移除。必须将 stability.level 标志设置为 experimental 才能使用此功能。

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 exporter。
protocol > otlp > clientclient配置 exporter 的 gRPC 客户端。
protocol > otlp > client > tlstls配置 gRPC 客户端的 TLS。
protocol > otlp > client > keepalivekeepalive配置 gRPC 客户端的 keepalive 设置。
protocol > otlp > queuequeue配置发送前的数据批处理。
protocol > otlp > retryretry配置失败请求的重试机制。
queuequeue配置在发送到 otlp > protocol exporter 之前的数据批处理。
retryretry配置对 otlp > protocol exporter 失败请求的重试机制。
debug_metricsdebug_metrics配置此组件生成的用于监控其状态的指标。

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

有两种类型的queueretry块:

  • protocol > otlp 下的 queue 和 retry 块。这对于特定后端的临时问题(例如瞬态网络问题)非常有用。
  • otelcol.exporter.loadbalancing 的顶层 queue 和 retry 块。这些配置选项提供了将数据重新路由到一组新的健康后端的的能力。这对于 Kubernetes 等高弹性环境特别有用,因为已解析端点列表会因部署和扩缩容事件而频繁更改。

resolver 块

resolver 块配置了如何检索此 exporter 将发送数据到的端点。

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

static 块

static 块配置了此 exporter 将发送数据到的端点列表。

支持以下参数:

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

dns 块

dns 块通过 DNS hostname 属性定期解析 IP 地址。此 IP 地址和通过 port 属性指定的端口将用于 gRPC exporter 作为导出数据到的端点。

支持以下参数:

名称类型描述默认值必需
hostnamestring要解析的 DNS 主机名。
intervalduration解析器间隔。"5s"
timeoutduration解析器超时。"1s"
portstring与从 DNS 主机名解析出的 IP 地址一起使用的端口。"4317"

kubernetes 块

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

支持以下参数:

名称类型描述默认值必需
servicestring要解析的 Kubernetes 服务。
portslist(number)与从 service 解析出的 IP 地址一起使用的端口。[4317]
timeoutduration解析器超时。"1s"
return_hostnamesbool返回主机名而不是 IP。false

如果在 service 中未指定命名空间,将尝试推断此 Alloy 的命名空间。如果失败,将使用 default 命名空间。

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

必须在 Kubernetes 中授予“get”、“list”和“watch”角色才能使解析器正常工作。

在某些情况下,例如在 Sidecar 模式下使用 Istio 时,return_hostnames 非常有用。要使用此功能,service 参数必须是无头 Service,指向 StatefulSet。此外,service 参数必须与 StatefulSet.spec.serviceName 下指定的名称相同。

aws_cloud_map 块

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

支持以下参数:

名称类型描述默认值必需
namespacestring服务注册所在的 CloudMap 命名空间。
service_namestring注册实例时指定的服务名称。
intervalduration解析器间隔。"30s"
timeoutduration解析器超时。"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 客户端。client 块使用的端点来自 resolver 块:

支持以下参数:

名称类型描述默认值必需
compressionstring用于请求的压缩机制。"gzip"
read_buffer_sizestringgRPC 客户端用于读取服务器响应的读取缓冲区大小。
write_buffer_sizestringgRPC 客户端用于写入请求的写入缓冲区大小。"512KiB"
wait_for_readyboolean在发送数据之前等待 gRPC 连接处于 READY 状态。false
headersmap(string)随请求发送的附加头部。{}
balancer_namestring用于请求的 gRPC 客户端负载均衡器。round_robin
authoritystring覆盖 gRPC 客户端发送的 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 方法建立到代理的连接。

NO_PROXY 环境变量是一个可选的逗号分隔的主机名列表,对于这些主机名不应使用 HTTPS 代理。每个主机名可以提供为 IP 地址(1.2.3.4)、CIDR 表示法的 IP 地址(1.2.3.4/8)、域名(example.com)或 *。域名匹配该域名及其所有子域名。带前导“.”(.example.com)的域名仅匹配子域名。NO_PROXY 仅在设置了 HTTPS_PROXY 时读取。

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

tls 块

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

支持以下参数:

名称类型描述默认值必需
ca_filestringCA 文件的路径。
ca_pemstring用于验证服务器的 CA PEM 编码文本。
cert_filestringTLS 证书的路径。
cert_pemstring用于客户端身份验证的证书 PEM 编码文本。
insecure_skip_verifyboolean忽略不安全的服务器 TLS 证书。
include_system_ca_certs_poolboolean是否在证书颁发机构旁边加载系统证书颁发机构池。false
insecureboolean连接到配置的服务器时禁用 TLS。
key_filestringTLS 证书密钥的路径。
key_pemsecret用于客户端身份验证的密钥 PEM 编码文本。
max_versionstring连接允许的最大 TLS 版本。"TLS 1.3"
min_versionstring连接允许的最小 TLS 版本。"TLS 1.2"
cipher_suiteslist(string)TLS 传输可使用的 TLS 密码套件列表。[]
reload_intervalduration证书重新加载的间隔时间。"0s"
server_namestring设置后验证服务器证书的主机名。
curve_preferenceslist(string)握手中使用的椭圆曲线集。[]

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

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

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

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

  • ca_pemca_file
  • cert_pemcert_file
  • key_pemkey_file

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

curve_preferences 参数决定了在握手过程中优先使用的椭圆曲线集,按照偏好顺序。如果未提供,则使用默认列表。可用的椭圆曲线集包括 X25519P521P256P384

keepalive 块

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

支持以下参数:

名称类型描述默认值必需
ping_waitduration在没有活动后多久 ping 服务器一次。
ping_response_timeoutduration如果服务器未响应 ping,在关闭非活动连接之前等待的时间。
ping_without_streamboolean即使没有活动的流请求也发送 ping。

queue 块

queue 块配置了在数据发送到 gRPC 服务器之前的一个内存批处理缓冲区。

支持以下参数:

名称类型描述默认值必需
enabledboolean在将数据发送到客户端之前启用内存缓冲区。true
num_consumersnumber并行发送写入队列的批次的读取器数量。10
queue_sizenumber队列中同时允许的最大未写入批次数量。1000
blockingboolean如果为 true,则阻塞直到队列有空间容纳新请求。false

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

queue_size 决定了可以容忍端点中断多久。假设每秒 100 个请求,默认队列大小 1000 提供了大约 10 秒的中断容忍时间。要计算 queue_size 的正确值,请将每秒平均传出请求数乘以可以容忍中断的秒数。值过高可能导致内存不足 (OOM) 终止。

num_consumers 参数控制有多少读取器从缓冲区读取数据并并行发送数据。num_consumers 值越大,数据发送速度越快,但会增加网络流量。

retry 块

retry 块配置了如何重试向 gRPC 服务器失败的请求。

支持以下参数:

名称类型描述默认值必需
enabledboolean启用重试失败的请求。true
initial_intervalduration在重试失败请求之前的初始等待时间。"5s"
max_elapsed_timeduration在丢弃失败批次之前等待的最长时间。"5m"
max_intervalduration重试之间的最大等待时间。"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_metricsboolean是否禁用某些高基数指标。true

disable_high_cardinality_metrics 是 Grafana Alloy 中相当于 OpenTelemetry Collector 中 telemetry.disableHighCardinalityMetrics 特性开关的功能。它移除了可能导致高基数指标的属性。例如,关于 HTTP 和 gRPC 连接的指标中包含 IP 地址和端口号的属性会被移除。

注意

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

导出字段

以下字段已导出,可被其他组件引用:

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

input 接受这些类型的遥测信号的 otelcol.Consumer OTLP 格式数据:

  • 日志
  • 追踪

选择负载均衡策略

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

otelcol.processor.tail_sampling

特定追踪 ID 的所有跨度必须发送到同一个尾部采样 Alloy 实例。

  • 这可以通过将 otelcol.exporter.loadbalancing 配置为 routing_key = "traceID" 来实现。
  • 如果不配置 routing_key = "traceID",采样决策可能不正确。尾部采样器在做出采样决策时必须具有完整追踪视图。例如,如果同一追踪的跨度分布在多个 Alloy 实例上,rate_limiting 尾部采样策略可能会错误地通过比预期更多的跨度。

otelcol.connector.spanmetrics

特定 service.name 的所有跨度必须发送到同一个 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 查询来聚合来自不同 Alloy 的指标。不幸的是,额外的 collector.id 属性有一个缺点,即存储在数据库中的指标将具有更高的基数
  2. Span metrics 可以在后端数据库中生成,而不是在 Alloy 中生成。例如,Span metrics 可以由 Grafana Cloud 中的 Tempo 追踪数据库生成

otelcol.connector.servicegraph

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

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

在后端数据库中完全生成服务图指标是比在 Alloy 中生成它们更简单、更具可扩展性的替代方案。例如,服务图可以由 Grafana Cloud 中的 Tempo 追踪数据库生成

混合有状态组件

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

  • 一组 otelcol.exporter.loadbalancing,其 routing_key = "traceID",将跨度发送到执行尾部采样且不生成 span metrics 的 Alloy。
  • 另一组 otelcol.exporter.loadbalancing,其 routing_key = "service",将跨度发送到生成 span metrics 且不生成服务图的 Alloy。

不幸的是,这也会导致副作用。例如,如果将 otelcol.connector.spanmetrics 配置为生成 exemplar,则尾部采样 Alloy 可能会丢弃 exemplar 指向的追踪。尾部采样 Alloy 和 span metrics Alloy 之间没有协调,以确保保留 exemplar 的追踪 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 {}
        }
    }
}

以下示例显示了一个配置了两组 Alloy 的 Kubernetes 配置:

  • 负载均衡器 Alloy 池
    • 通过 otelcol.receiver.otlp 从插桩的应用接收跨度。
    • 通过 otelcol.exporter.loadbalancing 导出跨度。
  • 采样 Alloy 池
    • 采样 Alloy 在无头服务后面运行,以便负载均衡器 Alloy 可以发现它们。
    • 通过 otelcol.receiver.otlp 从负载均衡器 Alloy 接收跨度。
    • 通过 otelcol.processor.tail_sampling 对追踪进行采样。
    • 通过 otelcol.exporter.otlp 将追踪导出到 Tempo 等兼容 OTLP 的数据库。

在运行示例之前,必须填写正确的 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 时,每当有新 Pod 添加或从服务中移除时,Kubernetes API 都会通知 Alloy。Span 将导出到 Kubernetes API 提供的地址,并结合所有可能的 ports

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

以下示例展示了一个 Kubernetes 配置,它设置了两组 Alloy

  • 负载均衡器 Alloy 池
    • 通过 otelcol.receiver.otlp 从插桩的应用接收跨度。
    • 通过 otelcol.exporter.loadbalancing 导出跨度。
    • Kubernetes API 会在采样 Alloy 池中添加或移除 Pod 时,随时通知负载均衡器 Alloy。
  • 采样 Alloy 池
    • 采样 Alloy 不需要运行在 headless 服务后面。
    • 通过 otelcol.receiver.otlp 从负载均衡器 Alloy 接收跨度。
    • 通过 otelcol.processor.tail_sampling 对追踪进行采样。
    • 通过 otelcol.exporter.otlp 将 traces 导出到与 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 具有可供以下组件使用的 exports

注意

连接某些组件可能不合理,或者组件可能需要进一步配置才能使连接正常工作。有关更多详细信息,请参阅链接的文档。