- 可观测性
- 后端
- 微服务
- 云原生
【免费下载链接】skywalking
APM, Application Performance Monitoring System
Apache SkyWalking 内置实现了 Envoy 的 Metrics Service gRPC 协议接收端,允许将数据面(Data Plane)的 Envoy 代理指标实时上报到 OAP Server,用于服务网格可观测性分析。本篇以仓库中docs/en/setup/envoy/examples/metrics/下的官方示例为核心,完整讲解基于 Docker Compose 一键启动 Envoy + SkyWalking OAP 的指标上报链路,覆盖 Metrics Service v2/v3 两代 gRPC 接口的配置差异、DEBUG 日志验证方法,并结合 OAP 端envoy-metric接收器配置与 MAL 指标规则说明底层工作方式。读完本文,你将掌握如何在本地复现 Envoy 指标上报、如何自定义 Envoy 的stats_sinks与node.metadata,以及如何在不借助 Istio 的情况下完成数据面监控接入。
示例目标:Envoy Stats 直达 SkyWalking OAP
该示例的目标非常明确:通过 Envoy 的Metric Service协议(gRPC 流式上报),把 Envoy 运行时产生的 Envoy Stats 持续推送给 SkyWalking OAP Server。示例同时覆盖了协议的两个版本:
- v2:
envoy.service.metrics.v2.MetricsService,对应 Envoy 1.16 等旧版本; - v3:
envoy.service.metrics.v3.MetricsService,对应 Envoy 1.19 及更新版本。
SkyWalking OAP 侧从 8.3.0 起同时支持这两个版本。在仓库的 OAP 接收器源码中可以看到这一设计:MetricServiceGRPCHandler直接继承MetricsServiceGrpc.MetricsServiceImplBase(gRPC 自动生成的服务基类),而MetricServiceGRPCHandlerV3同样继承 v3 版本的MetricsServiceGrpc.MetricsServiceImplBase,并将streamMetrics调用委托给前者处理,从而以一份核心逻辑同时兼容两代协议。相关实现位于:
- MetricServiceGRPCHandler.java
- MetricServiceGRPCHandlerV3.java
一键运行示例(Docker Compose)
示例的运行环境要求本地安装docker与docker-compose,镜像从 Docker Hub 拉取。仓库在示例目录下提供了 Makefile,封装了启停命令:
up: docker-compose up -d down: docker-compose down .PHONY: up down在 docs/en/setup/envoy/examples/metrics 目录下按以下步骤操作:
$ make up $ docker-compose logs -f skywalking第一条命令以后台模式拉起全部服务;第二条命令持续跟踪skywalking容器的日志。等待片刻,待 SkyWalking 完成初始化、Envoy 开始上报统计指标后,日志中会出现类似如下的 DEBUG 输出(由MetricServiceGRPCHandler打印):
skywalking_1 | 2021-07-23 13:25:30,683 - org.apache.skywalking.oap.server.receiver.envoy.MetricServiceGRPCHandler -19437 [grpcServerPool-1-thread-2] DEBUG [] - Received msg identifier { skywalking_1 | node { skywalking_1 | id: "ingress" skywalking_1 | cluster: "envoy-proxy" skywalking_1 | metadata { skywalking_1 | fields { skywalking_1 | key: "LABELS" skywalking_1 | value { skywalking_1 | struct_value { skywalking_1 | fields { skywalking_1 | key: "app" skywalking_1 | value { skywalking_1 | string_value: "test-app" skywalking_1 | } skywalking_1 | } skywalking_1 | } skywalking_1 | } skywalking_1 | } skywalking_1 | fields { skywalking_1 | key: "NAME" skywalking_1 | value { skywalking_1 | string_value: "service-instance-name" skywalking_1 | } skywalking_1 | } skywalking_1 | fields { skywalking_1 | key: "envoy" skywalking_1 | value { skywalking_1 | string_value: "isawesome" skywalking_1 | } skywalking_1 | } skywalking_1 | fields { skywalking_1 | key: "skywalking" skywalking_1 | value { skywalking_1 | string_value: "iscool" skywalking_1 | } skywalking_1 | } skywalking_1 | } skywalking_1 | locality { skywalking_1 | region: "ap-southeast-1" skywalking_1 | zone: "zone1" skywalking_1 | sub_zone: "subzone1" skywalking_1 | } skywalking_1 | user_agent_name: "envoy" skywalking_1 | user_agent_build_version { skywalking_1 | version { skywalking_1 | major_number: 1 skywalking_1 | minor_number: 19 skywalking_1 | } skywalking_1 | ... skywalking_1 | } skywalking_1 | extensions { ... } skywalking_1 | } skywalking_1 | } skywalking_1 | envoy_metrics { skywalking_1 | name: "cluster.service_google.update_no_rebuild" skywalking_1 | type: COUNTER skywalking_1 | metric { skywalking_1 | counter { skywalking_1 | value: 1.0 skywalking_1 | } skywalking_1 | timestamp_ms: 1627046729718 skywalking_1 | } skywalking_1 | ... skywalking_1 | } skywalking_1 | ...日志结构清晰展示了StreamMetricsMessage的两大部分:
identifier.node:Envoy 节点的身份信息,包括id、cluster、metadata(含LABELS、NAME等自定义元数据)、locality(地域/可用区/子区)以及版本与构建信息。SkyWalking 正是依据这些元数据来识别服务与服务实例,进而构建服务拓扑;envoy_metrics:具体的指标项,每条包含指标name(如cluster.service_google.update_no_rebuild)、指标type(如COUNTER)以及带时间戳的采样值。
实验结束后,在示例目录执行以下命令拆除环境:
$ make down两种协议版本的 Compose 与 Envoy 配置对照
示例目录下有两套相互独立的 Compose 编排文件,分别演示 v2 与 v3 协议:
方案一:Envoy 1.16 + Metrics Service v2
docker-compose.yaml:
version: "3" services: envoy16: image: envoyproxy/envoy-alpine:v1.16.2 command: /usr/local/bin/envoy -c /etc/envoy.yaml --service-cluster envoy-proxy ports: - 10000:10000 depends_on: - skywalking volumes: - ./envoy-v1.16.yaml:/etc/envoy.yaml skywalking: image: apache/skywalking-oap-server:latest volumes: - ./log4j2.xml:/skywalking/config/log4j2.xml expose: - "11800"配套的 envoy-v1.16.yaml 中,v2 协议的关键配置是stats_sinks使用name: envoy.metrics_service与config.grpc_service:
stats_sinks: - name: envoy.metrics_service config: grpc_service: envoy_grpc: cluster_name: service_skywalking同时必须在clusters中声明名为service_skywalking的上游集群,指向 OAP 的 11800 端口,且启用 HTTP/2(gRPC 必需):
clusters: - name: service_skywalking connect_timeout: 5s type: STRICT_DNS http2_protocol_options: {} dns_lookup_family: V4_ONLY lb_policy: ROUND_ROBIN load_assignment: cluster_name: service_skywalking endpoints: - lb_endpoints: - endpoint: address: socket_address: address: skywalking port_value: 11800方案二:Envoy 1.19 + Metrics Service v3
docker-compose-envoy-v3-api.yaml:
version: "3" services: envoy19: image: envoyproxy/envoy-alpine:v1.19-latest command: /usr/local/bin/envoy -c /etc/envoy.yaml --service-cluster envoy-proxy ports: - 10001:10000 depends_on: - skywalking volumes: - ./envoy-v1.19.yaml:/etc/envoy.yaml skywalking: image: apache/skywalking-oap-server:latest volumes: - ./log4j2.xml:/skywalking/config/log4j2.xml expose: - "11800"与 v2 方案的差异点:
- 使用了 Envoy 1.19 镜像,宿主机端口映射为
10001:10000(避开与方案一冲突); - Envoy 配置文件改为 envoy-v1.19.yaml;
stats_sinks使用 v3 命名空间,即envoy.stat_sinks.metrics_service,并通过typed_config显式声明transport_api_version: V3:
stats_sinks: - name: envoy.stat_sinks.metrics_service typed_config: "@type": type.googleapis.com/envoy.config.metrics.v3.MetricsServiceConfig transport_api_version: V3 grpc_service: envoy_grpc: cluster_name: service_skywalkingv3 配置中的service_skywalking集群与 v2 基本一致,但 HTTP/2 协议选项采用了 v3 的扩展写法:
clusters: - name: service_skywalking connect_timeout: 5s type: LOGICAL_DNS typed_extension_protocol_options: envoy.extensions.upstreams.http.v3.HttpProtocolOptions: "@type": type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicit_http_config: http2_protocol_options: {} dns_lookup_family: V4_ONLY lb_policy: ROUND_ROBIN load_assignment: cluster_name: service_skywalking endpoints: - lb_endpoints: - endpoint: address: socket_address: address: skywalking port_value: 11800提示:示例集群配置中带有
# Comment out the following line to test on v6 networks注释,即在纯 IPv6 网络环境下,可注释掉dns_lookup_family: V4_ONLY以允许 IPv6 解析。
两套 Envoy 配置中的流量转发目标service_google均指向www.google.com:443(v1.16 配置使用tls_context.sni,v1.19 配置使用UpstreamTlsContext),用于制造真实流量,从而让 Envoy 产生可观测的集群统计指标。
启用 OAP 侧 DEBUG 日志验证上报
示例中特意覆盖了 OAP 的 log4j2 配置,log4j2.xml 的核心内容如下:
<Configuration status="INFO"> <Appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout charset="UTF-8" pattern="%d - %c -%-4r [%t] %-5p %x - %m%n"/> </Console> </Appenders> <Loggers> <logger name="org.apache.zookeeper" level="INFO"/> <logger name="io.grpc.netty" level="INFO"/> <logger name="org.apache.skywalking.oap.server.receiver.istio.telemetry" level="DEBUG"/> <!-- We make envoy metrics receiver to log at DEBUG level --> <logger name="org.apache.skywalking.oap.server.receiver.envoy" level="DEBUG"/> <Root level="INFO"> <AppenderRef ref="Console"/> </Root> </Loggers> </Configuration>关键点在于将接收器包org.apache.skywalking.oap.server.receiver.envoy的日志级别调整为DEBUG。这样MetricServiceGRPCHandler中打印的Received msg ...原始消息(即 Envoy 上报的StreamMetricsMessage)就会输出到控制台,便于直观确认 Envoy 已成功与 OAP 建立 gRPC 流并持续上报指标。该文件通过 Compose 的 volume 挂载覆盖到容器内/skywalking/config/log4j2.xml。在生产环境并不建议全局开启 DEBUG,这只适合本地验证链路连通性。
OAP 端接收器配置与指标处理原理
envoy-metric 接收器配置段
OAP 的默认配置 application.yml 中,envoy-metric模块负责 Envoy 指标(以及 ALS 访问日志分析)的接收,关键配置如下:
envoy-metric: selector: ${SW_ENVOY_METRIC:default} default: acceptMetricsService: ${SW_ENVOY_METRIC_SERVICE:true} alsHTTPAnalysis: ${SW_ENVOY_METRIC_ALS_HTTP_ANALYSIS:""} alsTCPAnalysis: ${SW_ENVOY_METRIC_ALS_TCP_ANALYSIS:""} k8sServiceNameRule: ${K8S_SERVICE_NAME_RULE:"${pod.metadata.labels.(service.istio.io/canonical-name)}.${pod.metadata.namespace}"} istioServiceNameRule: ${ISTIO_SERVICE_NAME_RULE:"${serviceEntry.metadata.name}.${serviceEntry.metadata.namespace}"}其中acceptMetricsService: true(默认开启)即表示 OAP 在 11800 端口接受 Envoy 通过 Metrics Service 协议上报的指标流;alsHTTPAnalysis与alsTCPAnalysis则用于配置 Envoy ALS(Access Log Service)的 HTTP/TCP 分析规则,属于访问日志维度,与本文的指标上报相互独立。
从 gRPC 流到指标入库
从源码结构看,指标处理链路分为三段:
- 接收:
MetricServiceGRPCHandler.streamMetrics通过 gRPC 双向流接收 Envoy 上报的StreamMetricsMessage(v3 版本由MetricServiceGRPCHandlerV3委托给前者); - 转换:消息中的
envoy_metrics通过ProtoMetricFamily2MetricsAdapter适配为 Prometheus 格式的Metric对象,再交由PrometheusMetricConverter按 MAL 规则进行转换; - 入库:转换结果通过
MeterSystem写入指标系统,供后续查询与告警使用。处理器还会借助 telemetry 模块记录envoy_metric_in_count(收到的 Envoy 指标条数)与envoy_metric_in_latency(处理延迟)两项自监控指标。
MAL 规则示例
转换规则定义在 envoy-metrics-rules/envoy.yaml,以 MAL(Meter Analysis Language)编写,例如:
expSuffix: instance(['app'], ['instance'], Layer.MESH_DP) metricPrefix: envoy metricsRules: - name: heap_memory_used exp: server_memory_heap_size - name: cluster_membership_healthy exp: envoy_cluster_metrics.tagMatch('metrics_name' , '.+membership_healthy').tagMatch('metrics_name' , 'cluster.outbound.+|cluster.inbound.+').tagNotMatch('cluster_name' , '.+kube-system').sum(['app', 'instance' , 'cluster_name']) - name: cluster_up_cx_incr exp: envoy_cluster_metrics.tagMatch('metrics_name' , '.+upstream_cx_total').tagMatch('metrics_name' , 'cluster.outbound.+|cluster.inbound.+').sum(['app', 'instance' , 'cluster_name']).increase('PT1M')可以看出,expSuffix将 Envoy 节点元数据中的app(来自LABELS)映射为服务、instance(来自NAME)映射为服务实例,并归属到Layer.MESH_DP(数据面)层;metricsRules则把原始 Envoy 指标名(如server_memory_heap_size)换算为带envoy前缀的 SkyWalking 指标(如envoy_heap_memory_used),并对集群类指标按cluster_name维度聚合。这也解释了为何示例中要在 Envoy 的node.metadata里填写LABELS.app与NAME:它们决定了服务与服务实例在 SkyWalking 中的最终命名。
不借助 Istio 的独立 Envoy 接入要点
与示例同目录的配置指南 metrics_service_setting.md 对独立 Envoy(无 Istio)场景做了更完整的说明。核心思路与示例一致:让 Envoy 的stats_sinks指向envoy.metrics_service,并配置为config.grpc_service(gRPC 服务地址条目)。该文档还特别说明:grpc_service既可以使用envoy_grpc实现(通过 Envoy 内置集群转发),也可以使用google_grpc实现。其给出的精简配置骨架与示例中的service_skywalking集群定义一一对应,端口11800即 SkyWalking 对外提供 Envoy Metrics Service gRPC 流的端口。
为支撑服务拓扑分析,需要让 Envoy 在node.metadata中携带服务元数据:
node: # ... other configs metadata: LABELS: app: test-app NAME: service-instance-name此外,Envoy 的配置不仅可以通过静态文件下发,也可以通过 xDS 协议动态下发。当 Envoy 运行在 Istio 网格中时,Istio 会自动完成上述stats_sinks与元数据的注入,仅需在安装或更新 Istio 时设置meshConfig.defaultConfig.envoyMetricsService.address=<skywalking.address.port.11800>即可将指标导向 SkyWalking;同时可通过proxyStatsMatcher(Istio 1.8+ 支持)的inclusionRegexps白名单正则来精筛需要上报的指标,例如.*membership_healthy.*、.*upstream_cx_total.*、.*lb_healthy_panic.*等 OAP 实际分析所用的指标,从而降低 Envoy 内存占用与 CPU 开销。
指标数据形态参考
为帮助理解上报数据的结构,仓库提供了两份样例数据:
identify.json:包含节点标识(
identifier.node)的完整样例,展示了id: "ingress"、cluster: "envoy-proxy"、metadata以及locality的 JSON 形态;metrics.json:纯指标样例,覆盖三种 Prometheus 指标类型:
- COUNTER:如
cluster.service_stats.upstream_cx_total、cluster.service_google.update_attempt,携带递增计数值; - GAUGE:如
cluster.service_stats.membership_healthy、server.memory_heap_size、server.uptime,表示当前瞬时状态; - SUMMARY:如
cluster.service_stats.upstream_cx_connect_ms,携带多个分位点(quantile 0.25 至 0.999)的分布信息。
- COUNTER:如
每条指标均带timestampMs时间戳。指标命名遵循 Envoy 的层级规范,例如cluster.<名称>.upstream_cx_total表示某个上游集群的连接总数,listener_manager.total_listeners_active表示活跃监听器数量,server.memory_heap_size表示堆内存大小,等等。
常见问题与注意事项
- 看不到日志输出:先确认
make up是否已成功,且 OAP 已启动完成;再确认 Envoy 容器是否生成了流量(示例中需访问localhost:10000/localhost:10001触发转发到www.google.com)。若 OAP 日志仍无 DEBUG 输出,检查 log4j2.xml 是否被正确挂载到容器内/skywalking/config/log4j2.xml,以及org.apache.skywalking.oap.server.receiver.envoy的级别是否为DEBUG。 - 端口与协议匹配:Envoy 的 Metrics Service 走 gRPC,因此
service_skywalking集群必须启用 HTTP/2;v1.16 配置使用http2_protocol_options: {},v1.19 配置使用 v3 扩展的explicit_http_config.http2_protocol_options,二者不可混用。同时确认 OAP 侧acceptMetricsService未关闭(默认true)。 - 协议版本对应:使用 Envoy 1.16 时对应 Metrics Service v2 配置(
envoy.metrics_service+config),使用 Envoy 1.19 时对应 v3 配置(envoy.stat_sinks.metrics_service+typed_config+transport_api_version: V3),请按镜像版本选择对应的stats_sinks写法。 - 服务命名:SkyWalking 中服务名取自
node.metadata.LABELS.app,服务实例名取自node.metadata.NAME;若未配置这些元数据,将无法在拓扑与实例维度上正确归并指标。 - 网络环境:默认
dns_lookup_family: V4_ONLY面向 IPv4 环境;如需在 IPv6 网络测试,可注释掉该行。
小结
本文围绕官方示例完整还原了"Envoy 上报指标 → OAP 接收 → 指标转换入库"的全链路:通过 Makefile 一键启停、两套 Compose 与 Envoy 配置分别演示 Metrics Service v2/v3 协议、借助 log4j2.xml 的 DEBUG 级别验证 gRPC 消息内容,并延伸讲解了 OAP 端 application.yml 的envoy-metric配置与 envoy.yaml MAL 规则如何将原始 Envoy 指标转换为 SkyWalking 指标。无论你的 Envoy 运行在独立模式还是 Istio 网格内,都可以基于本示例快速打通数据面指标到 SkyWalking 的监控通道。
- 可观测性
- 后端
- 微服务
- 云原生
【免费下载链接】skywalking
APM, Application Performance Monitoring System
相关推荐
使用 Docker Compose 示例将 Envoy 指标发送到 SkyWalking OAP 服务器
使用 Docker Compose 示例将 Envoy 指标发送到 SkyWalking OAP 服务器 本篇技术指南讲解如何基于 Apache SkyWalk
可观测性APM链路追踪指标监控日志分析微服务Apache SkyWalking OAP 外部通信通道配置指南:receiver-sharing-server 独立 gRPC/HTTP 服务详解
Apache SkyWalking OAP 外部通信通道配置指南:receiver sharing server 独立 gRPC/HTTP 服务详解 导读 Sk
可观测性后端微服务云原生Apache APISIX skywalking-logger 插件实战:将网关访问日志无缝推送至 SkyWalking OAP
Apache APISIX skywalking logger 插件实战:将网关访问日志无缝推送至 SkyWalking OAP skywalking logg
后端微服务云原生
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考