☰
SkyWalking OAP与UI部署实战:从零搭建可观测性底座
2026/10/2 4:00:55 网站建设 项目流程

1. 项目概述:这不是“装个软件”,而是给系统装上“CT机”

如果你在微服务架构里干过运维、开发或SRE,大概率经历过这种场景:用户投诉订单提交失败,你翻遍网关日志、订单服务日志、支付服务日志,发现调用链断在某个中间件超时,但具体是哪个线程卡死、哪次SQL执行了8秒、哪个Redis key被大对象阻塞——全靠猜。这时候,SkyWalking 就不是“又一个监控工具”,而是你手里的分布式系统诊断CT机:它不只告诉你“哪里疼”,还能精准定位到“第3层肺叶第7支气管的毛细血管栓塞”。

标题里写的“SkyWalking指南——OAP及UI的搭建”,表面看是部署两个组件,实则是一套完整的可观测性基础设施落地起点。OAP(Observability Analysis Platform)是后端分析引擎,负责接收探针数据、存储、聚合、建模;UI 是前端可视化界面,把OAP吐出的指标、拓扑、追踪、告警翻译成人能看懂的图表和交互视图。二者缺一不可,但很多人卡在第一步:OAP起不来,UI连不上,或者UI打开后一片空白、拓扑图不刷新、追踪列表空荡荡——这根本不是“配置错了”,而是对SkyWalking的数据流、依赖关系、资源边界缺乏系统性认知。

我带过6个不同行业的团队落地SkyWalking,从金融核心交易系统到IoT设备管理平台,踩过的坑基本都围绕三个核心问题:OAP与存储的连接稳定性、UI与OAP的通信时序、以及整个链路对JVM资源的隐性消耗。比如某次电商大促前压测,UI界面卡顿被反复上报,最后发现不是前端性能问题,而是OAP的Elasticsearch客户端未启用连接池复用,每秒生成2000+短连接,直接打爆ES节点的文件描述符上限。这类问题,官方文档不会写,社区帖子也常归因为“配置不对”,但真正原因藏在组件间的数据契约和资源调度逻辑里。

这篇指南不讲“下载→解压→启动”的流水账,而是带你像架构师一样思考:OAP为什么必须独立部署?UI为什么不能直连ES?为什么推荐用Elasticsearch而非H2做存储?当UI显示“Service not found”时,到底是探针没发数据,还是OAP没存进去,还是UI查错了索引?我会用真实生产环境的参数配置、日志片段、curl调试命令,把每个环节的“黑盒”打开,让你搭的不是两个Docker容器,而是一套可诊断、可扩展、可信任的观测底座。适合正在规划APM方案的架构师、需要快速定位线上问题的后端工程师,以及刚接手运维却面对一堆报错日志无从下手的SRE同学。

2. 整体设计思路:为什么必须分OAP和UI?为什么不能All-in-One?

2.1 架构分层不是为了“高大上”,而是解决三个硬约束

SkyWalking 的 OAP 和 UI 分离部署,绝非为了“微服务化”而微服务化。这是由可观测性系统的数据特性、计算负载、安全边界三大硬约束决定的:

  • 数据流单向性与吞吐压力:探针(Agent)上报的是原始调用数据(Trace Segment、Metrics、Logs),OAP 需要实时解析、关联、降采样、构建服务拓扑。这个过程 CPU 和内存消耗极大,尤其在千级服务、万级TPS的场景下。而 UI 只是查询已聚合好的结果(如“过去1小时订单服务P99延迟”),本质是轻量级HTTP请求。若强行合并,UI的偶发高并发请求(比如几十人同时刷Dashboard)会直接抢占OAP的计算资源,导致数据处理延迟飙升,形成恶性循环。

  • 存储访问模式截然不同:OAP 写入存储是高频、小批量、强一致性要求(如每秒写入数万条Metrics点);UI 查询是低频、大批量、最终一致性即可(如拉取最近24小时的慢SQL列表)。Elasticsearch 的写入线程池和搜索线程池默认隔离,若OAP和UI共用同一套ES客户端,极易因搜索请求耗尽写入线程,造成数据堆积。我们曾在线上环境观察到:当UI开启“自动刷新”后,OAP的Metrics写入延迟从50ms飙升至2s,根源就是ES的search线程池占用了bulk线程池的资源。

  • 安全与权限收敛需求:OAP 需要读写存储、管理集群状态、暴露gRPC/HTTP管理端口;UI 只需向OAP发起HTTP GET/POST请求。将UI暴露在DMZ区或公网,而OAP严格限制在内网,是标准的安全实践。某金融客户曾因UI和OAP混部,导致UI的Nginx配置错误,意外将OAP的9200管理端口映射出去,触发了内部安全审计告警。

