SkyWalking:Java 接入、调用链与运行维护
SkyWalking 通过应用探针和遥测数据分析服务调用。它可以把订单入口、库存请求和数据库操作关联到同一条 Trace,再按服务与端点汇总请求量、耗时和错误。查看慢请求时,既能看到调用关系,也能展开具体的等待位置。
APM 的价值取决于接入完整度。需要观测的框架是否有插件、调用上下文能否跨进程传播、哪些数据被采样、查询窗口是否包含请求,这些条件会直接影响图上出现的内容。
组件与调用对象怎样对应
业务流量和遥测上报是两条路径
Agent 随应用进程加载,在受支持的调用点创建 Span。OAP 接收数据并分析服务、实例、端点和拓扑,再写入存储;UI 通过 OAP 查询。业务请求不会经过 OAP 转发,OAP 暂时不可达时应用通常仍可响应,但探针的缓冲、日志和资源开销仍需观察。
Horizon UI 的管理操作还会访问 OAP 的管理端口,它具有比查询更高的权限。生产网络要分别限制 Agent、查询用户、管理用户和存储访问,不能因为都属于观测组件就全部互通。
Service、Instance、Endpoint 与 Trace
Service: checkout
├── Instance: checkout-lab-1
└── Endpoint: GET:/checkout
└── Trace
├── checkout 的 Segment
│ ├── Entry Span:接收请求
│ └── Exit Span:调用 inventory
└── inventory 的 Segment
└── Entry Span:处理库存请求Service 是稳定的逻辑服务名;Instance 区分同一服务的运行实例;Endpoint 是可聚合的操作名称。发布一次就更换 Service 名会打断历史比较;多个副本复用 Instance 名则会混合实例数据。含业务 ID 的路径应归一化到路由模板,避免生成大量端点。
Trace 表示一次分布式执行,Span 表示其中一个被观测的操作。Entry、Exit 和 Local 分别描述进入当前服务、访问外部服务和进程内操作。SkyWalking 的 Segment 组织一组本地 Span,跨进程或跨线程通过引用连接,不能假设一个请求在一个进程中永远只有一个 Segment。对象定义见 SkyWalking 核心概念。
HTTP 插件把追踪上下文写入请求头,下游插件提取后接续调用。SkyWalking 的 sw8 与 W3C traceparent 不是可以互换的字段名;不同探针、代理或网关之间需要对应协议支持。若网关删除传播头,下游可能形成另一条 Trace。协议见 SkyWalking 上下文传播。
插件、SDK 与其他观测系统
自动探针适合覆盖受支持框架的 HTTP、RPC、数据库、消息和常见异步调用。自定义协议、内部计算阶段或特殊线程切换可能需要 SDK;无插件覆盖的代码不会凭空出现在调用树里。
OpenTelemetry 提供另一套仪表化和传输体系。接入前核对 OAP 对该信号、协议与字段的接收支持,避免把“支持 OTLP”理解为所有 OTel 指标和日志都按同样方式映射。相关入口见 OpenTelemetry Trace 接收。同一个应用叠加多个自动插桩 Agent 还可能产生重复 Span 或字节码冲突,应选择明确的接入方式并做兼容测试。
SkyWalking 可以从调用数据生成 APM 指标,但业务计数、基础设施指标和外部探测仍应按实际需求接入。日志用于查看事件内容,指标适合观察整体趋势,Trace 用于拆解一次执行;三者可以关联,保留与采样策略则分别设置。
部署环境并给两个 Java 服务接入 Agent
固定配套版本
下载双服务实验工程。需要 Linux Bash、openssl 和 Docker Compose v2,建议为 Docker 至少留出 10GB 可用内存。全部数据放入新建的 skywalking-lab 目录,不挂载已有数据库或应用目录。
| 组件 | 实验版本 | 作用 |
|---|---|---|
| OAP | 11.0.0 | 接收、分析与查询 |
| Horizon UI | 1.0.0 | 查询与受控管理界面 |
| BanyanDB | 0.11.0 | 保存指标与追踪数据 |
| Java Agent | 9.6.0 | 自动插桩 |
| 应用 | Java 17、Spring Boot 3.5.3 | 演示已选插件的接入 |
服务端与 Agent 分别发布,不能把 OAP 版本号当成 Agent 版本。该服务端组合来自 官方 Docker 配套配置,镜像和签名入口见 SkyWalking 下载。
应用补丁用于固定插件实验,不建议生产长期停留在该补丁。迁移到其他 Spring Boot/JDK 版本时,先核对 Java Agent 支持列表,再验证 HTTP 服务端、客户端和异步路径。BanyanDB 兼容性由 API 与发行版本共同约束,OAP 不兼容时会拒绝启动;对应关系见 BanyanDB 存储配置。
首次启动
解压并进入工程目录,先拉取 UI 镜像生成本地登录密码:
docker compose version
docker pull apache/skywalking-ui:horizon-1.0.0
bash prepare.sh || exit 1
docker compose config
docker compose build checkout
docker compose pull banyandb oap ui
docker compose up -d
docker compose ps构建包含三个测试,检查演示操作和非法模式。应用镜像复制独立 Agent 制品,运行身份为 10001;构建容器和官方 OAP 镜像默认使用 root。BanyanDB 使用准备脚本记录的当前用户 UID/GID,Horizon 使用镜像自带的专用用户。这些身份差异要逐组件确认,不能笼统声称“整套容器都非 root”。
准备脚本在生成凭据前拒绝已有本地状态,以及固定项目 ops8-trace 的容器、卷或网络;Docker 查询失败也会退出。换目录不代表新项目,不通过 -p 或 COMPOSE_PROJECT_NAME 绕过检查。恢复已有实验应回原目录直接启动,保留原 .env、密码和数据。
BanyanDB 将 Stream、Measure、Trace、Property 和 Schema Registry 的根目录分别设置到 /data 挂载下,全部持久化到 runtime/banyandb。Trace、Property 和 Schema Registry 有独立的默认临时路径,只设置 stream/measure 无法保留完整历史;各参数见 BanyanDB 配置。UI 配置与随机密码放在 runtime。OAP/UI 不需要主机公开访问存储端口;主机仅绑定以下回环入口:
18581 → checkout:8080 测试业务
18528 → oap:12800 查询和健康检查
18580 → ui:8081 Horizon 界面Horizon 1.0.0 通过挂载的 horizon.yaml 设置 OAP 查询/管理地址和本地用户,不能沿用旧 UI 的环境变量配置。实验生成密码哈希,不保存公开默认密码;生产还需 HTTPS、会话和角色权限。UI 配置参考见 Horizon 项目。
存储先就绪,随后 OAP 安装或核对 schema。首次启动可能需要一段时间,按下面方式限定等待:
ready=0
for attempt in $(seq 1 90); do
if curl -q --noproxy '*' --fail-with-body -sS --max-time 2 \
http://127.0.0.1:18528/healthcheck; then
ready=1
break
fi
sleep 1
done
test "$ready" -eq 1最多约四分半钟。超时后查看 docker compose logs --tail 100 banyandb oap,重点检查 API 兼容、目录写权限、内存和 schema 初始化错误。不要循环重启掩盖同一条启动失败。Docker Desktop 下观察的是 Linux VM 内运行结果;真实 Linux 主机的文件权限和安全策略仍需按目标环境复核。
Agent 怎样进入应用
应用启动参数中的关键项是:
java -javaagent:/opt/skywalking-agent/skywalking-agent.jar \
-jar /app/app.jar-javaagent 放在 -jar 前,完整 Agent 目录随镜像一起提供,不能只复制一个 JAR 而漏掉插件和配置。checkout 的环境变量指定服务、实例及上报地址:
SW_AGENT_NAME: checkout
SW_AGENT_INSTANCE_NAME: checkout-lab-1
SW_AGENT_COLLECTOR_BACKEND_SERVICES: oap:11800
SW_LOGGING_OUTPUT: CONSOLEinventory 使用自己的服务和实例名,指向相同 OAP。容器中的 localhost 指向本容器,因此不能把主机地址照搬成 localhost:11800。配置优先级、文件结构与启动方式见 Java Agent 安装。
Spring MVC 6 的注解插件在这个 Agent 版本中位于 optional-plugins。Dockerfile 将指定插件复制到 plugins,保留 Tomcat 和 Apache HttpClient 插件,以识别入口、归一化路由和下游请求。不要把全部可选插件一次性复制进去;它们可能增加开销或改变重复拦截关系。
发起跨服务调用
实验的 checkout 使用 Apache HttpClient 请求 inventory,明确设置连接和响应超时,并关闭自动重试,让一次演示请求只调用一次下游。慢分支等待约 1.2 秒,失败分支返回 503,没有真实库存写入。
curl -q --noproxy '*' --fail-with-body -sS --max-time 5 \
'http://127.0.0.1:18581/checkout?mode=fast'
curl -q --noproxy '*' --fail-with-body -sS --max-time 5 \
'http://127.0.0.1:18581/checkout?mode=slow'
status=$(curl -q --noproxy '*' -sS --max-time 5 -o /dev/null \
-w '%{http_code}' 'http://127.0.0.1:18581/checkout?mode=fail')
test "$status" = 503前两条返回 inventory reserved,slow 明显更慢,最后检查预期的 503。初次类加载和连接建立会增加延迟,性能比较应观察后续请求;不要把启动后的第一条调用当作稳定基线。
打开 http://127.0.0.1:18580,用 labadmin 与本机 runtime/ui-password 登录。从 Services Dashboard 进入 General services,在覆盖刚才请求的时间范围内检查 checkout 与 inventory。拓扑应出现 checkout 到 inventory 的关系,Trace 列表应能找到慢请求与错误请求。

