在 SkyWalking 中,EntrySpan
、ExitSpan
和 LocalSpan
是 分布式链路追踪(Tracing) 的三种核心 Span 类型,它们分别表示不同的调用场景。理解它们的区别有助于更好地分析和监控分布式系统的调用链。
1. 什么是 Span?
在分布式追踪系统中,一个 Trace 代表一次完整的请求链路,而 Span 代表 Trace 中的一个具体操作。
- EntrySpan → 入口请求(外部请求进入本服务)
- ExitSpan → 出口请求(本服务调用外部服务)
- LocalSpan → 本地调用(内部逻辑处理,不涉及 RPC)
SkyWalking 通过这些 Span 记录 服务间的调用关系、执行时间、异常信息等,帮助分析系统性能和排查问题。
2. EntrySpan
(入口 Span)
📌 适用于: 处理外部请求(通常是 HTTP、RPC 等请求)进入 当前服务 的场景。
📍 代表: 该 Span 是 整个请求链的起点 或 某个服务的入口点。
🌟 示例
假设有一个 用户服务(UserService) 提供了一个 GET /user/{id}
的 API:
EntrySpan span = ContextManager.createEntrySpan("/user/{id}", null);
try {
// 处理请求逻辑
} finally {
ContextManager.stopSpan(span);
}
📌 应用场景:
- 处理 来自外部(如浏览器、客户端) 的请求
- RPC 服务提供者(如 Dubbo、gRPC 服务端)
- 消息队列消费者(如 Kafka 消费)
📌 示例 Trace
UserService [EntrySpan] <-- 用户请求进入
└──> OrderService [ExitSpan](发起远程调用)
📌 总结
- EntrySpan 代表当前服务是入口
- 通常和 HTTP 请求、RPC 请求相关
- 用于监控 API 请求耗时、错误率
3. ExitSpan
(出口 Span)
📌 适用于: 当前服务调用外部服务(下游服务) 的场景。
📍 代表: 当前服务作为调用者,请求其他微服务、数据库、缓存等。
🌟 示例
ExitSpan span = ContextManager.createExitSpan("/order/{id}", "order-service:8080");
try {
// 调用远程服务,如 HTTP、gRPC、数据库等
} finally {
ContextManager.stopSpan(span);
}
📌 应用场景:
- 调用其他微服务(REST、gRPC、Dubbo 调用)
- 调用外部数据库(如 MySQL、Redis、Elasticsearch)
- 调用第三方 API
📌 示例 Trace
UserService [EntrySpan] <-- 用户请求进入
└──> OrderService [ExitSpan](发起远程调用)
└──> PaymentService [EntrySpan]
📌 总结
- ExitSpan 代表当前服务是调用方
- 通常和 HTTP 请求、数据库访问、MQ 生产者相关
- 用于监控外部服务调用的性能
4. LocalSpan
(本地 Span)
📌 适用于: 当前服务内部逻辑的追踪,不涉及远程调用。
📍 代表: 本地代码执行的逻辑,不涉及 RPC、HTTP 请求。
🌟 示例
LocalSpan span = ContextManager.createLocalSpan("parseUserData");
try {
// 本地数据处理,不涉及网络
} finally {
ContextManager.stopSpan(span);
}
📌 应用场景:
- 记录 本地方法调用(如数据处理、缓存操作)
- 监控 计算密集型任务(如日志解析、大量计算)
- 记录 MQ 消费者内部逻辑
📌 示例 Trace
UserService [EntrySpan] <-- 用户请求进入
└──> 解析用户数据 [LocalSpan](本地计算)
└──> OrderService [ExitSpan](远程调用)
📌 总结
- LocalSpan 代表当前服务内部逻辑
- 不会涉及远程调用
- 用于监控本地计算、日志处理等
5. 综述:三种 Span 的区别
Span 类型 | 适用于 | 示例 | 主要作用 |
---|---|---|---|
EntrySpan | 服务入口(接收请求) | 处理 HTTP、RPC 请求 | 记录 外部请求进入 |
ExitSpan | 调用外部服务 | 调用数据库、HTTP 请求、MQ 生产 | 记录 远程请求发送 |
LocalSpan | 本地逻辑处理 | 计算、日志处理、缓存操作 | 记录 本地代码执行 |
6. 典型的 Trace 示例
假设一个用户请求进入 UserService,然后:
- UserService 作为入口(
EntrySpan
) - 调用 OrderService(
ExitSpan
) - OrderService 作为入口(
EntrySpan
) - 调用 MySQL 数据库(
ExitSpan
) - UserService 内部进行数据解析(
LocalSpan
)
完整链路如下:
UserService [EntrySpan] <-- 用户请求进入
└──> 解析用户数据 [LocalSpan] (本地计算)
└──> OrderService [ExitSpan] <-- 远程调用
└──> OrderService [EntrySpan] <-- 处理订单
└──> MySQL [ExitSpan] <-- 查询数据库
7. 总结
Span 类型 | 作用 | 典型场景 |
---|---|---|
EntrySpan | 请求进入当前服务 | HTTP API、RPC 服务、MQ 消费者 |
ExitSpan | 当前服务调用外部服务 | 远程 API、数据库、消息队列 |
LocalSpan | 当前服务的本地逻辑 | 计算、缓存、日志 |
如何选择?
✅ 如果是 外部请求进入本服务(API 请求、RPC 调用)➡ EntrySpan
✅ 如果是 本服务调用外部服务(HTTP、数据库、MQ)➡ ExitSpan
✅ 如果是 本地逻辑执行(计算、日志处理、缓存)➡ LocalSpan
希望这个解释能帮你理解 SkyWalking 的三种 Span!如果有更具体的使用场景,可以告诉我,我可以帮你更详细分析 😊 🚀