微服务可观测性:让系统不再黑盒

微服务架构把一个大系统拆成了几十个小服务。每个服务独立部署、独立运行,服务之间通过网络调用。这种架构带来了灵活性和扩展性,但也带来了一个棘手的问题:出问题了怎么排查?

在单体时代,排查问题很简单:去一台机器上翻日志,看到异常堆栈就知道了。但在微服务架构中,一个请求可能经过网关、订单服务、库存服务、优惠券服务、用户服务。日志分散在几十台机器上,你甚至不知道该去看哪台机器的日志。

这就是微服务可观测性要解决的问题。简单来说,可观测性就是让你能够回答三个问题:

  • 链路追踪:慢在哪?断在哪?------ 回答"请求经历了什么"

  • 日志聚合:怎么快速找到相关日志?------ 回答"具体发生了什么"

  • 指标监控:系统整体健康吗?------ 回答"系统状态怎么样"

这三个维度互相配合,才能把一个错综复杂的微服务系统变得"可见、可查、可监控"。

一、链路追踪

1.1 链路追踪解决了什么问题

当一个请求跨多个服务时,你很难知道:整个请求花了多少时间?哪个环节最慢?有没有哪个服务调用失败了?

链路追踪的核心思路是:给每个请求分配一个全局唯一的Trace ID,这个ID在整个调用链路上传递。无论经过多少个服务,所有日志都带上这个ID。这样你只需要搜这个ID,就能把整个链路的所有日志串起来。

除了Trace ID,每个调用环节还有自己的Span ID,记录这一步的详细信息------调用了什么接口、花了多长时间、有没有报错。把所有Span按时间顺序串起来,就形成了一条完整的调用链路。

1.2 SkyWalking vs Zipkin

目前主流的链路追踪工具有两款:SkyWalking 和 Zipkin。

Zipkin 是 Uber 开源的,出现得早,功能简洁,与 SpringCloud Sleuth 集成非常好。缺点是存储依赖 Elasticsearch 或 MySQL,性能一般,UI 相对简单。

SkyWalking 是华为开源的,目前是 Apache 顶级项目。它性能更好,存储用 Elasticsearch,还内置了拓扑图展示------可以直观看到服务之间的调用关系、流量大小、是否异常。功能比 Zipkin 强大,但部署也更重一些。

两者的选择可以参考:SpringCloud 全家忠用户优先考虑 Zipkin,追求功能和性能用 SkyWalking,小项目直接用云厂商的链路追踪产品更省事。

1.3 链路追踪的传递原理

链路追踪的核心技术是上下文传递。在 HTTP 调用中,Trace ID 和 Span ID 放在请求头里传递。在 RPC 调用中,放在协议的扩展字段里。在消息队列中,放在消息的头部。

这就要求所有技术组件------HTTP客户端、RPC框架、MQ客户端------都必须支持这种传递机制。好消息是,SpringCloud 的 OpenFeign、RestTemplate、RabbitMQ 等都做了适配,基本上零配置就能自动传递。

二、日志聚合

2.1 为什么需要日志聚合

没有日志聚合时,查一个请求的日志要登录十几台服务器,逐个用 grep 搜索。如果不知道请求具体走了哪几台机器,更是无从下手。

日志聚合的核心是:把所有服务的日志收集到一个地方,集中存储、统一查询。常用的技术栈是ELK------Elasticsearch存储日志,Logstash负责收集和解析,Kibana提供查询界面。Filebeat是轻量级的日志收集器,部署在每个节点上读取日志文件发送到 Kafka 或 Logstash。

还有更轻量的 Loki,与 Grafana 无缝集成,存储成本比 ES 低很多,但查询功能稍弱。

2.2 日志规范的重要性

日志聚合的前提是日志格式统一。没有统一规范,聚合后的日志会是一团乱麻。

几条规定值得推广:所有服务使用统一的日志格式,包含时间戳、日志级别、服务名、Trace ID、消息内容;链路追踪的 Trace ID 必须打印到每条日志里;关键业务节点打 INFO 日志,排查问题时打 DEBUG 日志。

只要日志格式统一、Trace ID 完整,聚合后的日志可以做到一键搜索整个链路。

2.3 日志采样的必要性

日志量很大的时候,全量采集会占用大量网络带宽和存储空间。日志采样是一种优化手段------只采集部分日志,比如每 100 条取 1 条。

对于 INFO 及以上的重要日志应该全量采集,DEBUG 日志在高并发下基本不开。开启采样后,用来做统计分析和趋势观察是够用的,但精确排查单个问题就不行了。

三、指标监控

3.1 Prometheus 的核心模型

Prometheus 是目前最主流的监控方案。它的数据模型很简单:一个指标就是一组带时间戳的数值。

常见的指标类型有四种:Counter 只增不减的计数器,比如接口总调用次数;Gauge 可增可减的仪表盘,比如内存使用量、当前活跃连接数;Histogram 直方图,统计请求耗时分布;Summary 分位数统计。

