游戏服务的可观测性能力建设(C++生态)
前言
近年来可观测性领域越来越成熟,游戏服务的可观测性能力建设日益成为提升产品质量与运维效率的关键环节。随着游戏系统架构的不断复杂化,传统的监控和故障排查方式已难以满足业务高可用和用户体验优化的需求。通过健全的可观测性体系,可以实现对游戏服务全链路的实时监控、异常检测与分析,助力技术团队及时发现和定位问题,推动产品持续优化与稳定迭代,从而为玩家提供更加流畅和可靠的游戏体验。
近年来可观测性领域越来越成熟,游戏服务的可观测性能力建设日益成为提升产品质量与运维效率的关键环节。随着游戏系统架构的不断复杂化,传统的监控和故障排查方式已难以满足业务高可用和用户体验优化的需求。通过健全的可观测性体系,可以实现对游戏服务全链路的实时监控、异常检测与分析,助力技术团队及时发现和定位问题,推动产品持续优化与稳定迭代,从而为玩家提供更加流畅和可靠的游戏体验。
我给我们的服务器框架深度集成了一些可观测性的能力。使用 opentelemetry-cpp 作为接入层。 在指标方面,我们允许业务层自由地定制化指标上报和拉取,并以此实现策略控制。上报的时候有Pull模式接口(异步接口),也有Push模式接口(同步接口)。 为了减少 opentelemetry-cpp 内部的视图合并开销,性能最佳,我们尽量使用异步接口。 但是这种情况下由于 opentelemetry-cpp 内部存在后台Processor线程、Exporter线程等,指标的采集往往需要跨线程操作。 这就要求我们上报代码逻辑需要保证线程安全。
这篇分享拖更了好久了。问题起源于去年我们项目组接入 opentelemetry-cpp 的时候,在进程优雅退出的时候偶现超时,虽然可以直接kill进程没啥影响但是退出不“优雅”的话总归会破坏发布流程,增加人工介入的成本。这里记录一下问题可能其他的组件有类似的用法也会有相似的问题。
opentelemetry-cpp 在标准上报协议OTLP里是支持使用 gRPC 作为传输协议的。但是,当 gRPC 被作为静态库同时链接进多个动态库时,在一些平台上会有一些问题。这是 gRPC 本身的一些实现方式导致的。 一直拖到今天才来比较完整得写这个问题的具体成因和解决方案,实际上也有一些其他库有相似实现的也会有相同的问题,所以分享出来看看有没有其他同学也可能碰到可以参考一下。
Opentelemetry-cpp 是可观测领域,opentelemetry (CNCF基金会孵化项目)的C++ SDK接入层。 opentelemetry 里面主要是分链路跟踪(Trace)、指标(Metrics)、日志(Logs)三大块。 同时 opentelemetry 有一个标准规范文档 opentelemetry-specification ,而SDK实现主要就是来对这个标准规范文档的特定语言实现。 由于日志(Logs)这一块一直处于Experimental阶段,所以很长时间以来 C++ SDK接入层 都没有及时更新跟进规范的变化。
前段时间有人在 opentelemetry-cpp 提出了api组件在动态库中单例无法工作的 issue ,( https://github.com/open-telemetry/opentelemetry-cpp/issues/1520 ) 。
opentelemetry 是可观测性领域的开源项目,目标是统一链路跟踪、数据指标和日志的服务、上报、协议和接口规范,目前属于 CNCF基金会 孵化项目。而 opentelemetry-cpp 则是 opentelemetry 中对标准规范SDK的C++实现。