news 2026/10/10 2:29:20

SkyWalking + Spring Boot 全链路监控接入指南:从环境搭建到生产避坑

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SkyWalking + Spring Boot 全链路监控接入指南:从环境搭建到生产避坑

不管是第一次接手别人留下的老项目,还是自己从零搭服务,线上出问题的时候,最折磨人的通常不是“服务挂了”,而是“明明没报错,但接口就是慢”。日志翻了几遍没看出问题,数据库慢查询也是空的,Redis 也没热点,最后折腾半天,发现是上游服务的某个接口超时拖垮了整条链路。这种场景经历多了就会明白,单点日志已经撑不住分布式排查了。SkyWalking 这个开源 APM(应用性能监控)项目,就是用来解决这类问题的:不需要改业务代码,Java 应用只要在启动命令里加一段 javaagent 参数,就能自动把服务拓扑、调用链路、接口耗时、JVM 指标、慢 SQL 全部采集出来。这篇文章我想按“从 0 到 1”的方式,完整走一遍基于 SkyWalking 给 Spring Boot 应用做性能监控的过程,包括环境搭建、Agent 接入、数据读法和生产实践里容易踩的坑。

1. 先搞清楚:SkyWalking 到底帮你盯什么

1.1 没有 APM 的时候,排查慢接口有多痛苦

用一个很典型的场景来说。假设你负责一个订单服务,前端反馈说“下单页一直转圈”,第一反应是看服务端日志,结果整个流程打了几十条 info,看不出哪一步慢。然后看数据库,慢查询日志为空;看 Redis,延迟正常;看服务器 CPU,也不高。最后通过一遍遍加日志、预发布环境反复压测,才发现问题出在另一个服务调用上——下单流程里调用了库存服务的接口,而那个接口在活动期间一直被大查询拖住,响应时间从 50ms 涨到了 3s。整个过程耗费了大半天,期间用户持续受影响。

这种问题还不是最难的,难的是跨服务调用链很长的时候。订单服务调用支付服务,支付服务又回调账务服务,账务服务还要调风控服务,任何一个环节变慢或者抛错,没有 APM 的情况下只能人工去每个服务里翻日志,再靠时间戳手工拼链路。而这类问题的共同点是:单点的监控都有,但缺了“把一次请求完整串起来”的视野。SkyWalking 最核心的价值就是补上这一环——它把分布式调用链做成了一条完整的 trace,每个环节的耗时、状态、报错信息一眼就能看到。

1.2 SkyWalking 的三大组成部分分别是干什么的

第一块是 Agent,也就是探针。它以 javaagent 的方式跟着 Java 进程一起启动,自动针对 Spring MVC、Feign、JDBC、Redis 这些常用组件做字节码增强,拦截关键方法的调用,生成 trace 数据。Agent 本身不分析数据,只负责采集和上报,所以对你的业务代码基本零侵入。

第二块是 OAP Server,也就是分析端。它负责接收 Agent 上报的 trace 数据和指标数据,做聚合、统计、告警判断,然后把结果写入存储。OAP 本身是无状态的,多个实例可以横向扩展,这也是 SkyWalking 能支撑大规模集群的底气所在。

第三块是 UI,也就是前端展示。它从 OAP 读取数据,展示服务拓扑、调用链详情、服务指标、JVM 信息、告警列表等。UI 的操作逻辑和大多数 APM 工具类似,不需要额外学习太多复杂概念。

数据流向大致是这样的:Agent 通过 gRPC 上报到 OAP,OAP 分析之后写入存储(演示环境可以用内置 H2,生产环境一般用 Elasticsearch),UI 再通过 HTTP 从 OAP 拿数据展示。理解这条链路很重要,后面很多问题排查都是围绕它展开的。

1.3 为什么选 SkyWalking 而不是自己打点或者用其他工具