提示:不要被“SkyWalking All-in-One Docker镜像”误导。那个镜像仅用于本地Demo或CI/CD流水线中的单测,生产环境必须拆分。我见过太多团队用All-in-One跑通测试后,上线就崩溃,根本原因是忽略了资源隔离这一底层逻辑。

2.2 存储选型:为什么Elasticsearch是默认,而H2只适合“玩具”?

SkyWalking 支持多种存储后端:H2(嵌入式)、MySQL、PostgreSQL、Elasticsearch、TiKV。但生产环境唯一合理的选择只有Elasticsearch(ES),理由非常实在:

  • 时序数据天然适配:SkyWalking 的 Metrics(如JVM内存使用率)、Traces(调用链时间戳)、Logs(结构化日志)全是带时间戳的时序数据。ES 的倒排索引+Doc Values 对时间范围查询(@timestamp: [now-1h TO now])做了极致优化,查询毫秒级响应。而MySQL即使加了时间字段索引,在亿级Trace数据下,按服务名+时间范围聚合P99延迟,单次查询常超10秒。

  • 高基数维度查询能力:微服务中服务名、实例IP、Endpoint名称、Tag键值对构成超高基数维度。ES 的terms聚合能在千万级文档中秒级完成“按服务名分组统计错误率”。MySQL的GROUP BY在高基数下会触发临时表和文件排序,性能断崖式下跌。

  • 水平扩展性:ES集群可轻松扩到数十节点,通过Shard分片均匀分散读写压力。MySQL主从复制在写入密集场景下,从库延迟常达分钟级,导致UI看到的“实时”数据其实是10分钟前的。

H2 的唯一价值是零依赖快速验证。它把所有数据存在内存或本地文件,启动快、配置少。但一旦数据量超过1GB,H2的GC停顿就会让OAP频繁假死;且不支持集群,无法应对任何生产流量。某客户曾用H2跑POC,三天后数据文件涨到3GB,OAP启动耗时从8秒变成17分钟,最终不得不重导数据。

注意:ES版本兼容性是高频雷区。SkyWalking 9.x 要求 ES 7.0–7.17 或 8.0–8.12。用ES 8.13会导致OAP启动时报java.lang.NoSuchMethodError: org.elasticsearch.client.RequestOptions.Builder.setHttpAsyncResponseConsumerFactory——这是ES客户端API变更导致的,必须严格匹配。我们维护了一份《SkyWalking各版本与存储组件兼容矩阵》,文末会提供获取方式。

2.3 网络拓扑:UI→OAP→ES,三段链路各自的关键检查点

整个数据链路看似简单:探针 → OAP → ES ← UI,但每一段都是故障高发区。必须明确每段的协议、端口、健康检查方式:

链路段协议/端口健康检查方式典型故障现象根本原因示例
探针→OAPgRPC 11800 (默认)telnet oap-host 11800UI中无服务拓扑、无Trace数据OAP未开启gRPC监听,或防火墙拦截11800端口;探针配置了错误的OAP地址
OAP→ESHTTP 9200curl -XGET 'http://es-host:9200/_cat/health?v'OAP日志持续打印ElasticsearchException: Connection refusedES集群未启动,或OAP配置的ES地址为localhost(容器内DNS解析失败)
UI→OAPHTTP 8080curl -XGET 'http://oap-host:8080/oap/v3/services'UI白屏、Network面板显示502/504Nginx反代配置错误;OAP的core/default模块未启用;UI配置的OAP地址端口与OAP实际监听端口不符

