
gRPC C CSM 可观测性示例深度解析基于 xDS 与 OpenTelemetry 的 Hello World 实战指南【免费下载链接】mongoThe MongoDB Database项目地址: https://gitcode.com/GitHub_Trending/mo/mongo本篇技术指南以 gRPC C 的 CSMCloud Service Mesh可观测性示例为核心讲解如何基于 Hello World 示例 改造出支持 CSM 遥测的客户端与服务端覆盖命令行参数、OpenTelemetry 与 Prometheus 采集链路的初始化方式、xDS 目标解析机制以及基于 Bazel 的多阶段 Docker 构建与镜像推送全流程。读完本文你将能够独立编译、部署并理解一个完整的 gRPC C CSM 可观测性程序并掌握其底层实现原理。示例概览从 Hello World 到 CSM 可观测性CSMCloud Service Mesh可观测性示例位于仓库中的src/third_party/grpc/dist/examples/cpp/csm/observability/目录它在标准的 Hello World Example 基础上为 gRPC 客户端与服务端增加了 CSM 可观测性能力。两者的核心差异在于Hello World 示例客户端直连固定地址如localhost:50051无服务网格概念CSM 可观测性示例客户端默认通过 xDS 协议解析xds:///helloworld:50051目标将指标通过 OpenTelemetry SDK 导出到 Prometheus从而实现对跨集群、跨负载均衡器的 RPC 调用进行端到端观测。示例目录共包含 5 个文件文件作用README.md配置与构建说明文档csm_greeter_client.cc启用 CSM 可观测性的 gRPC 客户端csm_greeter_server.cc启用 CSM 可观测性的 xDS gRPC 服务端Dockerfile.client客户端镜像构建文件Dockerfile.server服务端镜像构建文件BUILDBazel 构建目标定义命令行参数配置客户端与服务端分别通过 Abseil Flags 接收命令行参数见 csm_greeter_client.cc 与 csm_greeter_server.cc。客户端参数参数默认值说明--targetxds:///helloworld:50051目标地址。默认情况下 gRPC 使用 xDS 解析该目标并连接到服务端后端可通过该参数覆盖为其他 target--prometheus_endpointlocalhost:9464Prometheus 暴露端点见下方源码说明--target的默认值意味着客户端不会直接连接某个 IP而是将解析工作交给 xDS 控制面。从源码看xDS 解析链路由 util.cc 中的RunClient承载它使用grpc::CreateCustomChannel(target, grpc::XdsCredentials(...))创建带有 xDS 凭据的 Channel并以每秒一次的频率持续向服务端发送SayHelloRPC。服务端参数参数默认值说明--port50051Hello World 服务的监听端口--prometheus_endpointlocalhost:9464Prometheus 暴露端点关于prometheus_endpoint的源码细节值得注意的是虽然命令行 Flag 默认值为localhost:9464但客户端与服务端源码中都显式将实际的 Prometheus Exporter URL 覆盖为0.0.0.0:9464注释明确说明原因默认的localhost:9464在跨 GKE Pod 场景下会导致连接问题。因此实际部署中采集端点监听在所有网卡上便于 Prometheus 从集群内任意位置抓取指标opentelemetry::exporter::metrics::PrometheusExporterOptions opts; // default was localhost:9464 which causes connection issue across GKE pods opts.url 0.0.0.0:9464; opts.without_otel_scope false;CSM 可观测性初始化OpenTelemetry 链路剖析CSM 可观测性的核心是grpc::CsmObservabilityBuilder。客户端与服务端都遵循相同的初始化三步曲1. 创建 Prometheus Exporter 与 MeterProvider通过 OpenTelemetry C SDK 创建 Prometheus 导出器并挂载到MeterProvider上auto prometheus_exporter opentelemetry::exporter::metrics::PrometheusExporterFactory::Create(opts); auto meter_provider std::make_sharedopentelemetry::sdk::metrics::MeterProvider(); meter_provider-AddMetricReader(std::move(prometheus_exporter));2. 覆盖直方图边界Latency View源码注释指出默认的直方图边界对 RPC 粒度不够精细因此两个示例都调用AddLatencyView覆盖延迟指标的 bucket 边界遵循 gRPC A66 提案otel stats的建议客户端覆盖grpc.client.attempt.duration指标服务端覆盖grpc.server.call.duration指标。AddLatencyView定义于 util.cc设置了从0.00001秒10 微秒到100秒共 40 个细粒度边界并通过InstrumentSelectorMeterSelectorViewFactory注册到grpc-c这个 meter 上。对于毫秒级、微秒级 RPC 延迟的精确观测这套边界远比默认直方图实用。3. 构建并注册 CSM 可观测性插件auto observability grpc::CsmObservabilityBuilder() .SetMeterProvider(std::move(meter_provider)) .BuildAndRegister(); if (!observability.ok()) { std::cerr CsmObservability::Init() failed: observability.status().ToString() std::endl; return static_castint(observability.status().code()); }从 csm_observability.cc 的实现可以看到BuildAndRegister()会注册一个CsmOpenTelemetryPluginOption并调用底层OpenTelemetryPluginBuilderImpl::BuildAndRegisterGlobal()随后将全局开关g_csm_plugin_enabled置为true。若初始化失败程序将以对应错误码退出。CsmObservability对象采用 RAII 管理生命周期析构时会将g_csm_plugin_enabled复位为false见同文件第 104-108 行从而在对象销毁时自动关闭 CSM 遥测能力。底层原理xDS 目标选择与服务网格标签注入仅对 xDS 目标启用CSM 遥测并不会无条件作用于所有 Channel。从 csm_observability.cc 的CsmChannelTargetSelector可以看到严格的启用条件if (!g_csm_plugin_enabled) return false; auto uri grpc_core::URI::Parse(target); if (!uri.ok()) return false; // CSM channels should have an xds scheme if (uri-scheme() ! xds) return false; // If set, the authority should be TD if (!uri-authority().empty() uri-authority() ! traffic-director-global.xds.googleapis.com) { return false; } return true;即目标必须使用xdsscheme且 authority若指定必须是 Traffic Director 的全局地址traffic-director-global.xds.googleapis.com。这保证了 CSM 遥测只作用于经服务网格控制面管理的流量避免对普通直连调用产生额外开销。服务网格标签注入CsmOpenTelemetryPluginOption构造时创建了ServiceMeshLabelsInjector其标签来源于google::cloud::otel::MakeResourceDetector()-Detect()见 csm_observability.cc。这意味着导出的指标会自动携带从云环境资源检测器获取的集群、命名空间、Pod 等标签从而在 Prometheus 中实现按服务网格维度聚合。xDS 服务端能力服务端通过 util.cc 的RunXdsEnabledServer启动关键差异在于使用grpc::XdsServerBuilder与grpc::XdsServerCredentials并启用默认健康检查服务grpc::EnableDefaultHealthCheckService(true)与 Proto 反射插件grpc::reflection::InitProtoReflectionServerBuilderPlugin()使其能够接入 xDS 控制面并接受服务网格管理。此外服务端还引入grpcpp_admin依赖为运维提供 admin 服务。使用 Docker 构建镜像文档给出的构建方式基于 Docker 多阶段构建。在 gRPC workspace 目录即src/third_party/grpc/dist下执行构建客户端镜像docker build -f examples/cpp/csm/observability/Dockerfile.client构建服务端镜像docker build -f examples/cpp/csm/observability/Dockerfile.serverDockerfile 内部结构拆解两个 Dockerfile 均采用多阶段构建见 Dockerfile.client 与 Dockerfile.server第一阶段构建阶段基于python:3.9-slim-bookworm安装build-essential clang curl将仓库源码复制到/workdir后执行 Bazel 构建RUN tools/bazel build //examples/cpp/csm/observability:csm_greeter_client RUN cp -rL /workdir/bazel-bin/examples/cpp/csm/observability/csm_greeter_client /artifacts/第二阶段运行阶段同样基于 slim 镜像仅安装运行所需的curl将构建产物从第一阶段拷贝进来并作为容器入口COPY --from0 /artifacts ./ ENTRYPOINT [/csm_greeter_client]服务端 Dockerfile 还额外设置了一个关键的GRPC_TRACE环境变量见 Dockerfile.server用于开启 xDS 全链路跟踪日志涵盖xds_client、xds_resolver、cds_lb、ring_hash_lb、outlier_detection_lb等负载均衡与解析器组件便于排查服务网格接入问题ENV GRPC_TRACExds_client,xds_resolver,xds_cluster_manager_lb,cds_lb,xds_cluster_resolver_lb,priority_lb,xds_cluster_impl_lb,weighted_target_lb,xds_server_config_fetcher,ring_hash_lb,outlier_detection_lb,xds_wrr_locality_lb,xds_override_host_lbBazel 构建目标若希望在本地直接构建可使用 BUILD 中定义的两个cc_binary目标tools/bazel build //examples/cpp/csm/observability:csm_greeter_client tools/bazel build //examples/cpp/csm/observability:csm_greeter_server两个目标均依赖//:grpc、//:grpcpp_csm_observability、//examples/cpp/otel:util、//examples/protos:helloworld_cc_grpc、Abseil flags/log 以及 OpenTelemetry C 的prometheus_exporter与sdk/src/metrics服务端额外依赖//:grpc_reflection与//:grpcpp_admin。编译时通过defines [BAZEL_BUILD]使代码走 Bazel 构建分支的 include 路径。推送镜像到镜像仓库构建完成后若需推送镜像到 registry文档给出了两种方式构建时直接打标签在docker build命令中追加-t参数docker build -t ${tag} -f examples/cpp/csm/observability/Dockerfile.client构建后补打标签使用构建输出中得到的镜像 SHA 打标签docker image tag ${sha from build command above} ${tag}随后使用docker push ${tag}将打标签后的镜像推送到目标 registry即可用于 Kubernetes / GKE 等集群中的服务网格部署。部署形态与数据流总结综合文档与源码该示例在服务网格中的完整数据流为服务端以--port 50051启动通过XdsServerBuilder注册到 xDS 控制面并监听0.0.0.0:9464暴露 Prometheus 指标客户端以默认xds:///helloworld:50051为目标启动经 xDS 解析后连接到服务端每秒发起一次SayHelloRPCgRPC 的 OpenTelemetry 插件基于CsmChannelTargetSelector判定该 Channel 属于 CSM 流量随即注入服务网格标签并采集 RPC 指标客户端与服务端分别通过grpc.client.attempt.duration与grpc.server.call.duration直方图记录延迟经 Prometheus Exporter 在9464端口暴露供 Prometheus 抓取。参考与延伸阅读Hello World 基础示例本示例的改造基础CSM 可观测性核心实现CsmObservabilityBuilder、目标选择器与标签注入的完整实现OTel 公共工具函数AddLatencyView、RunClient、RunXdsEnabledServer的声明BUILD 构建定义客户端与服务端二进制目标的依赖关系延迟直方图边界的设定依据为 gRPC 的 A66 提案otel stats示例代码中的注释给出了该提案作为推荐依据。通过本文你不仅掌握了该示例的参数、构建与部署方式还理解了 CSM 可观测性在 gRPC C 中的实现机理——从 xDS 目标判定、资源标签注入到 OpenTelemetry 直方图覆盖为在服务网格中落地可观测的 gRPC 服务提供了可直接复用的工程模板。【免费下载链接】mongoThe MongoDB Database项目地址: https://gitcode.com/GitHub_Trending/mo/mongo创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考