很多团队最开始会犹豫:我直接用日志不也能做链路吗?或者说用 Zipkin 不行吗?我的观点是这样的——如果你只是偶尔排查一两个接口,那日志手工串够用;但只要服务数量超过三五个,或者调用链超过两层,自己打点的成本就完全失控了。每个服务都要改代码、传 traceId、上报 span,光统一规范就得吵好几轮,更别说存储和分析的工程量。

SkyWalking 相比其他开源 APM 的几个优势,我实际用下来感受比较明显:一是接入成本低,Java 项目不需要改代码,只要把 agent 的路径加到启动命令里,对现有服务基本无侵入;二是数据模型覆盖得全,调用链、拓扑、JVM、慢 SQL、慢接口都有,省去同时部署三四套工具的麻烦;三是可观测的数据经过了聚合,UI 上看到的是服务的平均响应时间、成功率、吞吐量这些业务维度指标,而不是一堆原始 span 日志。跟 Zipkin 那种偏向 trace 原始数据的工具相比,SkyWalking 更像“开箱即用的监控平台”。

提示:APM 不是只有 SkyWalking 一家,选型时可以把 Pinpoint、Arthas、Prometheus + Grafana 这些方案都列出来对比,但如果你主要技术栈是 Java/Spring Boot,SkyWalking 的性价比通常是最高的。

2. 环境搭建:8.x 还是 9.x,怎么选怎么装

2.1 版本选择:一个让我少踩很多坑的建议

版本选择是我最想先说的。SkyWalking 目前我实际用过 8.9.1 和 9.6.0 两个版本,它们的差别主要体现在对后端存储和部分特性的支持上。8.9.1 是非常经典的稳定版,对 Java 8 的兼容最好,适合很多还在用 Spring Boot 2.x 的老项目;9.x 系列在存储层支持了更多 Elasticsearch 版本,同时浏览器监控、日志集成这些能力也更完善。如果你是新项目、用的是 Spring Boot 3.x + JDK 17,我更推荐直接用 9.x 系列,免得后面 agent 兼容出问题。

选版本时有一个很容易忽略的点:Agent、OAP Server、UI 这三个组件要尽量保持版本一致,或者至少大版本一致。比如 Agent 是 8.9.1,OAP 是 9.x,上报协议的差异可能让你看到“Agent connected”但数据迟迟不出来的现象。所以我的习惯是:到官网或镜像仓库一次性把同版本号的三个产物下载好,用多少版本就全用多少版本,不做混搭。

除了版本,还要留意 JDK 的兼容。SkyWalking 9.x 的 agent 我实测在 JDK 8、JDK 11、JDK 17 上都能跑,但不同小版本对高版本 JDK 的支持有差异,最稳妥的办法是先在一个测试环境里用一小段冒烟脚本验证,确认日志里出现 agent 启动成功的信息后再批量接入。

2.2 用 Docker Compose 一键拉起 OAP 和 UI

对于学习和单机演示,我最推荐的方式是用 Docker Compose 同时启动 OAP 和 UI,省去手动配置 ES 的麻烦,也方便随时重置环境。下面是我实际在本地跑过的编排文件,基于 9.6.0 版本,存储先用内置 H2 模式,适合快速看效果:

version: '3.8' services: oap: image: apache/skywalking-oap-server:9.6.0 container_name: skywalking-oap ports: - "11800:11800" - "12800:12800" environment: SW_STORAGE: h2 ui: image: apache/skywalking-ui:9.6.0 container_name: skywalking-ui depends_on: - oap ports: - "8080:8080" environment: SW_OAP_ADDRESS: http://oap:12800

启动命令很简单:docker compose up -d。启动完成后检查端口 11800 和 12800 是否监听,再打开http://localhost:8080,如果能出现 SkyWalking 的页面,说明环境已经起来了。

这里要特别说明两个端口的作用:11800 是 gRPC 端口,给 agent 上报数据用的;12800 是 HTTP 端口,给 UI 查询数据用的。javaagent 里配置的地址是host.docker.internal:11800或192.168.x.x:11800,而不是 localhost,因为 agent 运行在你的宿主机 Java 进程里,要从宿主机的视角连到容器里的 OAP。这个细节我碰到过不止一次,值得提前说。

