第1章:可观测性概述
大家好,我是你们的老朋友。今天咱们聊聊可观测性这个热门话题。
说实话,我刚入行那会儿,监控就是看看CPU、内存、磁盘。那时候觉得,能把这些指标盯住,就已经很了不起了。但后来我发现,事情远没那么简单。
从监控到可观测性的演进
监控和可观测性,这两个词经常被混用。但我个人习惯把它们区分开。
监控,说白了就是「我知道系统出了什么问题」。比如告警说CPU飙到90%,你知道了,然后去排查。
可观测性,则是「我不用猜,系统自己告诉我为什么出了问题」。你想想看,这完全是两个层次的事情。
我记得有一次线上事故,服务突然变慢。监控告诉我响应时间从50ms涨到了5s。但为什么?监控说不清楚。我花了整整一个下午,翻日志、查链路、看指标,最后才发现是数据库连接池被打满了。
这就是监控和可观测性的区别。监控告诉你「出事了」,可观测性告诉你「哪里出事了,为什么出事」。
核心观点:监控是「已知的未知」,可观测性是「未知的未知」。你预先定义好告警规则,那是监控。你随时能问系统「你现在怎么样」,那是可观测性。
三大支柱:Metrics、Logs、Traces
说到可观测性,就绕不开这三大支柱。我刚开始接触这个概念时,觉得不就是三个东西嘛,分开搞就行了。后来踩了坑才明白,它们必须协同工作。
| 支柱 | 是什么 | 典型工具 | 我踩过的坑 |
|---|---|---|---|
| Metrics(指标) | 聚合后的数值数据,比如QPS、延迟、错误率 | Prometheus、Grafana | 指标太多,存储爆炸 |
| Logs(日志) | 离散的事件记录,每行日志是一个事件 | ELK、Loki | 日志格式不统一,解析困难 |
| Traces(链路) | 请求在分布式系统中的完整路径 | Jaeger、Zipkin | 采样率设置不当,丢失关键数据 |
Metrics:系统的「体温计」
指标是最直观的。你看到CPU高了,就知道系统可能有问题。但指标有个致命缺陷——它只能告诉你「是什么」,不能告诉你「为什么」。
举个例子,你的服务QPS从1000掉到了100。指标告诉你「掉量了」。但为什么掉量?是上游服务挂了?还是网络问题?还是用户不来了?指标说不清楚。
我的建议:指标要少而精。别什么都往Prometheus里塞。我见过一个团队,一个服务暴露了500多个指标,最后没人看得懂。我个人习惯,每个服务核心指标不超过20个。
Logs:系统的「日记本」
日志记录了系统发生的每一件事。但问题在于,日志太多了。一个中等规模的服务,一天能产生几十GB的日志。
我曾经处理过一个线上问题,服务间歇性报错。我翻了一整天的日志,眼睛都快瞎了,才发现是某个特殊字符导致JSON解析失败。后来我学乖了,日志必须结构化,必须带trace_id。
# 不好的日志格式
2024-01-15 10:30:45 ERROR: something went wrong
# 好的日志格式
{"timestamp":"2024-01-15T10:30:45Z","level":"ERROR","trace_id":"abc123","service":"order","message":"order creation failed","error":"invalid json"}
Traces:系统的「导航地图」
链路追踪是我觉得最有意思的部分。它能把一个请求从入口到出口的完整路径画出来。
你想想看,一个请求经过A服务、B服务、C服务,最后调用数据库。如果慢了,到底是哪个环节慢?链路追踪一目了然。
我记得有一次,用户反馈下单很慢。指标看没问题,日志也没报错。但链路追踪告诉我,请求在B服务等待了3秒。进一步看,B服务在等待一个Redis锁。原来是某个慢查询把锁占住了。
注意:链路追踪有性能开销。我曾经见过一个团队,采样率设成100%,结果服务本身性能下降了20%。建议生产环境采样率控制在1%-10%,或者使用自适应采样。
云原生环境下的挑战
云原生环境,说白了就是微服务+容器+K8s。这套东西给可观测性带来了全新的挑战。
- 服务数量爆炸:以前一个单体应用,监控一个进程就够了。现在可能有几十上百个微服务,每个服务还有多个副本。
- 生命周期短暂:容器随时可能被调度、重启、扩缩容。Pod的IP是动态的,名字也是随机的。传统基于主机名的监控方式完全失效。
- 数据量巨大:每个服务都在产生指标、日志、链路。数据量是以前的几十倍甚至上百倍。
- 依赖关系复杂:服务之间互相调用,A依赖B,B依赖C,C又依赖A。出了问题,根本不知道从哪查起。
我刚开始做云原生监控时,犯过一个低级错误。我把所有Pod的指标都采集到Prometheus,结果存储直接爆了。后来才意识到,需要做指标降维和聚合。
避坑指南:我曾经在K8s集群里部署了完整的监控栈,结果发现监控系统本身占用了20%的集群资源。后来我做了三件事:1)只采集关键指标;2)合理设置采集间隔;3)使用sidecar模式减少网络开销。资源占用降到了5%以下。
还有一个容易被忽视的问题——时间同步。在分布式系统中,如果各个节点的时间不一致,链路追踪和日志关联就会出大问题。我建议所有容器都使用NTP同步时间,并且在日志和链路中统一使用UTC时间。
嗯,这里要注意一点。云原生环境下的可观测性,不是简单地把传统监控搬到容器里。你需要重新思考:
- 如何自动发现服务?
- 如何动态配置采集规则?
- 如何在海量数据中快速定位问题?
- 如何平衡数据完整性和存储成本?
这些问题,我们后面会一一展开。今天先到这里,下一章我们聊聊Prometheus的实战部署。
课后思考:你现在的监控系统,能回答「为什么」这个问题吗?如果不能,那它只是监控,不是可观测性。
公众号:蓝海资料掘金营,微信deep3321