一、前言:为什么微服务需要监控?
从单体应用到微服务,最大的变化不是代码量,而是问题的定位难度。
单体时代,一个 Tomcat 一个库,接口慢了、报错了,翻一下日志、看一眼 JVM 就能定位。微服务时代:
- 一个请求要跨 3~5 个服务(网关 → 认证 → 业务 → 数据库),出问题到底是哪个环节?
- 服务从 1 个变成 8 个,谁挂了、谁慢了、谁在拖垮别人?
- 每个服务一份日志,全翻一遍才能拼出真相?
所以微服务的监控,本质要回答三个问题:
| 问题 | 对应手段 |
|---|---|
| 服务还活着吗? JVM 健康吗? | 指标监控(Actuator + Spring Boot Admin) |
| 请求到底慢在哪? | 链路追踪(SkyWalking)+ 接口耗时统计 |
| 出错时去哪看现场? | 日志采集与集中查看 |
本文就是围绕这三层,讲我在项目里的真实落地过程
二、三层监控体系
没有一上来就上全家桶,而是按"成本从低到高、先解决最痛的问题"的顺序搭了三层:
┌─────────────────────────────────────────────────┐
│ 第 3 层 链路追踪: SkyWalking │ 慢在哪?跨服务调用关系
│ 拓扑图 + Trace + 慢 span │
├─────────────────────────────────────────────────┤
│ 第 2 层 网关观测: AuthFilter 耗时统计 │ 每个请求多久?哪些是慢接口?
│ 每请求日志 + 慢接口分级告警(WARN/ERROR) │
├─────────────────────────────────────────────────┤
│ 第 1 层 服务监控: Spring Boot Admin │ 服务活着吗?JVM 怎么样?日志呢?
│ Actuator + Nacos 发现 + 实时日志 │
└─────────────────────────────────────────────────┘
技术选型:
| 组件 | 干什么 | 部署方式 |
|---|---|---|
| Spring Boot Admin | 服务状态 + JVM 指标 + 实时日志 | 独立服务 pmhub-monitor(6888) |
| SkyWalking | 全链路追踪 + 拓扑 + 慢接口定位 | Docker(OAP + UI) |
| Gateway AuthFilter | 统一鉴权 + 每请求耗时统计 | 项目代码(网关) |
| Nacos | 服务注册发现(Admin 靠它找服务) | 本机 8848 |
三、实战步骤
步骤 1:给每个服务开启 Actuator 的 logfile 端点
Admin 控制台之所以能"直接看网关的实时日志",靠的是每个服务的 Actuator logfile 端点------它把服务正在写的日志文件暴露成一个 HTTP 接口。
前提条件:
- 依赖:
spring-boot-starter-actuator(7 个业务服务都已引入); - 暴露端点:配置
management.endpoints.web.exposure.include: "*"(放 Nacos 共享配置,所有服务生效); - 有日志文件可读:
logging.file.name: logs/${spring.application.name}/info.log。
启动后直接验证:
bash
curl http://127.0.0.1:6880/actuator/logfile # 网关,返回日志流
curl http://127.0.0.1:6801/actuator/logfile # system

