霸王餐API日志链路追踪:OpenTelemetry自动注入与SkyWalking对比
一、业务痛点
吃喝不愁"霸王餐"API集群日调用量 8 亿次,高峰期 12w qps。一次"下单→风控→券核销→商家回调"链路跨越 7 个服务、3 个消息队列、2 个 DB。旧日志方案只有 RequestId,无法回答:
- 哪台容器慢?
- 哪段代码抛异常?
- 网络抖动还是 GC 抖动?
目标:零代码侵入、秒级采样、兼容现有 ELK,同时在 SkyWalking 与 OpenTelemetry 之间给出可落地的二选一方案。

二、技术选型指标
| 维度 | SkyWalking | OpenTelemetry | 备注 |
|---|---|---|---|
| Agent 字节码注入 | 自带 | 依赖 javaagent | 均支持 |
| 协议 | SW6 私有 | W3C Trace-Context | OT 更通用 |
| 后端存储 | ES/H2/BanyanDB | ES/Jaeger/自定义 | 公司统一 ES |
| 采样策略 | 静态 QPS | 动态概率 + Tail | OT 更细 |
| dashboard 告警 | 内置 | 需 Grafana | SW 省工作量 |
三、OpenTelemetry 自动注入实战
3.1 依赖版本
xml
<properties>
<opentelemetry.version>1.32.0</opentelemetry.version>
</properties>
<dependency>
<groupId>io.opentelemetry.javaagent</groupId>
<artifactId>opentelemetry-javaagent</artifactId>
<version>${opentelemetry.version}</version>
</dependency>
3.2 Dockerfile 一行注入
dockerfile
COPY opentelemetry-javaagent.jar /opt/agent.jar
ENV JAVA_TOOL_OPTIONS="-javaagent:/opt/agent.jar \
-Dotel.service.name=ba霸王餐-order \
-Dotel.traces.exporter=otlp \
-Dotel.exporter.otlp.endpoint=http://otel-collector:4317 \
-Dotel.instrumentation.common.default-enabled=true \
-Dotel.metrics.exporter=none"
3.3 自定义 Span:记录"券核销"耗时
java
package cn.juwatech.bawang.canal.service;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.context.Scope;
@Service
public class CouponService {
private static final Tracer tracer =
GlobalOpenTelemetry.getTracer("cn.juwatech.bawang.canal");
public void consume(String couponId, String userId) {
Span span = tracer.spanBuilder("coupon.consume")
.setAttribute("coupon.id", couponId)
.setAttribute("user.id", userId)
.startSpan();
try (Scope ignored = span.makeCurrent()) {
// 业务逻辑
doConsume(couponId);
span.setAttribute("result", "ok");
} catch (Exception e) {
span.recordException(e);
throw e;
} finally {
span.end();
}
}
}
3.4 采样规则动态配置
yaml
# otel-collector-config.yaml
processors:
probabilistic_sampler:
sampling_percentage: 5
tail_sampling:
policies:
- name: slow-span
type: latency
latency: {threshold_ms: 500}
四、SkyWalking 8.9 接入实录
4.1 镜像层打包
dockerfile
FROM apache/skywalking-java-agent:8.9.0-java11
COPY app.jar /app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
4.2 自定义层(@Trace 增强)
java
package cn.juwatech.bawang.canal.service;
import org.apache.skywalking.apm.toolkit.trace.Trace;
import org.apache.skywalking.apm.toolkit.trace.Tag;
import org.springframework.stereotype.Service;
@Service
public class RiskService {
@Trace(operationName = "risk.evaluate")
@Tag(key = "score", value = "returnedObj.score")
public RiskResult evaluate(String userId) {
// 风控逻辑
return new RiskResult(computeScore(userId));
}
}
4.3 日志绑定 TraceId
xml
<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36}
[%tid] - %msg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="CONSOLE"/>
</root>
</configuration>
[%tid] 由 apm-toolkit-logback-1.x 提供,直接输出 SkyWalking TraceId。
五、链路对比压测数据
环境:4C8G × 30 容器,2k 并发,持续 20min。
| 指标 | OpenTelemetry | SkyWalking |
|---|---|---|
| CPU 增加 | +6% | +5% |
| 延迟 P99 | +3 ms | +2 ms |
| 存储量/亿条 | 260 GB | 180 GB |
| 查询 Trace 完整率 | 99.2% | 99.5% |
结论:SW 存储压缩率更高;OT 在跨云、多语言场景更灵活。
六、采样与存储优化
6.1 OpenTelemetry Collector 级联
yaml
receivers:
otlp:
protocols:
grpc:
processors:
batch:
timeout: 1s
send_batch_size: 1024
exporters:
elasticsearch:
endpoints: ["http://es:9200"]
index: "otel-v2-%{+yyyy.MM.dd}"
service:
pipelines:
traces:
receivers: [otlp]
processors: [batch]
exporters: [elasticsearch]
6.2 SkyWalking ES 模板冷热分离
json
PUT _ilm/policy/sw7-trace
{
"policy": {
"phases": {
"hot": {"actions": {"rollover": {"max_size": "30GB"}}},
"warm": {"actions": {"shrink": {"number_of_shards": 1}}},
"cold": {"actions": {"searchable_snapshot": {"snapshot_repository": "backup"}}}
}
}
}
七、代码级排障案例
场景 :用户反馈"霸王餐下单 502"。
步骤:
- 在 Grafana 搜索
http.status_code=502; - 定位到
ba霸王餐-gateway实例10.244.6.89; - 点击 Trace,发现
risk.evaluateSpan 耗时 28s; - 查看同 Span 的
scoreTag,发现 Redis 命令EVALSHA超时; - 回滚 Redis Lua 脚本,502 归零。
全过程 3 分钟,无需登录容器。
八、灰度与回滚策略
- 按 Kubernetes Namespace 灰度:
otel-collector与sw-oap双跑,通过注解sidecar.skywalking.enable=false一键关闭。 - 回滚:
删除JAVA_TOOL_OPTIONS中的-javaagent即可,应用无感知。
九、后续演进
- 将 OpenTelemetry Metrics 接入 Prometheus,统一告警。
- eBPF + OT 实现网络 RTT 级别观测。
- 使用 SkyWalking Satellite 替换 sidecar,降低 20% CPU。
本文著作权归吃喝不愁app开发者团队,转载请注明出处!