ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

gRPC-Go CSM Observability 实战:为 Proxyless gRPC 应用一键接入 Cloud Service Mesh 遥测

gRPC-Go CSM Observability 实战:为 Proxyless gRPC 应用一键接入 Cloud Service Mesh 遥测 gRPC-Go CSM Observability 实战为 Proxyless gRPC 应用一键接入 Cloud Service Mesh 遥测【免费下载链接】grpc-goThe Go language implementation of gRPC. HTTP/2 based RPC项目地址: https://gitcode.com/GitHub_Trending/gr/grpc-go导读本篇文章基于 grpc-go 仓库中的官方示例 examples/features/csm_observability深入讲解如何在 gRPC-Go 客户端与服务器二进制程序中每个进程只需配置一次启用 CSM ObservabilityCloud Service Mesh 可观测性并通过 OpenTelemetry Prometheus 暴露指标、通过元数据交换Metadata Exchange机制为遥测数据附加 CSM Labels。读完本文你将掌握csm.EnableObservability的完整用法、CSM 通道判定规则、CSM Labels 的生成逻辑以及本地联调与容器化构建的完整步骤。一、CSM Observability 是什么CSMCloud Service MeshObservability 是面向 Proxyless gRPC 应用的托管可观测性能力无需在 Pod 中注入 Envoy sidecargRPC-Go 应用本身通过 xDS 协议与控制平面通信就能把 RPC 级遥测数据指标发送到托管监控后端。在 grpc-go 仓库中这一能力由两个模块提供stats/opentelemetry通用的 gRPC-Go OpenTelemetry 插桩组件提供 DialOption 与 ServerOptionstats/opentelemetry/csmCSM 专属扩展包注释明确说明其用途是 utilities for Google Cloud Service Mesh observability见 pluginoption.go负责从环境与元数据交换中收集 CSM Labels 并注入到指标中。示例代码位于 examples/features/csm_observability由一个 helloworld 风格的 Greeter 客户端与服务器组成。客户端默认连接目标为xds:///helloworld:50051——也就是说客户端从 xDS 控制平面获取服务器地址这正是 Proxyless Service Mesh 的标准接入方式本地调试时可用--server_addr覆盖该地址。二、整体运行流程整个示例的运行链路如下客户端与服务器各自调用csm.EnableObservability(ctx, options)在进程内全局注册 OpenTelemetry 插桩客户端通过grpc.NewClient(xds:///helloworld:50051, ...)建立 gRPC 通道由 xDS 解析器与均衡器决定实际端点客户端与服务器基于 TLSxDS 凭证通信并在 HTTP/2 头中携带x-envoy-peer-metadata元数据交换标签每次 RPC 触发指标记录指标上自动附加 CSM Labels本地 远端双方各自在:9464端口通过 Prometheus HTTP exporter 暴露指标可用curl localhost:9464/metrics查看。三、核心 APIcsm.EnableObservability启用 CSM Observability 只需要一行代码cleanup : csm.EnableObservability(context.Background(), opentelemetry.Options{ MetricsOptions: opentelemetry.MetricsOptions{ MeterProvider: provider, }, }) defer cleanup()其实现位于 stats/opentelemetry/csm/observability.go关键点如下以newPluginOption(ctx)构造 CSM Plugin Option读取环境变量与 OpenTelemetry 资源探测器得到本地标签与元数据交换标签通过internal.AddGlobalPerTargetDialOptions注册按目标生效的 DialOption只有 xDS 通道才注入 CSM 插件普通通道仍走标准 OpenTelemetry 插桩见下文CSM 通道判定通过internal.AddGlobalServerOptions注册全局 ServerOption因此该进程内所有 gRPC 服务器都会启用 CSM 插桩返回的 cleanup 函数在main中defer调用用于清除全局选项。函数的文档注释强调了两条重要约束见 observability.go该函数不是线程安全的必须在创建任何 Channel 或 Server 之前、在main中只调用一次Context 超时不会报错而是将相关标签置为unknown。四、客户端与服务器完整代码拆解4.1 服务器端server/main.go服务器代码位于 examples/features/csm_observability/server/main.go核心步骤exporter, err : prometheus.New() // 创建 Prometheus exporter provider : metric.NewMeterProvider(metric.WithReader(exporter)) go http.ListenAndServe(*prometheusEndpoint, promhttp.Handler()) // :9464 暴露指标 cleanup : csm.EnableObservability(context.Background(), opentelemetry.Options{ MetricsOptions: opentelemetry.MetricsOptions{MeterProvider: provider}, }) defer cleanup() creds, err : xdscreds.NewServerCredentials(xdscreds.ServerOptions{ FallbackCreds: insecure.NewCredentials(), }) s, err : xds.NewGRPCServer(grpc.Creds(creds)) // xDS gRPC Server pb.RegisterGreeterServer(s, server{addr: : *port}) s.Serve(lis)要点说明MeterProvider 是必须的在 opentelemetry.go 的MetricsOptions注释中明确说明只有设置了MeterProvider才会记录指标未设置则完全静默xDS 服务器使用xds.NewGRPCServer创建支持 xDS 的服务器需要导入google.golang.org/grpc/xds以便在 Cloud Service Mesh 环境中被控制平面管理凭证回退NewServerCredentials使用 xDS 凭证本地无安全策略时回退到 insecure方便单机联调。服务器端命令行参数参数默认值说明--port50051服务器监听端口--prometheus_endpoint:9464Prometheus 指标暴露地址4.2 客户端client/main.go客户端代码位于 examples/features/csm_observability/client/main.go核心步骤exporter, err : prometheus.New() provider : metric.NewMeterProvider(metric.WithReader(exporter)) go http.ListenAndServe(*prometheusEndpoint, promhttp.Handler()) cleanup : csm.EnableObservability(context.Background(), opentelemetry.Options{ MetricsOptions: opentelemetry.MetricsOptions{MeterProvider: provider}, }) defer cleanup() creds, err : xdscreds.NewClientCredentials(xdscreds.ClientOptions{ FallbackCreds: insecure.NewCredentials(), }) cc, err : grpc.NewClient(*target, grpc.WithTransportCredentials(creds)) c : pb.NewGreeterClient(cc)客户端通过_ google.golang.org/grpc/xds导入 xDS 解析器与均衡器这是xds:///scheme 生效的前提见 main.go。随后进入 RPC 循环每隔 1 秒调用一次SayHello每次调用带 5 秒超时上下文以此持续产生遥测数据for { ctx, cancel : context.WithTimeout(context.Background(), time.Second*5) r, err : c.SayHello(ctx, pb.HelloRequest{Name: *name}) if err ! nil { log.Fatalf(Could not greet: %v, err) } fmt.Println(r) time.Sleep(time.Second) cancel() }客户端命令行参数参数默认值说明--targetxds:///helloworld:50051服务器地址默认走 xDS可覆盖为直连地址--prometheus_endpoint:9464Prometheus 指标暴露地址--nameworld发送给 SayHello 的名称五、CSM 通道判定哪些通道会注入 CSM 插件客户端侧并非所有 gRPC 通道都启用 CSM 元数据交换判定逻辑位于 pluginoption.go 的determineTargetCSMreturn parsedTarget.Scheme xds (parsedTarget.Host || parsedTarget.Host traffic-director-global.xds.googleapis.com)即同时满足以下两个条件才视为 CSM 通道目标 URL 的 scheme 为xds未显式指定 authority或 authority 为traffic-director-global.xds.googleapis.com。对应地EnableObservability内部注册的perTargetDialOption会根据DialOptionForTarget的判定结果选择带 CSM 插件的 DialOption还是普通 OpenTelemetry DialOption见 observability.go。因此示例中默认的xds:///helloworld:50051无 authority天然会被识别为 CSM 通道。六、CSM Labels 与元数据交换机制CSM Observability 的增量价值在于为指标附加 CSM Labels。这些标签来自两个方向本地标签local labels与远端标签remote labels后者通过x-envoy-peer-metadata头在客户端与服务器之间交换。6.1 元数据交换Metadata ExchangepluginOption结构体见 pluginoption.go持有两份数据localLabels标识本进程运行环境的标签metadataExchangeLabelsEncoded以 proto wire format 序列化后再 base64RawStdEncoding编码的元数据交换标签。GetMetadata将后者作为x-envoy-peer-metadata的值放入metadata.MD随 RPC 发送GetLabels则解析对端发来的同名头部还原出远端标签见 pluginoption.go。解析时对缺失字段一律回退为unknown。6.2 CSM Labels 的完整清单结合 pluginoption.go 与单元测试 observability_test.goCSM 指标上可出现的标签如下本地标签始终附加标签来源csm.workload_canonical_service环境变量CSM_CANONICAL_SERVICE_NAME未设置则为unknowncsm.mesh_id环境变量CSM_MESH_ID远端标签来自对端元数据交换标签适用对端类型csm.remote_workload_type全部未知则为unknowncsm.remote_workload_canonical_service全部即使 type 未知也会读取csm.remote_workload_project_idGKE / GCEcsm.remote_workload_locationGKE / GCEcsm.remote_workload_nameGKE / GCEcsm.remote_workload_cluster_name仅 GKEcsm.remote_workload_namespace_name仅 GKExDS 附加标签由EnableObservability自动加入在 observability.go 中dialOptionWithCSMPluginOption会把MetricsOptions.OptionalLabels设置为[csm.service_name, csm.service_namespace_name]确保这两个来自 xDS 的可选标签不会被过滤掉。6.3 环境变量与资源探测器本地/元数据交换标签由constructMetadataFromEnv见 pluginoption.go构建来源分两类环境变量CSM_CANONICAL_SERVICE_NAME、CSM_MESH_ID、CSM_WORKLOAD_NAME未设置一律视为unknown见getEnvOpenTelemetry 资源探测器通过resource.New(ctx, resource.WithFromEnv(), resource.WithDetectors(gcp.NewDetector()))获取云环境属性映射关系如下测试用例在 observability_test.go 中给出了完整验证资源属性用途cloud.platform判断 workload typegcp_kubernetes_engine/gcp_compute_enginecloud.availability_zone缺失则取cloud.region生成location标签cloud.account.id生成project_id标签k8s.namespace.name生成namespace_name标签GKEk8s.cluster.name生成cluster_name标签GKE如果cloud.platform不是 GKE/GCE则元数据交换只包含type与canonical_service两个字段标签也随之减少。6.4 指标与标签的关系EnableObservability注册的 CSM 插件会把上述 CSM Labels 附加到 OpenTelemetry 指标上。默认采集的指标定义在 opentelemetry.go由DefaultMetrics()返回包括客户端grpc.client.attempt.startedCounter、grpc.client.attempt.durationHistogram、grpc.client.attempt.sent_total_compressed_message_size/grpc.client.attempt.rcvd_total_compressed_message_sizeHistogram、grpc.client.call.durationHistogram服务器grpc.server.call.startedCounter、grpc.server.call.sent_total_compressed_message_size/grpc.server.call.rcvd_total_compressed_message_sizeHistogram、grpc.server.call.durationHistogram。对应实现结构体见 opentelemetry.go 的clientMetrics与serverMetrics。七、本地联调步骤7.1 前提与限制README 明确提醒该示例默认无法直接运行——客户端使用xdsscheme需要 xDS 资源才能解析服务器地址。两种可行的本地运行方式部署到 Cloud Service Mesh 中客户端从控制平面获取服务端点用--server_addr实际为--target覆盖目标为直连地址:server serving port。7.2 启动服务器在 grpc-go 仓库根目录下示例使用replace指令将google.golang.org/grpc指向本地仓库见 examples/go.modgo run examples/features/csm_observability/server/main.go默认监听0.0.0.0:50051。7.3 启动客户端本地直连调试时用--target覆盖默认的 xDS 地址go run examples/features/csm_observability/client/main.go --targetlocalhost:50051客户端将每隔 1 秒发起一次SayHello调用并打印回复。7.4 查看指标客户端与服务器都会在:9464端口暴露 Prometheus 指标用 curl 即可查看curl localhost:9464/metrics输出中应能看到grpc_client_attempt_started_total、grpc_client_attempt_duration_*、grpc_server_call_started_total等指标以及随环境注入的csm_workload_canonical_service、csm_mesh_id等 CSM Labels。八、容器化构建与部署8.1 构建镜像README 提供了基于仓库根目录的 docker build 命令Dockerfile 注释也给出了相同说明见 client/Dockerfile客户端docker build -t TAG -f examples/features/csm_observability/client/Dockerfile .服务器docker build -t TAG -f examples/features/csm_observability/server/Dockerfile .8.2 Dockerfile 要点两个 Dockerfile 采用多阶段构建见 client/Dockerfile构建阶段基于golang:1.25-alpine将整个 grpc-go 仓库复制到镜像中然后在示例目录下执行go build -tags osusergo,netgo .编译纯静态二进制不带 cgo这样最终镜像无需携带 Go 工具链与依赖运行阶段基于精简的alpine仅复制编译产物与curl镜像内设置了GRPC_GO_LOG_VERBOSITY_LEVEL99与GRPC_GO_LOG_SEVERITY_LEVELinfo用于输出详尽的 gRPC 内部日志方便在网格环境中排查问题最终以ENTRYPOINT [./client]/ENTRYPOINT [./server]启动。8.3 部署要求构建好的客户端与服务器容器需要部署在 Cloud Service Mesh 环境中才能完整工作客户端通过 xDS 协议从控制平面拉取路由与端点配置服务器则以 xDS gRPC Server 形式被网格纳管。本地环境要么覆盖目标地址直连要么无法完成 xDS 解析。九、常见问题与排查建议本地直接运行报无法解析目标确认客户端是否传入了--targetlocalhost:50051xDS 通道在无控制平面时无法解析xds:///目标。指标页面无数据检查是否在main最早期创建 Channel/Server 之前调用了csm.EnableObservability且MeterProvider非空指标依赖真实的 RPC 流量触发。CSM Labels 大量为unknown说明CSM_MESH_ID、CSM_CANONICAL_SERVICE_NAME、CSM_WORKLOAD_NAME等环境变量未设置或资源探测器未能识别 GCP 环境在 GKE/GCE 之外的环境运行时远端标签本就只包含 workload type 与 canonical service。本地同时跑多个示例端口冲突:9464是默认的 Prometheus 暴露端口可通过--prometheus_endpoint改为其他端口。十、关联源码导航示例主文档examples/features/csm_observability/README.md客户端实现examples/features/csm_observability/client/main.go服务器实现examples/features/csm_observability/server/main.go启用入口与全局注册stats/opentelemetry/csm/observability.goCSM 插件与标签构建stats/opentelemetry/csm/pluginoption.goCSM 标签行为测试stats/opentelemetry/csm/observability_test.goOpenTelemetry 选项与指标定义stats/opentelemetry/opentelemetry.go示例模块依赖与 replace 配置examples/go.mod结语CSM Observability 用极小的接入成本每个二进制一次调用csm.EnableObservability为 Proxyless gRPC 应用补齐了服务网格级别的可观测性既保留了 OpenTelemetry 生态的标准指标与导出链路又通过元数据交换自动附加 workload、mesh 级别的 CSM Labels让跨服务的调用遥测天然具备服务身份维度。结合本文给出的本地联调与容器化部署路径你可以先在本地直连模式下验证指标产出再将其迁移到 Cloud Service Mesh 生产环境中获得完整的网格观测能力。【免费下载链接】grpc-goThe Go language implementation of gRPC. HTTP/2 based RPC项目地址: https://gitcode.com/GitHub_Trending/gr/grpc-go创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表