关键经验:永远先用curl验证最底层链路。不要一上来就打开UI看空白页,先确认UI→OAP能通,再确认OAP→ES能通,最后确认探针→OAP能通。顺序错了,排查效率直接归零。

3. 核心细节解析:OAP配置的12个关键参数与UI的3个致命配置

3.1 OAP配置:application.yml里真正影响稳定性的12个参数

OAP的配置文件config/application.yml有数百行,但90%的线上问题,源于以下12个参数的误配。我按优先级排序,并附上生产环境实测值:

(1)storage模块:ES连接与索引策略
storage: selector: ${SW_STORAGE:elasticsearch} elasticsearch: nameSpace: ${SW_NAMESPACE:""} clusterNodes: ${SW_STORAGE_ES_CLUSTER_NODES:es-host1:9200,es-host2:9200} protocol: ${SW_STORAGE_ES_HTTP_PROTOCOL:"http"} trustStorePath: ${SW_STORAGE_ES_SSL_TRUST_STORE_PATH:""} # 关键!连接池大小,直接影响吞吐 connectTimeout: ${SW_STORAGE_ES_CONNECT_TIMEOUT:3} socketTimeout: ${SW_STORAGE_ES_SOCKET_TIMEOUT:30} responseTimeout: ${SW_STORAGE_ES_RESPONSE_TIMEOUT:30} # 关键!ES客户端最大连接数,必须≥OAP工作线程数*2 maxConnections: ${SW_STORAGE_ES_MAX_CONNECTIONS:30} maxConnectionsPerRoute: ${SW_STORAGE_ES_MAX_CONNECTIONS_PER_ROUTE:30} # 关键!索引滚动策略,避免单索引过大 indexShardsNumber: ${SW_STORAGE_ES_INDEX_SHARDS_NUMBER:2} indexReplicasNumber: ${SW_STORAGE_ES_INDEX_REPLICAS_NUMBER:1} # 关键!禁用动态Mapping,防止字段爆炸 enableDynamicMapping: ${SW_STORAGE_ES_ENABLE_DYNAMIC_MAPPING:false}
  • maxConnections:这是最常被低估的参数。OAP默认工作线程数为CPU核数×2,假设8核服务器,OAP有16个工作线程。每个线程可能并发执行ES查询,若maxConnections设为10,则大量线程会阻塞在连接获取上。我们线上统一设为30,确保冗余。
  • enableDynamicMapping: false:必须关闭!否则探针上报的任意Tag(如user_id=123456、order_status=paid)都会被ES自动创建新字段,导致Mapping膨胀,最终触发ES的circuit_breaking_exception熔断。正确做法是提前在ES中创建Index Template,定义好service.name、endpoint.name等固定字段。
(2)core模块:服务发现与采样控制
core: selector: ${SW_CORE:default} default: # 关键!采样率,1.0=全量,0.1=10%,生产环境建议0.3~0.5 sampling: ${SW_CORE_DEFAULT_SAMPLING:0.3} # 关键!心跳检测间隔,影响服务实例上下线感知速度 heartbeat: ${SW_CORE_DEFAULT_HEARTBEAT:30} # 关键!Trace数据保留天数,ES磁盘空间杀手 traceRecordMaxAge: ${SW_CORE_DEFAULT_TRACE_RECORD_MAX_AGE:3} # 关键!Metrics数据保留天数,比Trace更占空间 metricsDataMaxAge: ${SW_CORE_DEFAULT_METRICS_DATA_MAX_AGE:7}
  • sampling:新手常设为1.0,以为“数据越全越好”。但全量Trace在高并发下会产生海量数据,ES写入压力剧增。我们实测:电商系统TPS 5000时,采样率0.3与1.0相比,P99延迟分析误差<5%,但ES日均写入量从2TB降至600GB。采样不是丢数据,而是用统计学保证代表性。
  • traceRecordMaxAge:必须与ES的ILM(Index Lifecycle Management)策略联动。若设为3天,ES中对应索引(如sw_trace_day_20240501)必须在3天后自动删除,否则磁盘迟早爆满。我们用ES的rolloverAPI配合CronJob实现自动清理。
