Envoy性能指标
Categories:
Envoy 指标
Envoy 指标概述
Envoy 的主要目标之一是使网络易于理解。 Envoy 会根据其配置方式产生大量统计信息。一般来说,统计数据(指标)分为三类:
- Downstream:Downstream 指标与外来的连接/请求有关。它们由
listener
、HTTP connection manager(HCM)
、TCP proxy filter
等产生。 - Upstream:Upstream 指标与外向的连接/请求有关。它们由
connection pool
、router filter
、tcp proxy filter
等产生。 - Server:
Server
指标信息描述 Envoy 服务器实例的运作情况。服务器正常运行时间或分配的内存量等统计信息。
在最简单场景下,单个 Envoy Proxy 通常涉及 Downstream
和 Upstream
统计数据。这两种指标反映了取该 网络节点
的运行情况。来自整个网格的统计数据提供了每个 网络节点
和整体网络健康状况的非常详细的汇总信息。Envoy 的文档对这些指标有一些简单的说明。
Tag
Envoy 的指标还有两个子概念,支持在指标中使用: 标签(tags)
/维度(dimensions)
。这里的 tags
对等于 Prometheus 指标的 label。意义上,可以理解为:分类维度。
Envoy 的 指标
由规范的字符串来标识。这些字符串的动态部分(子字符串)被提取成为 标签(tag)
。可以通过指定 tag 提取规则(Tag Specifier configuration.) 来定制 tag 。
举个例子:
### 1. 原始的 Envoy 指标 ###
$ kubectl exec fortio-server -c istio-proxy -- curl 'localhost:15000/stats'
# 返回:
cluster.outbound|8080||fortio-server-l2.mark.svc.cluster.local.external.upstream_rq_2xx: 300
# 其中:
# - `outbound|8080||fortio-server-l2.mark.svc.cluster.local` 部分是 upstream cluster 的名字。可以正则提取作为 tag。
# - `2xx` 部分是 HTTP Status Code 的分类。可以正则提取作为 tag。 下文将有这个提取规则的配置说明。
### 2. 给 Prometheus 的指标 ###
$ kubectl exec fortio-server -c istio-proxy -- curl 'localhost:15000/stats?format=prometheus' | grep 'outbound|8080||fortio-server-l2' | grep 'external.upstream_rq'
# 返回:
envoy_cluster_external_upstream_rq{response_code_class="2xx",cluster_name="outbound|8080||fortio-server-l2.mark.svc.cluster.local"} 300
指标数据类型
Envoy 发出三种类型的值作为统计信息:
- 计数器(Counters):无符号整数,只会增加而不会减少。例如,总请求。
- 仪表(Gauges):增加和减少的无符号整数。例如,当前活动的请求。
- 直方图(Histograms):作为指标流的一部分的无符号整数,然后由收集器聚合以最终产生汇总的百分位值(percentile,即平常说的 P99/P50/Pxx)。例如,
Upsteam
响应时间。
在 Envoy 的内部实现中,Counters 和 Gauges 被分批并定期刷新以提高性能。Histograms 在接收时写入。
指标释义
从指标的产出地点来划分,可以分为:
- cluster manager : 面向
upstream
的 L3/L4/L7 层指标 - http connection manager(HCM) : 面向
upstream
&downstream
的 L7 层指标 - listeners : 面向
downstream
的 L3/L4 层指标 - server(全局)
- watch dog
下面我只选择了部分关键的性能指标来简单说明。
cluster manager
Envoy 文档:cluster manager stats
上面文档已经说得比较详细了。我只补充一些在性能调优时需要关注的方面。那么,一般需要关注什么指标?
我们从著名的 Utilization Saturation and Errors (USE) 方法学来分析。
利用率(Utilization):
upstream_cx_total
(Counter): 连接数upstream_rq_active
饱和度(Saturation):
upstream_rq_time
(Histogram): 响应时间upstream_cx_connect_ms
(Histogram)upstream_cx_rx_bytes_buffered
upstream_cx_tx_bytes_buffered
upstream_rq_pending_total
upstream_rq_pending_active
(Gauge)
错误(Error):
upstream_cx_connect_fail
(Counter): 连接失败数upstream_cx_connect_timeout
(Counter): 连接超时数upstream_cx_overflow
(Counter): 集群连接断路器溢出的总次数upstream_cx_pool_overflow
upstream_cx_destroy_local_with_active_rq
upstream_cx_destroy_remote_with_active_rq
upstream_rq_timeout
upstream_rq_retry
upstream_rq_rx_reset
upstream_rq_tx_reset
其它:
upstream_rq_total
(Counter): TPS (吞吐)upstream_cx_destroy_local
(Counter): Envoy 主动断开的连接计数upstream_cx_destroy_remote
(Counter): Envoy 被动断开的连接计数upstream_cx_length_ms
(Histogram)
http connection manager(HCM)
Envoy 文档:http connection manager(HCM) stats
可以认为,这是面向 downstream
& 部分 upstream
的 L7 层指标
利用率(Utilization):
downstream_cx_total
downstream_cx_active
downstream_cx_http1_active
downstream_rq_total
downstream_rq_http1_total
downstream_rq_active
饱和度(Saturation):
downstream_cx_rx_bytes_buffered
downstream_cx_tx_bytes_buffered
downstream_flow_control_paused_reading_total
downstream_flow_control_resumed_reading_total
错误(Error):
downstream_cx_destroy_local_active_rq
downstream_cx_destroy_remote_active_rq
downstream_rq_rx_reset
downstream_rq_tx_reset
downstream_rq_too_large
downstream_rq_max_duration_reached
downstream_rq_timeout
downstream_rq_overload_close
rs_too_large
其它:
downstream_cx_destroy_remote
downstream_cx_destroy_local
downstream_cx_length_ms
listeners
可以认为,这是 downstream 的 L3/L4 层的指标。
利用率(Utilization):
downstream_cx_total
downstream_cx_active
饱和度(Saturation):
downstream_pre_cx_active
错误(Error):
downstream_cx_transport_socket_connect_timeout
downstream_cx_overflow
no_filter_chain_match
downstream_listener_filter_error
no_certificate
其它:
downstream_cx_length_ms
server
Envoy 基础信息指标
利用率(Utilization):
concurrency
错误(Error):
days_until_first_cert_expiring
watch dog
Envoy 还包括一个可配置的看门狗系统,它可以在 Envoy 没有响应时增加统计数据并选择性地终止服务器。 系统有两个独立的看门狗配置,一个用于主线程,一个用于工作线程; 因为不同的线程有不同的工作负载。 这些统计数据有助于从高层次上理解 Envoy 的事件循环是否因为它正在做太多工作、阻塞或没有被操作系统调度而没有响应。
饱和度(Saturation):
watchdog_mega_miss
(Counter): mega 未命中数watchdog_miss
(Counter): 未命中数
如果你对 watchdog 机制的兴趣,可以参考:
https://github.com/envoyproxy/envoy/issues/11391 https://github.com/envoyproxy/envoy/issues/11388
Event loop
Envoy 架构旨在通过在少量线程上运行事件循环来优化可扩展性和资源利用率。 “main”
线程负责控制面处理,每个 “worker”
线程分担数据面的一部分任务。 Envoy 公开了两个统计信息来监控所有这些线程事件循环的性能。
跑一轮循环的耗时:事件循环的每次迭代都会执行一些任务。任务数量会随着负载的变化而变化。但是,如果一个或多个线程具有异常长尾循环执行耗时,则可能存在性能问题。例如,负责可能在工作线程之间分配不均,或者插件中可能存在长时间阻塞操作阻碍了任务进度。
轮询延迟:在事件循环的每次迭代中,事件调度程序都会轮询 I/O 事件,并在某些 I/O 事件就绪
或 发生 超时
时 “唤醒” 线程,以先发生者为准。在 超时
的情况下,我们可以测量轮询后预期唤醒时间与实际唤醒时间的差值;这种差异称为 “轮询延迟
”。看到一些小的 轮询延迟
是正常的,通常等于内核调度程序的 “时间片(time slice”)” 或 “量子(quantum)” ——这取决于运行 Envoy 的操作系统 —— 但如果这个数字大大高于其正常观察到的基线,它表示内核调度程序可能发生延迟。
可以通过将 enable_dispatcher_stats 设置为 true
来启用这些统计信息。
main
线程的事件调度器有一个以server.dispatcher.
为根的统计树。- 每个
worker
线程的事件调度器都有一个以listener_manager.worker_<id>.dispatcher.
为根的统计树。
每棵树都有以下统计信息:
Name | Type | Description |
---|---|---|
loop_duration_us | Histogram | 以微秒为单位的事件循环持续时间 |
poll_delay_us | Histogram | 以微秒为单位的轮询延迟 |
请注意,此处不包括任何辅助(非 main 与 worker)线程。
Watch Dog 和 Event loop 都是解决与监控事件处理延迟与时效的工具,这里有很多细节和故事,甚至可以说到 Linux Kernel。希望本书后面有时间,可以和大家一起学习和分析这些有趣的细节。
配置说明
本节参考:
[Envoy 文档](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/metrics/v3/stats.proto)
config.bootstrap.v3.Bootstrap
Envoy 文档:config.bootstrap.v3.Bootstrap proto
{
"node": {...},
"static_resources": {...},
"dynamic_resources": {...},
"cluster_manager": {...},
"stats_sinks": [],
"stats_config": {...},
"stats_flush_interval": {...},
"stats_flush_on_admin": ...,
...
}
什么是 `stats sink`? 本书不作说明。Istio 默认没定制相关配置。以下只说关注的部分配置。
stats_config (config.metrics.v3.StatsConfig) 用于内部处理统计信息的配置。
stats_flush_interval (Duration) 刷新
stats sink
的时间间隔。。出于性能原因,Envoy 不会实时刷新 counter ,仅定期刷新 counter 和 gauge 。 如果未指定,则默认值为 5000 毫秒。stats_flush_interval
或stats_flush_on_admin
只能设置之一。 Duration 必须至少为 1 毫秒,最多为 5 分钟。stats_flush_on_admin (bool) 仅当在
管理界面(admin interface)
上查询时才将统计信息刷新到sink
。 如果设置,则不会创建刷新计时器。 只能设置stats_flush_on_admin
或stats_flush_interval
之一。
config.metrics.v3.StatsConfig
Envoy 文档:config-metrics-v3-statsconfig
{
"stats_tags": [],
"use_all_default_tags": {...},
"stats_matcher": {...},
"histogram_bucket_settings": []
}
stats_tags - 维度提取规则(对应 Prometheus 的 label 提取) (多个 config.metrics.v3.TagSpecifier ) 每个
指标名称字符串
都通过这些标签规则独立处理。 当一个标签匹配时,第一个捕获组不会立即从名称中删除,所以后面的 TagSpecifiers 也可以重复匹配同一部分。在完成所有标签匹配后,再剪裁指标名称字符串
的匹配部分,并作为stats sink
的指标名,例如 Prometheus的指标名。use_all_default_tags (BoolValue) 使用 Envoy 中指定的所有默认标签正则表达式。 这些可以与 stats_tags 中指定的自定义标签结合使用。 它们将在自定义标签之前进行处理。Istio 默认为 false.
stats_matcher (config.metrics.v3.StatsMatcher) 指定 Envoy 要产出哪些指标。支持
包含
/排除
规则指定。 如果未提供,则所有指标都将产出。 阻止某些指标集的统计可以提高一点 Envoy 运行性能。
config.metrics.v3.StatsMatcher
Envoy 文档:config-metrics-v3-statsmatcher
用于禁用/开启统计指标计算与产出的配置。
{
"reject_all": ...,
"exclusion_list": {...},
"inclusion_list": {...}
}
reject_all (bool) 如果
reject_all
为 true ,则禁用所有统计信息。 如果reject_all
为 false,则启用所有统计信息。exclusion_list (type.matcher.v3.ListStringMatcher) 排除列表
inclusion_list (type.matcher.v3.ListStringMatcher) 包含列表
本节参考了: https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/observability/statistics
下一节,将以 Istio 如何使用上面的配置为例,举例说明。