2.3 存储引擎:演示用 H2,生产建议 Elasticsearch

SkyWalking 支持多种存储实现,包括内置的 H2、MySQL、PostgreSQL、Elasticsearch。切换方式很简单,在 OAP 的配置里设置SW_STORAGE环境变量,或者在 docker compose 的 environment 里指定。

我自己的建议是分阶段选择:

存储方式适用场景优点注意点
H2本地快速验证零依赖,启动最快数据易丢,不适合生产
MySQL / PostgreSQL测试环境或中小规模数据持久化,排查时可查 SQL高并发聚合查询性能一般
Elasticsearch生产环境聚合分析强,支持索引生命周期管理版本必须与 OAP 严格匹配

用 Elasticsearch 时要特别注意版本配套。SkyWalking 8.9.x 对应 ES 7.x 比较稳;9.6.0 对 ES 7 和 ES 8 都有兼容说明,但不同小版本依然有细微差异。我见过最典型的坑是:OAP 日志里不断出现 timeout,UI 上拓扑图空白,最后发现是 OAP 和 ES 的版本不匹配。所以如果生产用 ES,先去官方文档确认当前 OAP 版本的兼容矩阵,这一步比任何调优都重要。

3. Spring Boot 接入 Agent:三步搞定并验证

3.1 javaagent 到底对你的应用做了什么

在接入之前,最好先理解 Agent 的注入原理。SkyWalking Agent 是一个 jar 包,通过 Java 的-javaagent参数在 JVM 启动时被加载,在这个时机里,Agent 可以做字节码增强,也就是在类加载完成后、真正执行业务方法前,给代码“织入”一些额外的逻辑。比如你写的 Controller 方法本来只有 3 行代码,增强后 JVM 实际执行时会在方法开始和结尾多出两段埋点逻辑,用来记录耗时、捕获异常、传递 trace 上下文。

这个增强过程对你的业务代码是透明的,源代码不会被修改。这也是“无侵入”的真正含义:不是说不改代码,而是不改源码,只改运行时行为。实际使用时还要注意一点:因为 agent 会影响类加载和部分框架的初始化,极少数情况下会和某些字节码库冲突,所以上线前最好在测试环境完整跑一遍回归。

Agent 包本身不需要和 Spring Boot 应用一起打进 fat jar 里,它只需要存在于服务器上一个固定路径,JVM 启动时通过绝对路径引用即可。好处是升级 agent 时不需要重新发布业务应用,换版本只需要替换文件并重启服务。

3.2 启动命令怎么写:一个可以直接抄的示例

假设你的 Spring Boot 应用构建出来是order-service.jar,SkyWalking agent 解压后放在/opt/skywalking-agent。启动命令如下:

java -javaagent:/opt/skywalking-agent/skywalking-agent.jar \ -Dskywalking.agent.service_name=order-service \ -Dskywalking.collector.backend_service=192.168.1.100:11800 \ -jar order-service.jar

三个参数的作用分别是:-javaagent指定 agent 的 jar 路径;-Dskywalking.agent.service_name设置当前服务在监控平台里的名字,一般跟服务名保持一致;-Dskywalking.collector.backend_service指定 OAP 的 gRPC 地址,如果你的 OAP 就在本机,可以写localhost:11800。

如果你的服务用了nohup或 systemd 管理,注意把参数放在java和-jar之间,不要把-javaagent放在-jar后面,否则 JVM 会把它当成应用参数,agent 不会被加载。这是我见过最多的入门级错误。在 Spring Boot 应用里,如果你没有固定 agent 路径,也可以把它放到 IDE 各模块的 VM options 里,本地调试时效果一样。但生产环境我还是推荐统一用脚本管理,方便多实例批量修改配置。

3.3 接入成功的三个验证信号

接完 agent 后不要急着去看 UI,先在日志里确认三个信号。

