一、从监控到可观测性
传统监控回答“系统是否工作”,可观测性更进一步回答“为什么不工作”。它通过三类数据(Telemetry)实现:日志(Logs)、指标(Metrics)、追踪(Traces)。三者互补,缺一不可。
二、日志:事件的离散记录
日志是最古老的观测手段。最佳实践包括:
结构化日志:使用JSON格式,便于机器解析。PHPMonolog、JavaLogstashEncoder、C++spdlog均支持。
日志级别:ERROR(需要立即处理)、WARN(潜在问题)、INFO(关键业务流程)、DEBUG(开发调试)。生产环境只开启INFO以上。
避免敏感信息:禁止记录密码、令牌、身份证号。
异步写入:避免日志I/O阻塞业务线程(JavaLog4j2异步Appender、PHP可推送到队列)。
日志的缺点:存储量大,检索复杂(需要ELK/Loki)。但对于异常现场还原,日志无可替代。
参考:https://www.wkmsa.cn/category/sleep-disorders.html
三、指标:聚合的可量测数据
指标是数值型统计数据(如QPS、平均延迟、错误率),通常定期采集并存储到时序数据库(Prometheus、InfluxDB)。指标最适合设置告警和绘制仪表盘。
指标维度:
Counter(计数器):只增不减,如请求总数。
Gauge(仪表盘):可增可减,如当前内存占用。
Histogram(直方图):记录分布,如请求延迟的百分位。
各语言的指标库:
PHP:Prometheus官方客户端(支持APC共享内存)。
Java:Micrometer(SpringBoot默认集成),可导出到Prometheus、Datadog等。
C++:PrometheusC++客户端、或通过statsdexporter。
四、追踪:请求的端到端路径
分布式追踪(Tracing)记录一个请求在多个服务间的完整调用链。核心概念:
Trace:一次完整请求的全局ID。
Span:单个操作(如一次RPC、数据库查询),包含开始时间、结束时间、元数据。
SpanContext:用于跨进程传递Trace信息(通常通过HTTP头)。
OpenTelemetry已成为追踪标准,兼容Zipkin、Jaeger。Java通过Javaagent自动埋点(零代码侵入);PHP可通过扩展(如OpenTelemetryPHP)或手动埋点;C++则需集成SDK。
参考:https://www.wkmsa.cn/category/sleep-methods.html
五、三者的关联
日志应包含trace_id和span_id,以便从指标异常跳转到具体日志,再关联到追踪链路。
指标可以从追踪数据中派生(如统计每个服务的延迟分布)。
错误率高时,通过指标预警→采样相关trace→查看该trace的日志,定位根因。
六、各语言的成熟度
Java:生态最完善。SpringCloudSleuth+Micrometer+OpenTelemetry无缝集成。
PHP:有OpenTelemetry扩展和Laravel集成包,但生产使用较少。许多团队仍依赖NewRelic等APM商业软件。
C++:需要手动集成opentelemetry-cpp,然后导出到Jaeger/Zipkin。因为C++服务通常作为高性能基础组件,其可观测性往往由上层治理系统间接完成。
七、落地建议
从指标监控开始,快速建立告警体系。
选择一套APM工具(如Jaeger+Prometheus+Grafana)统一数据源。
逐步推进结构化日志和追踪注入。不必一次性完美,持续迭代。
八、总结
可观测性不是工具堆砌,而是工程文化。当团队习惯通过仪表盘和链路排查问题,而不只是登录服务器看日志时,系统韧
参考:https://www.wkmsa.cn