3.2 拉模式 vs 推模式

Prometheus 采用拉模式------Prometheus 服务器主动去各个目标拉取指标数据。优点是服务不需要暴漏端口,Prometheus 自己知道谁活着谁挂了;缺点是无法实时推送告警,有十秒左右的延迟。

大部分云厂商的监控服务采用推模式------应用主动把指标推送到网关。优缺点正好相反:实时性好,但需要多维护一个网关组件。

3.3 Grafana 可视化

Prometheus 自带的查询界面不好用,Grafana 是标配的可视化工具。它支持 Prometheus 作为数据源,用图表把指标展示出来。

关键要设计好监控大盘:业务大盘看核心接口 QPS、成功率、响应时间;资源大盘看 CPU、内存、网络、磁盘;依赖大盘看数据库、Redis、MQ 的健康状况。

有了大盘,系统状态一目了然。某个接口慢了、某个服务 CPU 飙升,一眼就能发现。

四、告警配置

4.1 告警规则设计

收集了那么多指标,最终目的是为了及时发现问题。Prometheus 的告警规则在 Alertmanager 组件里配置。

几个常用的告警规则:接口 5 分钟平均响应时间超过 1 秒;接口错误率超过 1%;服务宕机;CPU 持续 5 分钟超过 80%;磁盘可用空间低于 10%。

4.2 告警的常见问题

很多团队的告警配置存在以下问题:

告警太多:几十上百条告警刷屏,反而没人看了。解决方法是提高阈值,只保留真正需要人工介入的规则。

没有处理人:告警发出去了,但没人认领。解决方法是每条告警规则都要指定负责人。

重复告警:一个故障触发五六条告警。解决方法是做告警聚合,同类告警合并成一条。

原则是:告警数量要精,每一条都需要有人负责处理。

五、SpringBoot 中的实践

5.1 链路追踪集成

SpringCloud 全家桶对链路追踪的支持非常好。只需要添加依赖,配置采样率,就会自动在 HTTP 请求和日志中注入 Trace ID。

复制代码
# 关键配置就这两行
spring:
  sleuth:
    sampler:
      probability: 1.0   # 采样率,生产环境设 0.1

5.2 指标暴露

SpringBoot Actuator 可以暴露 Metrics 端点,Prometheus 从这里拉取数据:

复制代码
management:
  endpoints:
    web:
      exposure:
        include: prometheus

添加 micrometer-registry-prometheus 依赖后,Actuator 就会自动输出 Prometheus 格式的指标。

5.3 日志配置

日志配置中要加上 Trace ID。在 Logback 配置文件的 pattern 里加入 [%X{traceId}],这样每条日志都会带上 Trace ID。日志文件名建议加上服务名,比如 user-service.log,防止多个服务的日志混合在一起。

六、总结

微服务可观测性由三个维度构成:

维度 解决什么问题 常用工具
链路追踪 请求经历了什么、慢在哪 SkyWalking、Zipkin
日志聚合 具体报错信息是什么 ELK、Loki
指标监控 系统整体健康状况 Prometheus + Grafana

三个维度不是竞争关系,而是互相补充:

提出需求要三个维度配合:监控指标发现"接口慢了",链路追踪定位"慢在库存服务",日志聚合查出"库存服务查询超时的具体原因"。三者串联起来,可以在几分钟内定位过去可能要查几个小时的问题。

微服务架构把系统复杂度打散了,可观测性则把被打散的复杂度重新可视化地呈现出来。没有可观测性的微服务体系,就像一个没有仪表盘的飞机驾驶舱,你敢飞吗?

相关推荐
下次再写1 小时前
深入浅出微服务架构:从理论到Spring Boot实战
java·微服务·springboot·springcloud·架构设计·后端开发·分布式系统
Kiyra1 小时前
限流不是加个计数器就行:用 Lua 脚本实现多维度原子限流
开发语言·人工智能·网络协议·职场和发展·架构·lua·ai-native
SamDeepThinking2 小时前
千万级用户购物车系统的架构设计
java·后端·架构
前端不太难2 小时前
鸿蒙 App 的 Task + State 双核心架构
架构·状态模式·harmonyos
十年编程老舅2 小时前
深度长文|Linux 图形与显示架构
linux·运维·后端·架构·内核·linux内核·通信机制
heimeiyingwang2 小时前
【架构实战】服务注册与发现Nacos:微服务时代的“电话总机“
网络·架构
薛定猫AI2 小时前
【深度解析】Gemma Chat:基于 MLX 的 Mac 离线 Coding Agent 架构与实战
macos·架构
星梦清河2 小时前
微服务-Elasticsearch01
elasticsearch·微服务·架构
MrSYJ2 小时前
到底怎么使用nginx配置一个前后端分离的项目
微服务·云原生·架构