第一个信号:启动日志中出现了SkyWalking agent started这一行,说明 JVM 层面已经成功加载 agent。第二个信号:日志中出现了服务名和 OAP 地址信息,比如 agent 在初始化时打印的配置摘要,说明后端地址配置生效了。第三个信号:访问一次业务接口后,UI 的 General Service 列表中出现order-service这个名字,并且服务指标有对应的请求数、响应时间数据。

如果前两个信号都出现了,但 UI 里看不到服务,大概率是网络问题:检查 11800 端口是否通、防火墙是否放行、agent 和 OAP 之间的 gRPC 协议是否匹配。如果第一个信号就缺失,说明 agent 参数根本没被识别,回头检查启动命令的顺序和路径。

一个小经验是,验证阶段可以临时把日志级别调低,或者在 agent 目录下打开调试日志,能看到 agent 每次上报的数据是成功还是失败。等确认链路通了再恢复默认日志级别,避免生产环境日志量过大。

4. 制造流量看真实监控数据:拓扑、链路、慢查询

4.1 准备一个带 MySQL 和 Redis 的示例服务

为了能真实地看到调用链,我准备了一个最简单的 Spring Boot 服务,它包含两个接口:一个正常查询,一个故意制造慢查询。服务里用到 MySQL 和 Redis,这样 SkyWalking 会自动对 JDBC 和 Redis 调用做埋点,呈现出一个完整的调用链结构。

核心代码大致如下:

@RestController public class OrderController { @Autowired private JdbcTemplate jdbcTemplate; @Autowired private StringRedisTemplate stringRedisTemplate; @GetMapping("/order/list") public List<Map<String, Object>> list() { List<Map<String, Object>> result = jdbcTemplate.queryForList( "select * from t_order order by id desc limit 10"); stringRedisTemplate.opsForValue().increment("order:view:count"); return result; } }

这里不需要任何 SkyWalking 相关的依赖或注解,agent 会自动识别 Spring MVC 的入口、JDBC 的执行、Redis 的操作,把它们作为链路中的 span 记录下来。这也是我想强调的一点:SkyWalking 的埋点覆盖是“通用组件级”的,你不需要为它写任何业务埋点代码。

4.2 人为制造慢查询和异常,数据才更有说服力

先把应用接好 agent 启动,然后用 curl 打几次请求,接下来就可以制造两个典型的“问题场景”。

第一个是慢查询。我在 SQL 里加个sleep(2),模拟一个执行 2 秒的 SQL。虽然业务里一般不会这么干,但对于验证监控非常有效:

jdbcTemplate.queryForList("select sleep(2)");

第二个是抛异常。写一个接口直接抛RuntimeException,再调用几次,用来验证 SkyWalking 对异常状态的标记。

制造完流量后,给 SkyWalking 一点时间聚合数据,通常几十秒到一两分钟,再去刷新 UI,就能看到之前生成的拓扑图和调用链数据。这里需要有点耐心,因为 OAP 默认刷新周期不是实时的,不要因为刚点完接口马上刷新没看到数据就觉得接失败了。

4.3 UI 里几个必看的核心页面怎么读

打开 UI 后,重点看四个页面。

第一个是拓扑图。它会把你采集到的服务画成一个节点,服务之间用线连接,线上的数字表示调用次数和平均响应时间。在示例里,你会看到order-service节点连到MySQL和Redis两个节点,一眼就能看出依赖关系。

第二个是链路追踪详情页。点开一条 trace,可以看到整个请求从入口 Controller 开始,经过 Service 方法、SQL 执行、Redis 操作,每个 span 都有开始时间、结束时间、耗时、状态和具体调用参数。慢查询的那个 span 会特别显眼,直接告诉你 2 秒耗在哪一步了,不用再靠猜。

第三个是服务指标页。里面有响应时间、吞吐量、成功率的时间走势图。我习惯先看成功率,再看响应时间,因为成功率崩了往往比响应时间升高更严重。

第四个是 JVM 指标页。它展示堆内存、GC 次数、线程数、CPU 使用率等信息。有一次我们排查线上 Full GC 频繁的问题,就是靠这里的数据快速锁定了堆参数配置不合理。