(3)receiver-trace模块:gRPC服务监听
receiver-trace: selector: ${SW_RECEIVER_TRACE:default} default: # 关键!必须显式绑定到0.0.0.0,否则容器内其他服务无法访问 gRPCHost: ${SW_RECEIVER_TRACE_DEFAULT_GRPC_HOST:0.0.0.0} gRPCPort: ${SW_RECEIVER_TRACE_DEFAULT_GRPC_PORT:11800} # 关键!gRPC最大消息尺寸,避免大Trace被截断 maxMessageSize: ${SW_RECEIVER_TRACE_DEFAULT_GRPC_MAX_MESSAGE_SIZE:10485760} # 10MB
  • gRPCHost: 0.0.0.0:Docker部署时90%的“探针连不上”问题根源!OAP默认gRPCHost是localhost,在容器内localhost指向容器自身,外部探针自然连不通。必须改为0.0.0.0。
  • maxMessageSize:某些复杂调用链(如含大量LogEntry或大参数)Trace Segment可能超1MB,默认4MB不够,设为10MB保底。

3.2 UI配置:docker-compose.yml里3个让UI“活过来”的配置项

UI的Docker镜像(apache/skywalking-ui)本身很轻量,但配置错误会导致“页面加载但数据为空”。核心在docker-compose.yml的environment部分:

version: '3.7' services: ui: image: apache/skywalking-ui:9.7.0 restart: always ports: - "8080:8080" environment: # 关键!必须指向OAP的HTTP端口,不是gRPC端口! SW_OAP_ADDRESS: http://oap:12800 # 关键!UI的根路径,若反代到/skywalking,必须设此值 SW_BASEPATH: / # 关键!时区,否则时间显示错乱 TZ: Asia/Shanghai depends_on: - oap
  • SW_OAP_ADDRESS:这是最高频错误!很多人填http://oap:11800(gRPC端口),但UI是通过HTTP REST API(默认12800)与OAP通信的。填错直接导致Network面板所有请求返回404。确认OAP的HTTP端口:查看OAP日志,搜索Started SkyWalking OAP Server,后面会打印http://0.0.0.0:12800。
  • SW_BASEPATH:若UI通过Nginx反代到https://monitor.example.com/skywalking/,则此处必须设为/skywalking,否则UI内部所有API请求路径会变成/oap/v3/services(404),而非/skywalking/oap/v3/services。
  • TZ:不设时区,UI显示的所有时间都是UTC,与你本地日志时间差8小时,排查问题时极易误判。必须显式设置。

实操心得:UI容器启动后,第一时间进容器执行curl -v http://oap:12800/oap/v3/services。如果返回JSON数组(哪怕为空),说明网络和OAP服务正常;如果返回Connection refused,立刻检查OAP是否已启动、端口是否监听(netstat -tuln | grep 12800)、防火墙是否放行。

4. 实操过程:从零开始搭建,附完整命令、日志分析与避坑清单

4.1 环境准备:Linux服务器基础配置(以CentOS 7为例)