这里当时检查了好久才发现 :日志文件里
WARN级别默认是"失踪人口"------很多项目的 logback 里file_info追加器用LevelFilter只收 INFO,WARN/ERROR 全被丢弃,只进控制台。我们网关的"慢接口 WARN 日志"就是因此一直进不了 Admin 日志页。修复:改成两个 LevelFilter 链式,INFO 和 WARN 都落盘。
步骤 2:Spring Boot Admin 通过 Nacos 发现服务,集中看日志与 JVM
Spring Boot Admin(以下简称 SBA)是监控面板:每个服务注册到 Nacos 后,SBA 通过 Nacos 发现所有实例 ,然后 HTTP 轮询它们的 /actuator/* 端点,把状态、JVM 指标、日志都拉到自己页面上。
SBA 侧配置 (Nacos 里 pmhub-monitor-dev.yml):
yaml
spring:
security:
user:
name: admin # 控制台登录
password: 123456
boot:
admin:
ui:
title: PmHub服务状态监控
discovery:
enabled: true
ignored-services: pmhub-monitor # 排除自己,避免无 actuator 显示 OFFLINE
登录 http://localhost:6888(admin/123456),wallboard 上就能看到全部服务,点进 pmhub-gateway:
- Logging 标签:实时日志(就是步骤 1 的 logfile 端点);
- Metrics 标签:堆内存、GC、线程、HTTP 请求量等 JVM 指标;
- Journal 标签:服务上下线、状态变化事件。



步骤 3:网关统一鉴权 + 每请求耗时统计 + 慢接口分级
这一层是纯代码,不用额外组件。网关的 AuthFilter(全局过滤器)本来就做登录态校验,我们让它顺手把每个请求的耗时记下来,并做分级:
java
// 1. 记录开始时间
exchange.getAttributes().put("begin_visit_time", System.currentTimeMillis());
return chain.filter(exchange.mutate().request(mutate.build()).build())
.then(Mono.fromRunnable(() -> {
long cost = System.currentTimeMillis() - begin;
// 分级:>3s ERROR,>1s WARN,其余 INFO
if (cost > 3000) log.error("慢接口(>3s): {}", logData);
else if (cost > 1000) log.warn("慢接口(>1s): {}", logData);
else log.info("访问接口信息:{}", logData);
}));
效果:每个经过网关的请求都留一行日志,慢接口自动升级为 WARN/ERROR,配合 Admin 日志页就能实时看到哪些接口在拖慢系统。

步骤 4:SkyWalking 全链路追踪,慢接口一眼定位
网关日志能告诉你"这个接口慢",但慢在哪一步(网关?下游服务?SQL?Redis?)要靠链路追踪。SkyWalking 是目前最主流的开源 APM 之一,Agent 自动埋点,业务代码零侵入。
4.1 用 Docker 起 OAP + UI
yaml
# docker-compose.middleware.yml
services:
pmhub-skywalking-oap:
image: apache/skywalking-oap-server:9.7.0
ports: ["11800:11800", "12800:12800"] # 11800 是 agent 上报 gRPC 端口
environment: [SW_STORAGE=h2] # 演示用内嵌存储,重启丢数据可接受
pmhub-skywalking-ui:
image: apache/skywalking-ui:9.7.0
ports: ["8085:8080"]
environment: [SW_OAP_ADDRESS=http://pmhub-skywalking-oap:12800]
4.2 给服务挂 Agent(零代码侵入)
下载 apache-skywalking-java-agent-9.7.0.tgz(国内用清华镜像),解压到 agent/skywalking-agent,然后每个服务启动时加三个 JVM 参数:
-javaagent:C:/.../agent/skywalking-agent/skywalking-agent.jar
-Dskywalking.agent.service_name=pmhub-gateway
-Dskywalking.collector.backend_service=127.0.0.1:11800
Spring MVC、Spring Cloud Gateway、OpenFeign、MyBatis、Redis 的调用,Agent 自动埋点,业务代码一行不用改。
4.3 演示:造一个慢接口,看全链路
写一个 2 秒的演示接口(模拟慢 SQL/慢第三方调用):
java
@GetMapping("/project/demo/slow")
public AjaxResult slow() throws InterruptedException {
Thread.sleep(2000);
return AjaxResult.success("slow done, cost 2000ms");
}
发两个请求后,打开 SkyWalking UI(http://localhost:8085):
- 拓扑图:能看到 gateway → project 的调用边(还有 gateway/project → Redis 的边);
- Trace:点进慢请求,展开 span,2 秒的耗时一眼定位在哪个服务的哪个方法;
- 与网关日志的
duration对照,两个视角交叉验证。


还可以直接点击网关服务进入

可以看见非常的清晰,各种指标都有。我也是第一次用发现还可以看消息队列。甚至可以直接看数据库的慢sql情况。惊艳到我了

四、实践效果
| 能力 | 效果 |
|---|---|
| 统一鉴权 | 8 个服务共用网关登录态校验 |
| 接口耗时 | 每请求落日志,慢接口 >1s WARN、>3s ERROR 分级 |
| 日志集中 | Admin 控制台实时看任意服务日志 + JVM 指标 |
| 全链路追踪 | 跨服务调用拓扑、慢 span 定位到具体方法 |
| 零侵入 | SkyWalking Agent 自动埋点,业务代码零改动 |
五、不足与下一步
这套方案解决的是"能看见 ",但离"好排查"还有明显差距,老实说:
1. 日志靠"翻"
Admin 的日志页本质是"tail 一个文件",不能按关键字全文检索、不能聚合统计 。出问题时要自己对着日志文件翻,服务一多就低效。
→ 需要引入 集中式日志检索(ELK 或 Loki)。
2. 没有指标大盘
Actuator 的指标能看,但没有趋势图、没有对比 ,内存涨没涨、QPS 变化,靠肉眼盯不现实。
→ 需要 Prometheus 采集 + Grafana 可视化。
3. 没有告警
不管是日志异常还是指标超标,都要人主动去看 ;服务半夜挂了,第二天才发现。
→ 需要 Alertmanager 告警 + 钉钉/企微通知。
4. 日志和链路没打通
SkyWalking 的 trace 和业务日志是两套体系,排查时"这条 trace 对应的日志是什么"要靠时间戳人工对齐。
→ 在日志里注入 traceId,链路 ↔ 日志一键关联。
5. 存储是 H2
演示用的 SkyWalking H2 存储重启即丢,只适合学习;真要长期跑要上 Elasticsearch 或 BanyanDB。
六、顺带认识一下其他监控组件
| 组件 | 一句话定位 | 和本文方案的关系 |
|---|---|---|
| Prometheus | 指标采集 + 存储 + 查询的数据库(PromQL 查询语言),拉模型主动抓指标 | 替代/增强"手动看 Actuator 指标" |
| Micrometer | 指标门面(门面模式),统一各类监控系统 API;Spring Boot Actuator 的指标底层就是它 | 本文已经在用(Actuator 基于它),接 Prometheus 只需加依赖 |
| Grafana | 可视化大盘,把 Prometheus/MySQL/日志等数据源画成图表、看板 | 给 Prometheus 指标画趋势图 |
| Loki | 轻量级日志聚合,只索引标签不索引全文,存储成本低,和 Grafana 一家 | 替代"翻日志文件" |
| ELK(Elasticsearch + Logstash + Kibana) | 重量级全文日志检索,Logstash 采集加工、ES 存储索引、Kibana 可视化 | 日志量大的场景比 Loki 强,但重 |
| Zipkin / Jaeger | 链路追踪,和 SkyWalking 同类(基于 OpenTracing/OpenTelemetry 思想) | 可替代 SkyWalking |
| Alertmanager | 告警管理:规则匹配、去重、路由到钉钉/邮件/企微 | 给监控装上"闹钟" |
演进路线:
当前:Admin 看状态+日志 / 网关耗时 / SkyWalking 链路
↓
第一步:Prometheus + Micrometer + Grafana ------ 指标大盘,成本最低、收益最直观
↓
第二步:Loki + Promtail ------ 日志集中检索,和 Grafana 同一入口
↓
第三步:Alertmanager 告警 ------ 被动监控 → 主动通知
↓
第四步:日志注入 traceId,链路日志打通 ------ 排查体验质变
七、总结
微服务监控没有银弹,最务实的三板斧是:指标(活着吗)+ 日志(出啥事)+ 链路(慢在哪)。
- 低成本起步:Actuator + Spring Boot Admin 先解决"看得见";
- 网关顺手埋点:耗时统计 + 慢接口分级,零组件成本;
- 链路追踪:SkyWalking 一键接入,定位跨服务慢请求;
监控不是"装完就算",而是出了问题能快速定位 ------这就是它的价值。
在本次实战中admin充当的是发现问题:通过查看日志。
skywalking充当的是链路追踪,我只知道哪个接口慢,就可以知道哪个服务慢。
当定位到具体服务,可以查看admin,可以根据jvm和可以查看内存使用,垃圾回收,进程线程。