注意:UI 展示的数据经过了 OAP 的聚合,刷新会有延迟,通常几十秒级别,别拿它当实时的秒级日志用。如果需要更实时的追踪单次请求,优先看链路详情里的 trace 记录。

4.4 手动埋点:自动埋点覆盖不到时,用 API 补一段

常用组件之外,有时候你想单独统计某个核心方法的耗时,比如一个复杂的规则引擎计算。这时可以用 SkyWalking 提供的@Trace注解,或者直接调用TracingContext创建自定义 span。@Trace需要额外引入apm-toolkit-trace依赖,这个依赖不会影响线上运行逻辑,agent 会识别注解并自动生成 span,示例依赖如下:

<dependency> <groupId>org.apache.skywalking</groupId> <artifactId>apm-toolkit-trace</artifactId> <version>9.6.0</version> </dependency>

在目标方法上加@Trace后,调用链详情里就会出现对应方法节点,你还能给 span 加 tag 和日志;这样自动埋点覆盖不到的业务逻辑也能纳入监控。这个能力在生产环境很有用,比如对核心服务里的疑难方法单独加埋点,可以省掉后续反复加日志的环节。

5. 生产落地:采样率、告警和避坑清单

5.1 采样率与内存:决定 SkyWalking 能不能撑住大流量

如果你的服务 QPS 很高,默认把所有请求都上报链路会给 OAP 带来压力,也会让存储量暴增。SkyWalking agent 提供了采样配置,在agent/config/agent.config里有一个agent.sample_rate参数,默认是 1,表示 100% 采样。把它设置为 0.5 就是 50% 采样,设置为10000表示 1/10000 采样。

采样率不是越低越好,因为它会直接影响链路问题的发现概率。我实际生产的经验是:根据你的存储和 OAP 水位来调,如果 QPS 在 1000 以下,默认 100% 采样一般没问题;一旦单机 QPS 上几千,先关注 OAP 的 CPU 和磁盘写入量,再决定要不要降采样率。

同时要注意 agent 自身的资源占用。SkyWalking agent 在增强后的应用里会有少量 CPU 和内存消耗,对绝大多数业务来说可以忽略,但老旧的 JDK 8 机器上如果堆本身就很紧张,建议在测试环境先压测一波,确认额外内存开销可接受。

5.2 告警规则:把监控结果推送到你的工作群

SkyWalking 支持配置告警规则,默认的规则文件在 OAP 的config/alarm-settings.yml里。最常见的场景是服务响应时间超过阈值、成功率低于某个百分比、JVM 老年代使用率过高等。下面是我常用的一个精简配置:

rules: - rule-name: endpoint-avg-rt-over-1000 metric-name: endpoint_avg_response_time op: '>' threshold: 1000 period: 5 count: 3 message: Endpoint response time over 1000ms in last 5 minutes - rule-name: service-sla-below-90 metric-name: service_sla op: '<' threshold: 0.9 period: 10 count: 2 message: Service SLA below 90% in recent 10 minutes

配置里的period表示统计周期(分钟),count表示连续几个周期满足条件才触发告警,这样能有效避免偶发抖动导致误报。告警推送可以配置 webhook,SkyWalking 会 POST 一个 JSON 到你填的地址,你只要在后端服务里接收这个 JSON,再转成企业微信、钉钉或邮件消息推送即可。

生产环境我建议先把告警阈值稍微调宽,跑一两周拿到真实基线后再收紧,不然刚上线很容易被各种历史毛刺告警刷屏,反而让团队麻木。

5.3 我踩过的几个坑:Agent 不生效、数据断档、版本冲突

坑一:Agent 不生效。表现是启动日志没有SkyWalking agent started。根因通常是参数位置写错,或者路径里有空格。注意 shell 脚本中对路径加引号,-javaagent和-jar的顺序不要颠倒。