SkyWalking对硬件要求不高,但操作系统配置直接影响稳定性。以下是经过12个生产环境验证的最小化配置:

  • 内核参数调优(/etc/sysctl.conf):

    # 提升网络连接数,应对探针海量连接 net.core.somaxconn = 65535 net.ipv4.tcp_max_syn_backlog = 65535 # 避免TIME_WAIT连接占用过多端口 net.ipv4.tcp_fin_timeout = 30 net.ipv4.tcp_tw_reuse = 1 # ES和OAP都是Java进程,增大虚拟内存映射区 vm.max_map_count = 262144

    执行sysctl -p生效。vm.max_map_count不足会导致ES启动失败,报错max virtual memory areas vm.max_map_count [65536] is too low。

  • JDK版本:OAP和UI都基于Java,必须使用JDK 11或JDK 17。JDK 8已不被SkyWalking 9.x支持。验证命令:

    java -version # 正确输出示例:openjdk version "17.0.2" 2022-01-18
  • 磁盘空间规划:ES是磁盘大户。按经验公式预估:

    日均ES存储 = (日均Trace量 × 1.5KB/Trace + 日均Metrics点 × 0.2KB/Metric) × 保留天数 × 1.3(副本+预留)

    例如:1000 TPS系统,平均每次Trace 5个Span,日均Trace量≈1000×3600×24×5=4.32亿,按1.5KB算约650GB;Metrics点按服务数×实例数×指标数×采集频率,假设200服务×10实例×20指标×4次/分钟≈960万点/天,按0.2KB算约1.9GB。3天保留,总需约(650+1.9)×3×1.3≈2540GB。务必为ES单独挂载SSD磁盘,切勿与系统盘混用。

4.2 Elasticsearch部署:单节点快速启动与多节点生产配置

单节点(开发/测试)
# 下载ES 7.17.12(SkyWalking 9.7兼容) wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.17.12-linux-x86_64.tar.gz tar -xzf elasticsearch-7.17.12-linux-x86_64.tar.gz cd elasticsearch-7.17.12 # 修改配置 config/elasticsearch.yml echo "cluster.name: skywalking-es" >> config/elasticsearch.yml echo "node.name: es-node-1" >> config/elasticsearch.yml echo "network.host: 0.0.0.0" >> config/elasticsearch.yml echo "http.port: 9200" >> config/elasticsearch.yml echo "discovery.type: single-node" >> config/elasticsearch.yml echo "xpack.security.enabled: false" >> config/elasticsearch.yml # 生产环境必须开启! echo "path.data: /data/es" >> config/elasticsearch.yml echo "path.logs: /var/log/elasticsearch" >> config/elasticsearch.yml # 创建数据目录并授权 mkdir -p /data/es /var/log/elasticsearch chown -R elasticsearch:elasticsearch /data/es /var/log/elasticsearch # 启动(后台运行) sudo -u elasticsearch ./bin/elasticsearch -d -p pid

验证:curl http://localhost:9200返回JSON即成功。

多节点生产(3节点集群)
# 三台机器,配置相同,仅node.name和network.host不同 # node1: network.host: 192.168.1.101, node.name: es-node-1 # node2: network.host: 192.168.1.102, node.name: es-node-2 # node3: network.host: 192.168.1.103, node.name: es-node-3 # config/elasticsearch.yml 公共配置 cluster.name: skywalking-prod node.name: es-node-1 network.host: 192.168.1.101 http.port: 9200 transport.port: 9300 # 关键!集群发现,列出所有master-eligible节点 discovery.seed_hosts: ["192.168.1.101:9300","192.168.1.102:9300","192.168.1.103:9300"] cluster.initial_master_nodes: ["es-node-1","es-node-2","es-node-3"] xpack.security.enabled: true # 必须开启认证 xpack.security.transport.ssl.enabled: true # ... 其他SSL证书配置

注意:ES集群必须先于OAP启动。OAP启动时会尝试连接ES,若ES未就绪,OAP会不断重试直至超时(默认30秒),然后退出。我们用wait-for-it.sh脚本在OAP容器启动前等待ES健康。

4.3 OAP部署:Docker Compose一键启停与关键日志解读

docker-compose.yml(OAP部分):

