Apache SkyWalking 接入指南:将 Envoy Metrics 通过 gRPC 发送到 OAP Server 完整示例
2026/9/20 23:36:54 网站建设 项目流程
  • 可观测性
  • 后端
  • 微服务
  • 云原生

【免费下载链接】skywalking

APM, Application Performance Monitoring System

项目地址:https://gitcode.com/gh_mirrors/sky/skywalking
点击查看免费下载

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_sinksnode.metadata,以及如何在不借助 Istio 的情况下完成数据面监控接入。

示例目标:Envoy Stats 直达 SkyWalking OAP

该示例的目标非常明确:通过 Envoy 的Metric Service协议(gRPC 流式上报),把 Envoy 运行时产生的 Envoy Stats 持续推送给 SkyWalking OAP Server。示例同时覆盖了协议的两个版本:

  • v2envoy.service.metrics.v2.MetricsService,对应 Envoy 1.16 等旧版本;
  • v3envoy.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)

示例的运行环境要求本地安装dockerdocker-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 节点的身份信息,包括idclustermetadata(含LABELSNAME等自定义元数据)、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_serviceconfig.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_skywalking

v3 配置中的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 协议上报的指标流;alsHTTPAnalysisalsTCPAnalysis则用于配置 Envoy ALS(Access Log Service)的 HTTP/TCP 分析规则,属于访问日志维度,与本文的指标上报相互独立。

从 gRPC 流到指标入库

从源码结构看,指标处理链路分为三段:

  1. 接收MetricServiceGRPCHandler.streamMetrics通过 gRPC 双向流接收 Envoy 上报的StreamMetricsMessage(v3 版本由MetricServiceGRPCHandlerV3委托给前者);
  2. 转换:消息中的envoy_metrics通过ProtoMetricFamily2MetricsAdapter适配为 Prometheus 格式的Metric对象,再交由PrometheusMetricConverter按 MAL 规则进行转换;
  3. 入库:转换结果通过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.appNAME:它们决定了服务与服务实例在 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_totalcluster.service_google.update_attempt,携带递增计数值;
    • GAUGE:如cluster.service_stats.membership_healthyserver.memory_heap_sizeserver.uptime,表示当前瞬时状态;
    • SUMMARY:如cluster.service_stats.upstream_cx_connect_ms,携带多个分位点(quantile 0.25 至 0.999)的分布信息。

每条指标均带timestampMs时间戳。指标命名遵循 Envoy 的层级规范,例如cluster.<名称>.upstream_cx_total表示某个上游集群的连接总数,listener_manager.total_listeners_active表示活跃监听器数量,server.memory_heap_size表示堆内存大小,等等。

常见问题与注意事项

  1. 看不到日志输出:先确认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
  2. 端口与协议匹配: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)。
  3. 协议版本对应:使用 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写法。
  4. 服务命名:SkyWalking 中服务名取自node.metadata.LABELS.app,服务实例名取自node.metadata.NAME;若未配置这些元数据,将无法在拓扑与实例维度上正确归并指标。
  5. 网络环境:默认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

项目地址:https://gitcode.com/gh_mirrors/sky/skywalking
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询