坑二:UI 能看到服务名,但拓扑图一直空白。大概率是 OAP 存储配置的问题,尤其是 H2 模式数据文件满了或者容器重启后数据丢失。如果用的 ES,检查索引是否创建成功、OAP 日志里有没有 elasticsearch 相关的异常。我遇到过 ES 集群版本是 8.x,但 OAP 配置里按 7.x 来初始化,导致 mapping 冲突,数据写入失败。

坑三:Agent 上报正常,但某些接口的 trace 缺一段。比如只有 Servlet 入口,没有 JDBC 的 span。这通常是 agent 版本和框架版本的兼容问题,查看官方文档确认你用的 Spring Boot 版本是否在支持列表内,必要时升级 agent。不要自己试图去改 agent 的埋点代码,维护成本会很高。

表面现象优先排查方向
启动日志无 agent 启动信息启动参数位置、路径、JDK 版本
Agent 启动成功但 UI 无服务gRPC 端口连通性、版本是否匹配
拓扑图正常但缺少组件依赖节点对应插件是否启用、框架是否在支持列表
告警不触发阈值、统计周期、webhook 地址是否可访问

5.4 最后的提醒:从监控到治理才是终点

把 SkyWalking 部署起来只是第一步。真正有价值的,是把它变成团队日常的工作习惯:每次发布前先看上一版本的性能基线,线上出现告警时不是先查代码,而是先打开链路看瓶颈点,然后让对应负责人去处理。我在好几个项目里验证过,一个配置得当的 APM 系统,能把跨服务问题从“大半天靠人肉翻日志”压缩到“十分钟内定位根因”,这个效率提升对团队来说是实打实的。

我个人在实际操作中的体验是:SkyWalking 的入门门槛不算高,真正容易翻车的地方全在细节上——版本配套、端口配置、采样策略、告警阈值。如果看到这里你正准备动手,我建议先按文章里的流程在本地把环境跑起来,把 demo 服务接入 agent,再故意制造一次慢查询,亲眼看到拓扑图和链路详情后,你对这套监控体系的信任感就有了。之后再去处理生产接入,心里就有底了。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/10 2:28:53

如何读懂 NPUSim 指令流水图:Perfetto 可视化操作与关键字段全解

如何读懂 NPUSim 指令流水图&#xff1a;Perfetto 可视化操作与关键字段全解 【免费下载链接】npu-simulator NPUSim&#xff08;全称NPU Simulator&#xff09;是一款面向算子开发场景的SoC级芯片仿真工具&#xff0c;用于分析运行在AI仿真器上的AI任务在各阶段的精度和性能数…

作者头像 李华
网站建设 2026/10/10 2:23:45

应用软件系统数据备份方案:实时、定期、阶段三档备份与恢复实操

简介&#xff1a;这份《应用软件系统数据备份方案》面向企业IT运维人员、系统管理员及信息化建设从业者&#xff0c;聚焦数据安全与业务连续性这一核心命题&#xff0c;帮助读者建立从备份等级划分到策略落地的完整认知框架。资源为单个docx文档&#xff0c;压缩包约15KB&#…

作者头像 李华
网站建设 2026/10/10 2:20:57

PS5串流实战:AnyPS5统一配置,局域网与远程调优全指南

先说个背景。我之前很长一段时间都靠串流把PS5接到屋里各种屏幕上玩——客厅电视、书房显示器、卧室平板&#xff0c;来回切换。折腾多了就会发现&#xff0c;真正麻烦的不是串流本身&#xff0c;而是每次换设备都要重新调协议、配参数、处理掉线&#xff0c;体验非常割裂。后来…

作者头像 李华
网站建设 2026/10/10 2:19:51

基于 BiLSTM 的微博情感四分类实战:数据处理、模型训练到 Web 部署

基于 BiLSTM 的微博情感四分类实战&#xff1a;数据处理、模型训练到 Web 部署 做舆情分析&#xff0c;最基础也最关键的一步&#xff0c;就是判断一条微博到底表达的是什么情绪。高兴还是愤怒&#xff0c;厌恶还是低落&#xff0c;如果能自动识别&#xff0c;对舆情监控、产品…

作者头像 李华