这是「微服务从踩坑到填坑」系列的第 3 篇。上篇我们搞定了服务发现,但调用链一长,排查问题就像破案。本篇用最短篇幅,把链路追踪的原理、落地和踩坑讲清楚。

一、为什么必须上链路追踪
拆成微服务后,一个请求可能穿过四五个服务。如果某接口变慢,你只能在每个服务的日志里搜关键词,手动拼出调用顺序——这就是灾难。

链路追踪的核心价值:用一个全局 TraceId 把一次请求的所有调用串起来,哪个环节慢、哪里报错,一图看清。

二、原理一句话
网关生成唯一的 TraceId,通过请求头(如 sw8)一路透传。每个服务处理时,把自己的耗时、状态包装成一个 Span,附上 TraceId 上报。后端系统按 TraceId 把 Span 拼成完整调用链。

所有操作对业务代码零侵入,靠字节码增强自动完成——这就是 SkyWalking 的做法。

三、SkyWalking 快速落地
3.1 后端:Docker Compose 一键起

version: '3.8'
services:
  elasticsearch:
    image: elasticsearch:7.17.6
    environment:
      - discovery.type=single-node
    ports:
      - "9200:9200"
  oap:
    image: apache/skywalking-oap-server:9.2.0
    environment:
      SW_STORAGE: elasticsearch
      SW_STORAGE_ES_CLUSTER_NODES: elasticsearch:9200
    ports:
      - "11800:11800"
      - "12800:12800"
    depends_on:
      - elasticsearch
  ui:
    image: apache/skywalking-ui:9.2.0
    ports:
      - "8080:8080"
    environment:
      SW_OAP_ADDRESS: http://oap:12800

3.2 服务接入:启动参数加个 Agent

java -javaagent:skywalking-agent.jar \
     -DSW_AGENT_NAME=order-service \
     -DSW_AGENT_COLLECTOR_BACKEND_SERVICES=localhost:11800 \
     -jar order-service.jar

重启后,UI 上立即出现拓扑、调用链、性能指标,不用写一行代码。

四、直接上干货:踩过的坑
TraceId 透传丢失
Spring Cloud Gateway 的 Netty 层可能没自动带上 TraceId,需在 Filter 里手动塞:
request.mutate().header(“sw8”, TracingContext.traceId());

存储爆炸
默认会采集所有端点,包括 /health、/actuator。在 agent.config 里排除:
plugin.http.exclude_url_paths=/health,/actuator/**

异步线程断了链
线程池任务丢失 Trace 上下文,用 ContextManager.wrap(executorService) 包一层解决。

插件版本兼容
中间件升级可能引发 Agent 插件不兼容,启动报错。要么降级中间件,要么在 agent 配置里关闭特定插件。

五、选型:为什么是 SkyWalking
Zipkin:要写代码埋点,UI 弱。

Jaeger:Go 友好,Java 生态集成不如 SkyWalking 平滑。

SkyWalking:Apache 项目,Java Agent 零侵入,自动埋点覆盖 Dubbo、Redis、MQ 等,性能损耗实测低于 5%,自带 UI 和告警。

一句话:不想改业务代码,就用 SkyWalking。

六、结尾
有了链路追踪,排障从小时级变成分钟级。但服务还是会挂,下篇我们聊如何用 Sentinel 限流熔断,让故障不扩散。

Logo

一站式 AI 云服务平台

更多推荐