某金融科技公司的支付系统曾陷入严重的故障排查困境:用户反馈 "转账失败",运维人员在 ELK 中找到支付服务的错误日志,却无法确定该请求的上游调用来源;在 Prometheus 中发现接口响应时间突增,却不知道是哪个下游服务导致延迟;最终花费 4 小时才定位到问题 ------ 第三方风控服务超时,但因调用链断裂,中间环节的异常未被关联。这正是微服务可观测性的核心痛点:追踪、日志、指标三者孤立,缺乏统一的全链路关联,故障排查效率极低。本文将以 SkyWalking 为核心,结合 Elasticsearch、Prometheus,构建 "分布式追踪为骨架、日志为细节、指标为预警" 的全链路可观测性体系,实现从 "发现问题" 到 "定位根因" 的端到端闭环。
一、微服务全链路可观测性的核心痛点与价值
- 传统可观测性方案的三大瓶颈
在微服务架构中,仅靠独立的日志、指标或追踪工具,无法满足故障排查需求:
- 调用链断裂:跨服务调用时,traceId传递丢失(如 HTTP 调用未携带 Header、消息队列消费未传递上下文),导致调用链无法串联,无法追踪请求完整路径;
- 数据孤立:日志中包含traceId,但无法直接关联到对应的调用链;指标显示 "接口错误率升高",却无法定位到具体的异常调用实例;
- 排查效率低:故障发生时,需在 ELK(查日志)、Prometheus(看指标)、Zipkin(追调用链)多个工具间切换,手动关联数据,排查时间从小时级起步;
- 业务关联性弱:传统追踪工具仅关注 "技术指标"(如响应时间、调用次数),缺乏与 "业务指标"(如订单号、用户 ID)的关联,无法快速定位 "某笔特定订单的调用异常"。
金融支付系统的典型困境:
当一笔转账请求失败时,日志中仅记录 "转账失败,订单号:PAY20251208001",但无法通过订单号找到对应的调用链;调用链中显示 "风控服务调用超时",却无法直接查看该次调用的详细日志,需手动复制traceId到 ELK 中查询。
- 全链路可观测性的核心价值
一套完善的全链路可观测性体系,需实现 "追踪、日志、指标" 的深度融合,其核心价值体现在:
- 全链路追踪:从用户请求入口(网关)到下游所有服务(订单、支付、风控),完整串联调用链,可视化展示请求路径、耗时分布、异常节点;
- 数据关联融合:通过traceId/spanId将 "调用链""日志""指标" 三者关联 ------ 点击调用链中的某个span,可直接查看对应的日志;指标异常时,自动关联最近的异常调用链;
- 业务上下文穿透:在追踪数据中嵌入业务标识(如订单号、用户 ID),支持通过 "订单号" 直接查询对应的调用链与日志,实现 "业务问题→技术根因" 的快速映射;
- 智能故障定位:基于调用链拓扑,自动分析异常传播路径(如 "风控服务超时→支付服务重试→订单服务回滚"),定位故障源头,而非仅看到表面的异常节点;
- 性能瓶颈分析:通过调用链的耗时分布,识别性能瓶颈(如 "数据库查询耗时占比 80%""第三方接口响应慢"),指导性能优化。
- 主流分布式追踪工具对比
|-------------|-------------------------|----------|-----------------------|----------------|----------------|
| 工具 | 核心优势 | 部署复杂度 | 生态融合度 | 业务上下文支持 | 适用场景 |
| SkyWalking | 中文友好、支持多语言、全链路拓扑 | 中 | 高(支持 ELK/Prometheus) | 强(支持自定义标签) | 中大型微服务、多语言架构 |
| Zipkin | 轻量、部署简单、OpenTracing 兼容 | 低 | 中(需手动集成日志) | 弱(仅基础标识) | 小型微服务、快速试点 |
| Jaeger | 云原生友好、K8s 集成度高 | 中 | 中(支持 Grafana) | 中(支持 baggage) | 云原生微服务、K8s 环境 |
| Dynatrace | AI 驱动根因分析、全栈监控 | 低(SaaS) | 高(自动关联日志 / 指标) | 强(自动识别业务标识) | 企业级关键业务、高预算场景 |
二、SkyWalking 核心原理与架构解析
- SkyWalking 的核心概念
SkyWalking 是一款开源的分布式追踪、APM 工具,基于字节码增强技术实现无侵入式监控,核心概念包括:
- Trace(调用链):一个用户请求从入口到出口的完整调用路径,由多个Span组成;例如 "用户下单" 请求,包含 "网关→订单服务→库存服务→支付服务" 的完整链路;
- Span(调用跨度):调用链中的最小单元,代表一次服务间调用或一个本地方法执行;每个Span包含traceId(所属调用链 ID)、spanId(自身 ID)、parentSpanId(父调用 ID);
- 服务(Service):微服务实例的逻辑分组,如 "order-service""payment-service";
- 服务实例(Service Instance):服务的具体部署实例,如 "order-service-10.0.0.1:8080";
- 端点(Endpoint):服务提供的具体接口或方法,如 "/order/create""com.xxx.payment.service.PaymentServiceImpl#pay";
- 标签(Tag):附加在Span上的键值对,用于存储业务上下文(如orderNo=PAY20251208001)或技术信息(如http.method=POST);
- 日志关联:通过traceId和spanId将日志与Span绑定,实现 "调用链→日志" 的跳转;
- 指标关联:基于Service/Endpoint维度,自动生成性能指标(如 QPS、响应时间、错误率),与 Prometheus 兼容。
- SkyWalking 核心架构
SkyWalking 采用 "agent + 后端服务 + 存储 + UI" 的分层架构,支持多语言、多协议接入:
- Agent 层:无侵入式探针,部署在微服务实例中,负责采集调用链、日志、指标数据;
- Java Agent:通过字节码增强(Instrumentation)技术,自动拦截 HTTP、Dubbo、Spring Cloud 等调用,无需修改业务代码;
- 其他语言 Agent:支持 Go、Python、Node.js 等语言,通过 SDK 或框架集成实现数据采集;
- Backend 层:后端服务,负责接收 Agent 上报的数据,进行清洗、分析、聚合;
- OAP Server(Observability Analysis Platform):核心分析引擎,分为接收层(Receiver)、分析层(Analyzer)、存储层(Storage);
- Alert Manager:告警管理模块,基于指标或调用链异常触发告警;
- Storage 层:持久化存储,支持 Elasticsearch、MySQL、TiDB 等;推荐使用 Elasticsearch,满足高吞吐、高查询性能需求;
- UI 层:Web 可视化界面,提供调用链查询、服务拓扑、仪表盘、日志查看等功能;
- 生态集成层:与 ELK、Prometheus、Grafana 等工具集成,实现数据互通(如 SkyWalking 调用链跳转至 Kibana 日志)。
核心数据流转流程:
- 微服务启动时,加载 SkyWalking Agent;
- Agent 拦截服务调用(如 HTTP 请求、Dubbo 调用),自动生成traceId/spanId,采集调用耗时、状态等信息;
- Agent 将调用链、日志、指标数据异步上报至 OAP Server;
- OAP Server 对数据进行分析(如计算接口 QPS、错误率,构建服务拓扑),并存储到 Elasticsearch;
-
用户通过 SkyWalking UI 查询调用链、查看服务拓扑,或通过集成工具(如 Grafana)查看指标。
-
无侵入式追踪的实现原理
SkyWalking Java Agent 的无侵入式追踪,基于 Java Instrumentation 技术实现,核心步骤:
- Agent 加载:通过 JVM 参数-javaagent:/path/to/skywalking-agent.jar指定 Agent 包,JVM 启动时优先加载 Agent;
- 字节码增强:Agent 在类加载时(ClassFileTransformer),对目标类(如 Spring MVC 的DispatcherServlet、Dubbo 的Invoker)进行字节码修改,插入追踪逻辑;
- 例如:拦截DispatcherServlet#doDispatch方法,在请求处理前生成Span,处理后记录耗时并上报;
- 上下文传递:跨服务调用时,Agent 自动将traceId/spanId放入调用协议的 Header(如 HTTP 的sw8 Header、Dubbo 的attachment),下游服务接收后解析上下文,继续延伸调用链;
- 避免性能影响:Agent 采用异步上报(队列 + 线程池),数据压缩传输,对业务服务的性能影响控制在 5% 以内。
三、实战部署:SkyWalking 全链路追踪体系搭建
- 环境准备
- 基础环境:JDK 11+(Agent 支持 JDK 8-21)、Docker(用于部署 Elasticsearch、SkyWalking OAP);
- 存储需求:Elasticsearch 7.x(推荐 7.17 版本,与 SkyWalking 兼容性最佳);
- 微服务框架:Spring Cloud Alibaba 2022.0.0.0(或 Spring Boot 2.7+);
- 工具版本:SkyWalking 9.7.0(最新稳定版)、Elasticsearch 7.17.0。
- 部署 Elasticsearch(存储层)
SkyWalking 的调用链、日志、指标数据需存储在 Elasticsearch 中,采用 Docker Compose 部署:
yaml取消自动换行复制
启动 Elasticsearch:
bash取消自动换行复制
docker-compose -f docker-compose-es.yml up -d
验证启动:访问http://localhost:9200,返回ES集群信息即成功
- 部署 SkyWalking OAP 与 UI(后端与可视化层)
同样使用 Docker Compose 部署 SkyWalking OAP Server 与 Web UI:
yaml取消自动换行复制
启动 SkyWalking:
bash取消自动换行复制
确保ES网络已存在
docker network inspect skywalking-network || docker network create skywalking-network
启动OAP与UI
docker-compose -f docker-compose-skywalking.yml up -d
验证启动:访问http://localhost:8080,进入SkyWalking UI即成功(默认无账号密码)
- 微服务集成 SkyWalking Agent(数据采集层)
Spring Boot 微服务集成 SkyWalking Agent,实现无侵入式追踪,核心步骤:
4.1 下载 SkyWalking Agent
从 SkyWalking 官网(https://skywalking.apache.org/downloads/)下载 9.7.0 版本的 Agent 包,解压后得到skywalking-agent目录,核心文件包括:
- agent.jar:Agent 核心包;
- config/agent.config:Agent 配置文件;
- plugins/:各类框架的拦截插件(如 Spring Cloud、Dubbo、MySQL)。
4.2 配置 Agent(agent.config)
修改config/agent.config,关键配置如下:
properties取消自动换行复制
1. 服务名称(将在SkyWalking UI中显示,建议与Spring应用名一致)
agent.service_name=${SW_AGENT_NAME:order-service}
2. OAP Server地址(Agent上报数据的地址)
collector.backend_service=${SW_AGENT_COLLECTOR_BACKEND_SERVICES:127.0.0.1:11800}
3. 日志集成:将日志中的traceId/spanId上报至SkyWalking(需配合Logback/Log4j2配置)
plugin.toolkit.log.grpc.reporter.server_host=${SW_GRPC_LOG_SERVER_HOST:127.0.0.1}
plugin.toolkit.log.grpc.reporter.server_port=${SW_GRPC_LOG_SERVER_PORT:11800}
plugin.toolkit.log.grpc.reporter.max_message_size=${SW_GRPC_LOG_MAX_MESSAGE_SIZE:10485760}
4. 采样率配置(生产环境建议100%,测试环境可降低)
agent.sample_n_per_3_secs=${SW_AGENT_SAMPLE:10000} # 每秒采样10000个请求(即100%)
5. 业务标签:自动采集HTTP请求参数(如orderNo)作为Span标签(可选)
plugin.http.http_params_length=${SW_HTTP_PARAMS_LENGTH:1024}
4.3 集成 Logback 日志(关联日志与调用链)
为了让日志中包含traceId/spanId,并能在 SkyWalking UI 中查看日志,需修改 Logback 配置(logback-spring.xml):
- 引入 SkyWalking 日志依赖(pom.xml):
xml取消自动换行复制
walking kit-logback-1.x</artifactId>
<version>9.7.0</version>
</dependency>
- 配置 Logback 输出traceId/spanId:
xml取消自动换行复制
<conversionRule conversionWord="spanId" converterClass="org.apache.skywalking.apm.toolkit.log.logback.v1.x.SpanIdConverter"/>
. 控制台输出(开发环境):包含traceId/spanId -->
SOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%traceId] [%spanId] [%level] %logger{50} - %msg%n </encoder>
</appender>
- 日志上报至SkyWalking(通过gRPC):支持在UI中查看日志 -->
YWALKING_LOG" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender">
{yyyy-MM-dd HH:mm:ss.SSS} [%level] %logger{50} - %msg%n </encoder>
</appender>
- 全局日志级别:INFO,同时输出到控制台与SkyWalking -->
INFO">
ender-ref ref="CONSOLE"/>
ender-ref ref="SKYWALKING_LOG"/>
</root>
>
4.4 启动微服务并加载 Agent
通过 JVM 参数指定 Agent 路径,启动 Spring Boot 微服务:
bash取消自动换行复制
java -javaagent:/path/to/skywalking-agent/agent.jar \
-Dskywalking.agent.service_name=order-service \ # 服务名(覆盖agent.config配置)
-Dskywalking.collector.backend_service=127.0.0.1:11800 \ # OAP地址
-jar order-service-1.0.0.jar
验证集成效果:
- 访问微服务接口(如http://localhost:8081/order/create);
- 查看控制台日志,确认包含traceId/spanId(如2025-12-08 15:30:00.123 [8f7e6d5c4b3a210...] [a1b2c3d4e5f6...] [INFO] ...);
- 进入 SkyWalking UI → 追踪 → 搜索traceId,确认调用链已被采集。
四、全链路追踪核心功能实战
- 调用链查询:可视化请求完整路径
SkyWalking UI 提供强大的调用链查询功能,支持通过traceId、服务名、端点名、时间范围等多维度筛选:
1.1 基础调用链查询
- 进入 SkyWalking UI → 左侧菜单 "追踪";
- 筛选条件设置:
- 服务名:选择 "order-service";
- 端点名:选择 "/order/create";
- 时间范围:选择 "最近 10 分钟";
- 状态:选择 "成功" 或 "失败";
- 点击 "搜索",展示符合条件的调用链列表;
- 点击某条调用链,进入详情页,查看:
- 调用路径:从网关(如 spring-cloud-gateway)→ 订单服务 → 库存服务 → 支付服务的完整链路;
- 耗时分布:每个span的耗时(如 "订单服务→库存服务" 调用耗时 200ms);
- 状态标识:失败的span以红色标注,鼠标悬停可查看异常信息(如 "第三方风控服务超时");
- 标签信息:每个span的标签(如http.method=POST、db.instance=order-db)。
1.2 业务标识查询:通过订单号定位调用链
传统追踪工具仅支持通过traceId查询,SkyWalking 支持通过业务标识(如订单号)查询调用链,需在代码中手动注入业务标签:
- 注入业务标签(Spring Boot 服务):
java取消自动换行复制
import org.apache.skywalking.apm.toolkit.trace.TraceContext;
import org.apache.skywalking.apm.toolkit.trace.Tag;
import org.apache.skywalking.apm.toolkit.trace.Tags;
@RestController
@RequestMapping("/order")
public class OrderController {
@PostMapping("/create")
// 通过@Tag注解将订单号作为Span标签
@Tags({@Tag(key = "orderNo", value = "{request.orderNo}"), @Tag(key = "userId", value = "{request.userId}")})
public OrderDTO createOrder(@RequestBody OrderCreateRequest request) {
// 手动将订单号放入MDC,便于日志关联
MDC.put("orderNo", request.getOrderNo());
try {
return orderService.createOrder(request);
} finally {
MDC.clear();
}
}
}
- 通过订单号查询调用链:
- 进入 SkyWalking UI → 追踪 → 点击 "高级搜索";
- 标签筛选:添加条件 "orderNo = PAY20251208001";
- 点击 "搜索",直接定位到该订单对应的调用链,无需记忆traceId。
- 服务拓扑图:可视化微服务依赖关系
SkyWalking 自动构建服务拓扑图,展示服务间的调用关系、调用量、成功率,帮助快速识别依赖瓶颈:
2.1 查看全局拓扑
- 进入 SkyWalking UI → 左侧菜单 "拓扑图";
- 时间范围:选择 "最近 1 小时";
- 层级筛选:选择 "服务"(展示服务级拓扑)或 "实例"(展示实例级拓扑);
- 拓扑图解读:
- 节点:每个节点代表一个服务(如 "order-service""stock-service"),节点大小代表调用量;
- 边:服务间的调用关系,边的粗细代表调用量,颜色代表成功率(绿色:成功率 > 99%,黄色:95%-99%,红色:5%);
- 悬停信息:鼠标悬停在节点上,显示服务的 QPS、平均响应时间、错误率;悬停在边上,显示调用量、平均耗时。
2.2 故障定位:通过拓扑图快速识别异常服务
当支付服务调用第三方风控服务超时,拓扑图会呈现明显异常:
- 支付服务(payment-service)到风控服务(risk-control-service)的边显示红色,且标注 "错误率 100%";
- 点击该边,可查看具体的异常信息(如 "超时时间 5000ms");
- 进一步点击 "查看调用链",直接定位到超时的span,无需逐个服务排查。
- 日志与调用链联动:从追踪到日志的一键跳转
SkyWalking 支持 "调用链→日志" 的直接联动,无需在多个工具间切换,大幅提升排查效率:
3.1 在调用链中查看关联日志
- 进入调用链详情页,找到某个span(如 "支付服务调用风控服务");
- 点击该span右侧的 "日志" 标签,展示该span对应的所有日志;
- 日志包含完整的上下文信息(如traceId、spanId、订单号),可直接查看异常堆栈信息;
- 若日志量较大,可通过 "日志级别"(INFO/ERROR)筛选,快速定位错误日志。
3.2 日志与调用链的双向联动
通过 SkyWalking 与 ELK 的集成,实现双向跳转:
- SkyWalking→Kibana:在调用链详情页,点击 "查看 Kibana 日志",自动跳转到 Kibana 并筛选该traceId的所有日志;
- 配置方法:修改 SkyWalking OAP 的application.yml,添加 Kibana 地址与日志查询模板:
yaml取消自动换行复制
ui:
settings:
log:
kibana:
address: http://localhost:5601
queryTemplate: "/app/discover#/?_g=(time:(from:now-1h%2Fm,to:now))&_a=(columns:!(),filters:!((query:(match:(traceId:(query:'{traceId}',type:phrase)))),index:'microservice-log-*',interval:auto,query:(language:kuery,query:''),sort:!((@timestamp,desc)))"
- Kibana→SkyWalking:在 Kibana 日志中,点击traceId字段,自动跳转到 SkyWalking 对应的调用链详情页;
- 配置方法:在 Kibana 中为traceId字段添加 "链接模板",指向 SkyWalking UI 的调用链查询地址:
plaintext取消自动换行复制
- 指标与调用链联动:从指标异常到根因定位
SkyWalking 自动将调用链数据聚合为指标(如 QPS、响应时间、错误率),当指标异常时,可直接关联到对应的调用链:
4.1 基于指标触发告警并关联调用链
- 配置指标告警:
- 进入 SkyWalking UI → 左侧菜单 "告警" → "告警规则" → "创建规则";
- 规则配置:
- 指标类型:选择 "端点指标";
- 指标名称:选择 "平均响应时间";
- 服务名:选择 "payment-service";
- 端点名:选择 "/payment/transfer";
- 阈值条件:"> 1000ms"(持续 1 分钟);
- 告警通知:配置钉钉 / 邮件通知,包含 "查看异常调用链" 的链接;
- 指标异常触发告警:
- 当/payment/transfer接口平均响应时间超过 1000ms,触发告警;
- 告警通知中包含 "查看异常调用链" 的链接,点击后直接跳转到 SkyWalking 的调用链查询页面,筛选出该时间段内的所有慢调用;
- 定位根因:
- 在慢调用链列表中,查看每个调用链的耗时分布,发现 "调用第三方银行接口" 的span耗时占比 90%;
- 进一步查看该span的日志,发现 "银行接口返回超时错误",确认根因为第三方服务延迟。
4.2 集成 Prometheus 实现跨工具指标联动
SkyWalking 支持将指标导出到 Prometheus,通过 Grafana 展示,并关联到 SkyWalking 的调用链:
- 配置 SkyWalking 指标导出到 Prometheus:
- 修改 SkyWalking OAP 的application.yml,启用 Prometheus exporter:
yaml取消自动换行复制
prometheus:
exporter:
enabled: true
port: 9090 # Prometheus采集端口
metrics_path: /metrics
- Prometheus 配置采集 SkyWalking 指标:
- 在prometheus.yml的scrape_configs中添加:
yaml取消自动换行复制
- job_name: 'skywalking-metrics'
static_configs:
- targets: ['skywalking-oap:9090']
- Grafana 配置仪表盘并关联调用链:
- 在 Grafana 中创建基于 SkyWalking 指标的仪表盘(如 "支付服务接口性能");
- 为 "平均响应时间" 图表添加 "链接",指向 SkyWalking 的调用链查询页面,筛选该时间段内的慢调用:
plaintext取消自动换行复制
http://localhost:8080/trace?traceId=\&serviceName=payment-service\&endpointName=/payment/transfer\&startTime={{startTime}}&endTime={{endTime}}&status=slow
五、生产环境最佳实践与性能优化
- 调用链采样策略:平衡性能与排查需求
在高并发生产环境中,100% 采样会导致 Agent 上报数据量过大,影响服务性能,需制定合理的采样策略:
1.1 常见采样策略对比
|---------|----------------------------|--------------------------|-----------------------|
| 采样策略 | 核心逻辑 | 适用场景 | 优缺点 |
| 全量采样 | 所有请求都生成调用链 | 低并发服务(如后台管理系统)、关键业务(支付) | 排查全面,但高并发下性能影响大 |
| 固定速率采样 | 每秒采样 N 个请求(如 1000 个 / 秒) | 中高并发服务(如订单服务) | 性能影响可控,但低流量时可能漏采关键请求 |
| 按比例采样 | 按百分比采样(如 10%) | 非关键业务服务(如商品浏览) | 配置简单,但高并发下采样量仍可能过大 |
| 基于规则采样 | 仅采样异常请求(错误 / 慢调用)+ 少量正常请求 | 高并发核心服务(如网关、支付) | 性能影响最小,关键故障不遗漏 |
1.2 生产环境推荐配置(基于规则采样)
修改 SkyWalking Agent 的agent.config:
properties取消自动换行复制
1. 基础采样:每秒采样100个正常请求(避免数据量过大)
agent.sample_n_per_3_secs=${SW_AGENT_SAMPLE:300} # 3秒采样300个 → 1秒100个
2. 异常请求强制采样:错误请求100%采样
plugin.jdk.httpclient.sample_error=true
plugin.spring.mvc.sample_error=true
plugin.dubbo.sample_error=true
3. 慢调用强制采样:耗时超过500ms的请求100%采样
plugin.jdk.httpclient.slow_threshold=${SW_SLOW_THRESHOLD:500}
plugin.spring.mvc.slow_threshold=${SW_SLOW_THRESHOLD:500}
plugin.dubbo.slow_threshold=${SW_SLOW_THRESHOLD:500}
- 调用链上下文传递:避免调用链断裂
跨服务调用或异步处理时,若traceId/spanId传递丢失,会导致调用链断裂,需确保全链路上下文传递:
2.1 HTTP 调用上下文传递(Spring Cloud)
SkyWalking Agent 自动拦截 Spring Cloud OpenFeign、RestTemplate 的 HTTP 调用,在 Header 中添加sw8协议头(包含traceId/spanId),无需手动配置;若使用自定义 HTTP 客户端(如 OkHttp),需手动传递 Header:
java取消自动换行复制
public class CustomHttpClient {
public String callRiskControlService(String orderNo, String traceId, String spanId) {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("http://risk-control-service/risk/check?orderNo=" + orderNo)
// 手动添加SkyWalking上下文Header
.addHeader("sw8", "1-" + traceId + "-" + spanId + "-1-1")
.build();
try (Response response = client.newCall(request).execute()) {
return response.body().string();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
2.2 消息队列上下文传递(Kafka/RabbitMQ)
消息生产者发送消息时,需将traceId/spanId放入消息头;消费者消费消息时,从消息头中解析上下文并传递给 SkyWalking Agent:
- Kafka 生产者传递上下文:
java取消自动换行复制
import org.apache.skywalking.apm.toolkit.trace.TraceContext;
import org.apache.kafka.clients.producer.ProducerRecord;
@Service
public class KafkaProducerService {
@Autowired
private KafkaTemplateafkaTemplate;
public void sendOrderMessage(String orderNo, String message) {
// 从SkyWalking上下文获取traceId/spanId
String traceId = TraceContext.traceId();
String spanId = TraceContext.spanId();
// 创建ProducerRecord,添加上下文Header
ProducerRecord String> record = new ProducerRecord", message);
record.headers().add("sw8-traceId", traceId.getBytes());
record.headers().add("sw8-spanId", spanId.getBytes());
// 发送消息
kafkaTemplate.send(record);
}
}
- Kafka 消费者传递上下文:
java取消自动换行复制
// 从消息Header中解析traceId/spanId
String traceId = new String(record.headers().lastHeader("sw8-traceId").value());
String spanId = new String(record.headers().lastHeader("sw8-spanId").value());
// 将上下文传递给SkyWalking Agent
TraceContext.continued(traceId, spanId);
try {
// 处理消息逻辑
orderService.processOrder(record.value());
} finally {
// 清除上下文,避免线程复用导致数据污染
TraceContext.clear();
}
}