Horizon 1.0.0 的 Services Dashboard:实验流量形成 checkout → inventory 调用关系。图中的请求量与成功率来自该实验窗口,不能作为生产阈值;其他层没有接入,因此显示为空。
从 Trace 找到耗时,并控制采集成本
读调用树时比较哪些数据
在 General Service 的 Traces 页选择服务、时间范围和状态,执行 Run query;按 Slowest 排序可优先观察慢请求。打开一条 Trace,核对入口、下游服务、实例、Span 类型、组件、错误标记以及相对耗时。
一条典型实验 Trace 包含 checkout Entry、HttpClient Exit 和 inventory Entry。跨进程引用应连接到相应父 Segment/Span;只看到两个服务名称,尚不能说明它们已经连成同一条 Trace。
父 Span 通常覆盖子调用时间,不能把所有 Span 的持续时间相加当作请求总耗时。并发调用还会在时间轴上重叠。先找长时间覆盖的下游或没有可见子操作的空白区,再用线程、连接池或更细插桩继续分析。
checkout Entry ├───────────────────────────────┤
HttpClient Exit ├─────────────────────────┤
inventory Entry ├───────────────────┤
下游处理约 1.2 秒客户端 Exit 比服务端 Entry 更长,差值可能包含连接获取、网络、排队和客户端处理,不能全部叫作服务端计算时间。跨主机时钟偏差还可能使时间位置失真,应同时检查时钟同步。
失败分支返回 503,对应 Span 可带错误状态。业务拒绝是否应记为错误取决于插件与业务约定;HTTP 200 的错误业务码也可能需要自定义标记。不要仅根据 UI 颜色推断业务最终状态。
采样发生在哪里
Agent 端减少生成或上报,可以降低应用与传输开销,但未上报的数据无法由后端恢复。OAP 端采样控制保存哪些追踪记录,适合已经接受上报、但希望降低存储量的情况。服务指标的统计来源与追踪保存比例需要分别解释。
OAP 的常规 Trace 保存策略可以用比例与慢请求阈值表达:
default:
rate: 1000
duration: 1000这里 rate 的精度是万分之一,1000 对应 10%;duration 使用毫秒。强制保留错误 Segment 或慢 Segment 时,实际保存比例可能高于默认比例,故障高峰尤其明显。单独保留某个错误片段也未必保留完整上下游。配置位置与行为见 服务端采样。
BanyanDB 在新 Trace 模型下另有尾采样与生命周期能力。接入时按所选存储和版本核对处理顺序,不叠加几套采样规则后仍按一个“10%”估算容量。新模型的查询也有差异:OAP 11 与 BanyanDB 0.11 的 Trace 列表使用 queryTraces;旧 queryBasicTraces 虽可能仍在 GraphQL schema 中,却会对该模型返回不支持。接口兼容检查要执行实际查询,不能只看接口名称存在。
日志关联与异步上下文
日志中保存 Trace ID 后,可以从异常事件跳到调用树。SkyWalking 为常见日志框架提供 toolkit,将 Trace ID 输出到日志格式;应用依赖该 toolkit 与启动 Agent 是不同动作。选用 Logback 时按 日志关联工具 配置依赖、布局和格式,不在没有上下文的任务里伪造 Trace ID。
日志展示 Trace ID 与把日志上传到 OAP 也是两个配置步骤。已有 Loki/Elasticsearch 日志平台可以继续独立保存日志,通过标识跳转;只有确实需要在 SkyWalking 查询日志时再配置对应传输和解析。
跨线程时,线程池中的任务需要携带正确上下文,并在执行后恢复。某些框架已有插件,手工线程、定制执行器或特殊回调则需 toolkit/SDK。观察断链时先核对任务提交和执行位置,不能只在所有方法上追加注解。异步工具见 跨线程工具。
从请求慢进入 Profiling
Trace 先定位哪段调用慢,Profiling 再观察该段执行的栈或资源活动。长时间没有可见子 Span,可能是 CPU 计算,也可能在锁、连接池或未被插桩的库中等待;仅看空白时间无法区分。
按目标端点、时间和采样间隔创建有限任务,先在单个测试实例验证开销。任务完成后结合 Span 和采样栈判断热点;它不是每个方法每次调用的精确计时。Trace Profiling 的条件与流程见 官方说明,其他 eBPF 或异步分析能力需分别满足内核、探针与权限要求,不为了打开一个面板就给应用容器特权。
告警关注服务指标及恢复
OAP 的告警规则在 alarm-settings.yml 中,11.0.0 使用 MQE 表达式。表达式的返回类型需要符合规则要求,不能直接复制旧版本的 op/threshold/count 配置。
rules:
checkout_latency_rule:
expression: avg(service_resp_time) > 1000
include-names:
- checkout
period: 3
silence-period: 3
message: Checkout average latency exceeds 1000ms这是按三分钟窗口观察服务平均耗时的规则示例,业务阈值应结合实际流量与目标设定,不能据此代替 P95 或业务成功率。11.0.0 支持恢复观察和恢复通知配置;不同 hook 的消息内容、接收确认和升级流程还要单独验证。配置语义见 SkyWalking 告警。
真实接入时先让少量测试请求触发条件,检查告警实体、规则名、hook 投递和恢复通知,再连接生产值班通道。SkyWalking 与 Prometheus 对同一故障同时告警时,应协调分工和去重,不让处理人收到两个不同名字的同一事件。
生产部署、升级和故障处理
存储与 OAP 分别扩展
实验使用单机 BanyanDB,适合学习和功能验证。生产需要根据摄入量、查询负载和故障域选择集群形态,并为数据、副本、元数据和恢复准备独立方案。复制因子、节点数量和资源预算应由目标容错要求确定,不能把三个容器放在同一宿主就称为跨故障域高可用。
BanyanDB 按数据类别与粒度管理保存期限。Trace、日志、分钟/小时/天聚合指标有不同体积和查询用途,调整 TTL 时检查实际生效组配置及清理状态。数据生命周期参考 TTL 和前面的 BanyanDB 存储文档。
评估容量至少采集每秒 Span/Segment 数、平均大小、活跃服务与端点数量、写入失败、查询延迟和存储增长。采样比例是影响因素之一;错误强采、重复插桩、参数化端点失控和慢查询都会改变预算。降低保留天数无法消除 OAP 当前分析队列压力。
OAP 多节点需要稳定的成员发现和内部通信,Agent 接入地址则负责把长连接分配到节点。gRPC 长连接不会随每个请求重新负载均衡,应观察每节点连接数与数据量。集群发现方式见 OAP 集群管理。
安全和运行身份
生产对外仅提供经认证与授权的 UI/查询入口。Agent 上报端口限制工作负载来源,存储端口仅允许 OAP 和维护身份;OAP 管理 HTTP 与内部管理 gRPC 更不能直接暴露给普通应用。传输加密及认证选项见 SkyWalking TLS 与安全。
Horizon 角色权限控制 UI 能执行哪些管理操作,不能替代底层网络和 OAP 认证。配置应使用受控密钥,限制会话、启用 HTTPS,并避免把查询用户自动授予修改规则、调试和数据管理权限。
SQL、请求参数、消息内容和异常栈可能包含敏感信息。优先关闭不必要的采集字段,在应用或探针侧脱敏,再限制平台查询权限和保留时间。生产使用非 root OAP 镜像时,应提前准备它所需的配置、临时和日志目录并验证启动;不能只追加 user 后忽略启动脚本的写入需求。
版本更新与恢复
一次更新涉及 Agent 插件、应用框架、OAP、UI 和存储。分别固定版本,先在隔离环境验证一条完整跨服务请求、错误请求、查询和告警,再逐步扩大接入。
存储升级先核对格式/API 兼容、备份和恢复步骤;不要让两个不兼容版本同时写入同一目录。Agent 更新可从少量实例开始,比较资源、错误、Span 数量与插件告警,异常时退回原 Agent 制品和配置并重启该实例。
OAP/UI 更新前保存配置和必要存储副本,验证历史 Trace 与指标仍能查询。Horizon 与旧 UI 的配置方式和管理能力不同,需重新核对认证与端口,而不是只替换镜像标签。发行差异见 SkyWalking 11 变更说明。
受限网络中,提前准备 Maven 依赖、Agent、OAP、UI、存储镜像、CA 与插件,不在目标生产节点临时下载。离线包应包含来源、摘要、目标架构和配置样例,凭据在目标环境单独注入。
区分没有数据、调用断链与查询失败
| 现象 | 首查位置 | 后续判断 |
|---|---|---|
| UI 打不开或登录失败 | UI 日志、监听、horizon.yaml 与密码文件 | 区分文件读取、认证和 OAP 管理连接 |
| 服务完全未出现 | Agent 是否加载、服务名、上报地址和网络 | 发起受支持请求,再看 Agent/OAP 日志 |
| 两个服务没有关联边 | 是否真实跨服务调用、客户端插件、传播头 | 不靠手工填服务名补出虚假拓扑 |
| Trace 缺少下游 | 下游探针、上下文、采样及丢弃 | 比对双方 Agent,检查网关和线程切换 |
| 有指标但部分 Trace 查不到 | 保存采样、TTL、时间范围和存储模型 | 用同窗口与正确 API 查新请求 |
| OAP 正常,查询很慢 | 时间窗、端点基数、存储与查询负载 | 先缩小范围,再检查后端队列与资源 |
| Agent 日志持续上报失败 | DNS、TLS、目标端口与 OAP 健康 | 恢复连接后观察新数据,不假定旧数据全补齐 |
只有兼容插件生效才会执行对应增强。启动日志中旧版插件因 witness class 不存在而未激活,可能是正常的版本选择;需要核对目标框架插件及实际 Span,而不是见到任何 WARN 都认定接入失败。
可以在隔离实验中暂停 OAP,继续请求 checkout,观察业务响应与 Agent 上报错误:
docker compose stop oap
curl -q --noproxy '*' --fail-with-body -sS --max-time 5 \
'http://127.0.0.1:18581/checkout?mode=fast'
docker compose logs --tail 50 checkout
docker compose start oap恢复后重新检查 OAP 健康,再产生新请求并到 Trace 页面确认。Agent 重连和数据可查询各有等待时间,健康端点先恢复时,第一批请求仍可能没有进入存储。在随后两分钟内间隔发起少量测试请求,按请求时间确认新 Trace;持续没有数据时,检查 Agent 的连接状态与上报错误,不反复重启全部组件。离线期间是否补齐取决于缓冲和丢弃条件,不能用恢复后的新请求替代那段历史的完整性检查。观测系统自身的指标与告警接入见 OAP 自观测。
验证容器重建后的历史保留时,先从 Trace 页面保存一条含 checkout、inventory 及跨服务引用的 Trace ID、查询时间窗和 Span 内容。停止发送业务请求,在原目录执行 docker compose down,然后 docker compose up -d;不重新 prepare,也不删除 runtime。等待存储和 OAP 健康后,用原时间窗查询原 Trace ID,对照 Span ID、服务、时间、错误状态与引用。查回同一条历史后,再发新请求验证继续写入;新 Trace 出现不能代替历史恢复检查。
上述目录配置用于新建实验。若旧容器曾使用默认临时根,应在删除容器前保护 /tmp/trace、/tmp/property 和 /tmp/schema-property 等旧数据,按同版本停写、停止存储和目录迁移流程在副本中验证;不要先 down 再改挂载,已删除容器中的未挂载数据无法靠新配置找回。
结束实验使用 docker compose down,绑定目录中的追踪数据和账号配置保留。只有明确放弃这些实验数据时才删除专用目录,不触碰已有存储卷。
权威资料与规范地址
对象模型与协议
- SkyWalking 核心概念:https://skywalking.apache.org/docs/main/v11.0.0/en/concepts-and-designs/overview/
- SkyWalking 上下文传播:https://skywalking.apache.org/docs/main/v11.0.0/en/api/x-process-propagation-headers-v3/
- OpenTelemetry Trace 接收:https://skywalking.apache.org/docs/main/v11.0.0/en/setup/backend/otlp-trace/
安装与插件
- 官方 Docker 配套配置:https://github.com/apache/skywalking/blob/v11.0.0/docker/docker-compose.yml
- SkyWalking 下载:https://skywalking.apache.org/downloads/
- Java Agent 支持列表:https://skywalking.apache.org/docs/skywalking-java/v9.6.0/en/setup/service-agent/java-agent/supported-list/
- BanyanDB 存储配置:https://skywalking.apache.org/docs/main/v11.0.0/en/setup/backend/storages/banyandb/
- BanyanDB 配置:https://skywalking.apache.org/docs/skywalking-banyandb/v0.11.0/operation/configuration/
- Horizon 项目:https://github.com/apache/skywalking-horizon-ui
- Java Agent 安装:https://skywalking.apache.org/docs/skywalking-java/v9.6.0/en/setup/service-agent/java-agent/readme/
Trace、采样与告警
- 服务端采样:https://skywalking.apache.org/docs/main/v11.0.0/en/setup/backend/trace-sampling/
- 日志关联工具:https://skywalking.apache.org/docs/skywalking-java/v9.6.0/en/setup/service-agent/java-agent/application-toolkit-logback-1.x/
- 跨线程工具:https://skywalking.apache.org/docs/skywalking-java/v9.6.0/en/setup/service-agent/java-agent/application-toolkit-trace-cross-thread/
- 官方说明:https://skywalking.apache.org/docs/main/v11.0.0/en/setup/backend/backend-trace-profiling/
- SkyWalking 告警:https://skywalking.apache.org/docs/main/v11.0.0/en/setup/backend/backend-alarm/
存储与运行维护
- TTL:https://skywalking.apache.org/docs/main/v11.0.0/en/setup/backend/ttl/
- OAP 集群管理:https://skywalking.apache.org/docs/main/v11.0.0/en/setup/backend/backend-cluster/
- SkyWalking TLS 与安全:https://skywalking.apache.org/docs/main/v11.0.0/en/setup/backend/grpc-security/
- SkyWalking 11 变更说明:https://skywalking.apache.org/docs/main/v11.0.0/en/changes/changes/
- OAP 自观测:https://skywalking.apache.org/docs/main/v11.0.0/en/setup/backend/backend-telemetry/