version: '3.7' services: oap: image: apache/skywalking-oap-server:9.7.0 restart: always ports: - "11800:11800" # gRPC - "12800:12800" # HTTP REST - "11801:11801" # gRPC for receiver-jvm environment: # 关键!指定存储为ES SW_STORAGE: elasticsearch SW_STORAGE_ES_CLUSTER_NODES: es-host1:9200,es-host2:9200 # 关键!JVM参数,防止OOM JAVA_OPTS: "-Xms4g -Xmx4g -XX:+UseG1GC -XX:MaxGCPauseMillis=100" # 关键!OAP模块开关,必须启用core和receiver-trace SW_CORE_DEFAULT_SAMPLING: "0.3" SW_RECEIVER_TRACE_DEFAULT_GRPC_HOST: "0.0.0.0" SW_RECEIVER_TRACE_DEFAULT_GRPC_PORT: "11800" volumes: - ./config:/skywalking/config - ./logs:/skywalking/logs depends_on: - es

启动与日志分析:

# 启动 docker-compose up -d oap # 查看OAP日志(重点关注前三行和ERROR) docker logs -f oap | head -n 50 # 正常启动关键日志: # [INFO] 2024-05-01 10:00:00: Started SkyWalking OAP Server # [INFO] 2024-05-01 10:00:02: Elasticsearch health check success. # [INFO] 2024-05-01 10:00:05: gRPC server started, listening on /0.0.0.0:11800 # 若出现ERROR,立即定位: # ERROR ElasticSearchException: Connection refused -> 检查ES是否启动、网络是否通 # ERROR Failed to init module core -> 检查application.yml语法错误(YAML缩进敏感!) # WARN No service detected in last 5 minutes -> 探针未接入,检查探针配置

4.4 UI部署:Nginx反代实现HTTPS访问与路径重写

UI直接暴露8080端口不安全,必须用Nginx反代。nginx.conf配置:

upstream skywalking_ui { server 127.0.0.1:8080; } server { listen 443 ssl http2; server_name monitor.example.com; ssl_certificate /etc/nginx/ssl/fullchain.pem; ssl_certificate_key /etc/nginx/ssl/privkey.pem; location / { proxy_pass http://skywalking_ui; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # 关键!重写UI内部API路径 proxy_redirect / /; } # 关键!为OAP API单独配置,避免跨域 location /oap/ { proxy_pass http://127.0.0.1:12800/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }

提示:location /oap/必须存在,否则UI的AJAX请求会因跨域被浏览器拦截。Nginx反代后,UI的SW_OAP_ADDRESS应设为https://monitor.example.com(即Nginx地址),而非OAP内网地址。

5. 常见问题与排查技巧实录:从“白屏”到“数据飞起”的21个真实案例

5.1 UI白屏/空白页:90%的问题出在这3步

当浏览器打开https://monitor.example.com,看到纯白页面或“Loading...”不动,按此顺序排查:

  1. 检查浏览器Network面板:

    • F12 → Network → 刷新 → 查看/oap/v3/services请求状态。
    • 若为Failed或Pending:网络不通,检查Nginx配置中location /oap/是否生效,proxy_pass地址是否正确。
    • 若为404:SW_OAP_ADDRESS配置错误,UI在请求/oap/v3/services,但OAP实际监听/v3/services(少了一个oap前缀),此时需确认OAP版本——SkyWalking 9.x的REST API路径已统一为/oap/v3/,旧版是/v3/,UI镜像版本必须与OAP匹配。
  2. 检查OAP是否收到请求:

    # 在OAP服务器执行,监听12800端口 sudo tcpdump -i any port 12800 -A -s 0 | grep "GET /oap/v3/services" # 若无输出,说明请求根本没到OAP,问题在Nginx或网络层
  3. 检查OAP日志是否有异常:

    docker logs oap 2>&1 | grep -i "error\|exception\|fail" | tail -n 20 # 常见错误: # "No services found" -> 探针未接入,或OAP的`core`模块未启用 # "ElasticsearchException: index_not_found_exception" -> ES中缺少`sw_service_inventory`等索引,需手动创建或重启OAP触发初始化

5.2 UI卡顿/响应慢:不是前端问题,是后端数据源瓶颈

当点击“Topology”拓扑图加载缓慢,或“Trace”列表翻页卡顿,不要优化UI代码,检查:

  • ES查询慢:登录ES Kibana,执行慢查询日志分析:

    GET /_nodes/stats?pretty&human&filter_path=nodes.*.indices.search.slowlog

    若slowlog中有大量查询,说明ES负载过高。优化方向:

    • 减少UI中“自定义时间范围”,避免跨多天查询;
    • 在OAP配置中降低metricsDataMaxAge,减少历史数据扫描;
    • 为高频查询字段(如service.name,endpoint.name)添加keyword子字段并启用eager_global_ordinals。
  • OAP线程阻塞:jstack抓取OAP线程快照:

    docker exec oap jstack 1 > /tmp/oap-thread.log # 查找WAITING状态线程 grep "java.lang.Thread.State: WAITING" /tmp/oap-thread.log -A 5 # 若大量线程在`org.apache.skywalking.oap.server.storage.plugin.elasticsearch.EsStorageModuleProvider`等待,说明ES连接池耗尽,增大`maxConnections`。

5.3 数据不显示:探针、OAP、ES三者数据流断点定位

这是最复杂的故障。按数据流向逐段验证:

验证点命令/方法期望结果异常处理
探针是否发送数据在应用服务器抓包:tcpdump -i any port 11800 -A -s 0 | grep "TraceSegment"看到TraceSegment字符串检查探针配置agent.service_name、collector.backend_service是否指向OAP正确地址和端口
OAP是否接收数据查看OAP日志:docker logs oap | grep -i "receive|segment"看到Received TraceSegment from xxx检查OAPreceiver-trace模块是否启用,gRPCHost是否为0.0.0.0
OAP是否写入ESES中查询:curl "http://es:9200/sw_trace_day_*/_count?q=service.name:your-service-name"返回{"count":1234,"_shards":{...}}检查OAPstorage配置,ES索引是否存在,enableDynamicMapping是否为false

实操心得:我们制作了一个“三色状态灯”脚本,自动执行上述三步并输出红/黄/绿状态,5分钟内定位90%的数据缺失问题。脚本核心逻辑是:

# 探针侧:检查本地是否有*.trace文件(探针本地缓存) ls /path/to/agent/logs/*.trace 2>/dev/null | wc -l # OAP侧:检查OAP日志最近1分钟是否有"segment"关键词 docker logs oap --since 1m 2>/dev/null | grep -c "segment" # ES侧:检查ES中该服务最近1小时Trace数量 curl -s "http://es:9200/sw_trace_day_*/_count?q=service.name:xxx&preference=_primary" \| jq '.count'

5.4 高级问题速查表:21个典型问题与一招解决

序号现象根本原因解决方案验证命令
1UI显示“Service not found”,但探针日志说“send segment success”OAP未启用core模块,服务注册功能关闭在application.yml中确认core.selector: default已取消注释docker logs oap | grep "CoreModule"
2拓扑图显示服务,但无连线(无调用关系)探针未开启trace插件,或agent.ignore_suffix过滤了关键路径检查探针agent.config中plugin.trace.ignore_suffix是否包含.do等后缀cat /path/to/agent/config/agent.config | grep ignore_suffix
3Trace详情中Span的peer字段为空(如DB调用显示unknown)探针未加载对应插件(如mysql-plugin.jar)将插件JAR包放入agent/plugins/目录,重启应用ls /path/to/agent/plugins/ | grep mysql
4UI中Metrics图表数据稀疏,远低于实际QPSsampling配置过低,或metricsDataMaxAge太小导致数据被清理将SW_CORE_DEFAULT_SAMPLING临时调至0.8,观察数据密度curl "http://oap:12800/oap/v3/metrics?name=service_cpm&serviceName=xxx"
5OAP启动报错java.lang.OutOfMemoryError: MetaspaceJVM Metaspace不足,类加载器泄漏在JAVA_OPTS中添加-XX:MetaspaceSize=512m -XX:MaxMetaspaceSize=1024mdocker exec oap jstat -gc 1 | awk '{print $9}'
6ES中sw_trace_day_*索引大量yellow状态ES副本分片未分配,通常因节点数<

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询