SkyWalking 8.5 ES7发行包部署实战:配置、调优与避坑指南
简介:面向微服务架构的可观测性实践,Apache SkyWalking 8.5.0 的 ES7 版本压缩包是专为分布式系统打造的 APM 工具,可直接用于链路追踪、性能指标采集与故障根因分析。整个包体共 508 个文件,体积约 176.25MB,以 365 个 jar 组成运行与插件体系,辅以 yml/yaml 配置、sh/bat 启停脚本、agent.config 探针配置及各类 license 声明,目录结构完整,开箱即可部署。包内整合 OAP 服务端、SkyWalking WebApp 控制台和 Java Agent,并已适配 Elasticsearch 7.x 存储,适合 Java 技术栈的开发者、运维及 SRE 快速搭建可观测平台。已有 372 人学习下载。借助该包,可省去源码编译和依赖适配过程,直接启动后就能通过拓扑视图、调用链和指标仪表盘定位性能瓶颈;还能按需修改 application.yml 对接既有 ES7 集群,或启用告警规则,是落地微服务监控体系的实用载体。
1. 一个带 es7 标记的安装包:存储选型定死,升级路线才好规划
看到apache-skywalking-apm-es7-8.5.0.tar这个文件名,先别急着解压。它说明两件事:你要装的是 SkyWalking 8.5.0,并且它的链路数据要落进 Elasticsearch 7.x。8.5.0 同时提供 es7、es8 两个发行包,二者在功能上几乎没有差别,差别在 storage 实现、索引模板和 REST Client 的兼容版本上。选错包,轻则写入报错,重则索引模板直接建不出来。这个包适合已有 ES 7.8 以上集群、想用自带 WebUI 快速拉起一套链路监控的团队,也适合内网交付场景里带着 tar 包离线分发。
很多人以为 APM 部署最难的是 agent 埋点,实际上等你把 OAP、ES、WebUI 三件套对齐后,agent 只是加一行启动参数的事。我见过太多团队盯着 agent 调了半天,最后发现是 OAP 把数据写进了错误的存储引擎。这个 es7 包存在的意义,就是把“存储层选型”这个最容易翻车的变量提前固定下来。不管你是给订单系统看 SQL 耗时,还是在 MES 制造执行系统里追踪工单状态转换的调用链,SkyWalking 都不挑业务形态,只挑存储。
2. 拆包与首次启动:tar 解出来的模块各司其职,先搞懂再动配置
拿到 tar 包后的第一件事不是tar -xf然后双击脚本,而是先想清楚包里面有三个角色:OAP 负责接收 agent 上报、聚合和写存储;WebUI 负责查询展示;agent 负责埋点采集。它们可以分开部署,也可以像这个发行包默认做的那样,由startup.sh一并拉起。理解了这个结构,后面所有配置都会有落点。
2.1 先看包结构:oap、webapp、agent 各有各的职责
先用tar -tf只列目录,不解压,确认包体完整性和根目录名:
tar -tf apache-skywalking-apm-es7-8.5.0.tar | head -30-t是列出内容,-f指定文件,head -30只看前面一部分。如果这里能看到bin/、config/、oap/、webapp/、agent/之类的目录,说明包结构正常。注意,这里特意用-tf而不是直接解压,因为 tar 包到了内网环境后经常被中间设备截断,先看列表能提前发现问题。
解压后你会得到一个apache-skywalking-apm-es7-8.5.0目录。bin/下是启停脚本,config/下是 OAP 的application.yml,oap/是服务端程序,webapp/是打包好的前端,agent/是 Java 探针。这个发行包和我后来自己用源码构建的区别在于:源码构建要自己准备 Maven 3.6.x 环境并逐个模块打包,而 tar 包直接把可运行产物给你了,适合快速交付。
2.2 启动前必改的 5 个配置项:存储地址、命名空间、分片副本
OAP 的所有存储配置集中在config/application.yml。我一般会先备份一份,再改下面这段:
storage: selector: ${SW_STORAGE:elasticsearch7} elasticsearch7: namespace: ${SW_NAMESPACE:skywalking} clusterNodes: ${SW_STORAGE_ES_CLUSTER_NODES:localhost:9200} indexShardsNumber: ${SW_STORAGE_ES_INDEX_SHARDS_NUMBER:2} indexReplicasNumber: ${SW_STORAGE_ES_INDEX_REPLICAS_NUMBER:0}selector是存储选择器,发行包已经默认指向elasticsearch7,不要手误改成 es8。clusterNodes填你的 ES 地址,多个节点用逗号分隔。namespace是索引命名空间,多套环境共用一个 ES 集群时,用不同 namespace 可以隔离数据。indexShardsNumber和indexReplicasNumber决定每天新建索引的分片数和副本数,默认 2 分片、0 副本,适合测试;生产环境有三节点 ES 的话,我一般会改成 3 分片、1 副本。
很多人改完配置直接启动,忘了检查 ES 侧是否已经就绪。ES 7.8 以上版本默认开放 9200 端口,如果你在配置里填了 9200 但 ES 实际跑在 9300,后面会看到一连串连接超时。这里有一个习惯:改完clusterNodes先用curl -s http://localhost:9200确认返回了带version字段的 JSON,再启动 OAP。
2.3 用 startup.sh 把 OAP 和 WebUI 拉起来,再确认 11800/12800/8080 三个端口
我第一次部署时直接./bin/startup.sh,然后干等,什么都看不到。正确做法是启动之后立刻盯日志,并检查三个端口:
tar -xf apache-skywalking-apm-es7-8.5.0.tar cd apache-skywalking-apm-es7-8.5.0 cp config/application.yml config/application.yml.bak ./bin/startup.sh sleep 15 tail -n 100 logs/skywalking-oap-server.logstartup.sh会后台拉起 OAP 和 WebUI,日志默认写在logs/目录下,WebUI 的日志在webapp/logs/。sleep 15是给 JVM 启动留时间,机器慢的话可以延长到 30 秒。看到日志里出现类似Server started的字样,说明 OAP 已经起来了。
接着验证三个端口:
curl -s -o /dev/null -w "%{http_code}\n" http://localhost:12800/health curl -s -o /dev/null -w "%{http_code}\n" http://localhost:8080/12800 是 OAP 的 HTTP 查询端口,8080 是 WebUI。如果第一个返回 200,说明 OAP 活着;第二个返回 200,说明前端可访问。注意,agent 上报用的是 11800 gRPC 端口,很多人会在这三个端口之间迷路,后面避坑章我会专门讲。
3. 把链路数据真正落到 Elasticsearch 7:索引与三个调优参数
OAP 进程起来只是第一步,真正的难点是让数据持续、可控地写进 ES7。这一章先讲索引长什么样,再讲参数怎么调,最后讲怎么从 ES 侧反推问题。
3.1 认识 skywalking_v9_ 索引:数据模型版本与包版本不是一回事
SkyWalking 8.x 的数据模型版本是 v9,所以你在 ES 里看到的索引名会以skywalking_v9_开头,这和软件版本 8.5.0 是两个概念。OAP 启动后会按天创建类似skywalking_v9_segment-20240925的索引,同时用别名skywalking_v9_segment暴露给查询。这里有一个容易困惑的点:索引名里带日期,但查询时走的是别名,不需要你手动指定日期。
看当前索引列表用这一条:
curl -s "http://localhost:9200/_cat/indices/skywalking_v9_*?v&s=index" | tail -20_cat/indices是 ES 的索引状态接口,s=index按索引名排序,tail -20只看最新一批。正常情况下你会看到segment、segment_traffic、service_meta、endpoint_meta等多个索引系列,每个系列按天拆分。如果这里只有模板没有数据索引,说明 OAP 和 ES 的连接虽然通,但上报链路还没走通。
ES7 只支持单 mapping 类型,所有字段类型都由 OAP 自动注册的模板定义。这也是为什么不能用 ES8 的包去连 ES7 集群:模板格式不兼容,字段类型会被错误解析,后面写入时就会出现 mapping 异常。
3.2 OAP 侧最值得先调的三个参数:bulkActions、flushInterval、concurrentRequests
存储配置里真正影响写入吞吐的,是下面三个参数:
bulkActions: ${SW_STORAGE_ES_BULK_ACTIONS:2000} flushInterval: ${SW_STORAGE_ES_FLUSH_INTERVAL:10} concurrentRequests: ${SW_STORAGE_ES_CONCURRENT_REQUESTS:2}| 参数 | 默认值 | 流量大时建议值 | 作用 |
|---|---|---|---|
| bulkActions | 2000 | 4000 | 攒够多少条批量写入一次,调大减少请求次数 |
| flushInterval | 10 秒 | 5 秒 | 最多等多久强制刷一次,调小降低数据延迟 |
| concurrentRequests | 2 | 4 | 同时执行 bulk 请求的并发数,调大提升写吞吐 |
这三个参数是联动的。bulkActions决定攒批的条数,flushInterval决定攒批的最长时间,concurrentRequests决定同时能发多少个 bulk 请求。默认值是给中小规模场景用的,每秒 500 条 Trace 以内可以不动;每秒 2000 条以上,我一般把bulkActions提到 4000、flushInterval降到 5、concurrentRequests提到 4。
但要注意,这三个参数不是孤立的,ES 侧的写入能力和它们互相制约。concurrentRequests调大后,ES 的 bulk 队列和 CPU 使用率会明显上升。如果 ES 节点只有 2C4G,建议保持默认concurrentRequests=2,不然你会看到 ES 频繁触发RejectedExecutionException。调参的正确顺序是:先看 ES 侧负载,再动 OAP 侧并发,最后才动批量大小。
3.3 从查询响应反推调优是否到位:看写入延迟、看 segment 数、看队列
参数调完不是看 UI 变快,而是看 ES 侧的实际反应。第一步是查 OAP 日志里有没有批量写入相关的告警:
grep -i "bulk\|flush\|rejected" logs/skywalking-oap-server.log | tail -50如果日志里频繁出现RejectedExecutionException或者 bulk 重试,说明 ES 写入跟不上,而不是 OAP 出了问题。这时候不要盲目把concurrentRequests继续调大,先看 ES 的 CPU 和堆内存是否已经吃紧。
第二步是看 segment 数。segment 是 ES 底层不可变分段,数量太多会导致查询变慢:
curl -s "http://localhost:9200/_cat/segments/skywalking_v9_segment-*?v&s=docs.count:desc" | head -20单索引的 segment 数量如果长期维持在几十上百,说明 merge 策略没跟上升级速度。这常常是因为 OAP 写入节奏过快、ES 的 merge 线程来不及合并。解决方向是调 ES 的indices.store.throttle.max_bytes_per_sec,或者减少分片数,而不是继续加 OAP 并发。
还有一个容易被忽略的点:ES 7.8 以上支持 ILM 索引生命周期管理。如果你没在 OAP 配置里启用,旧索引会一直堆积,占满磁盘。常见做法是在存储配置里打开 ILM 策略,按天滚动索引并设置保留天数。我自己一般保留 7 天,链路数据超过 7 天基本只有排障时才查,留太久成本不划算。
4. 避坑笔记:这套 es7 包让我翻过车的 5 个地方
下面的每一条都是我在不同环境里攒下的血泪经验,按“现象 → 原因 → 解决”的顺序写,方便排查时对照。
4.1 现象:OAP 起来后日志报 no handler found for type
OAP 启动时日志里出现类似No handler found for type [xxx]的异常,大多数情况是存储选择器配置和包版本不匹配。比如你拿到的是 es7 包,但application.yml里storage.selector被改成了别的值,OAP 就找不到对应的存储实现。
先检查当前生效的配置:
grep -A 2 "storage:" config/application.yml重点看selector后面的值。es7 包应该保持elasticsearch7。如果你之前手动编译过源码,还要注意 Maven 环境的版本,换用 Maven 3.6.x 重新构建后再替换配置。
这条坑还有一个变种:有人把 OAP 目录从 Windows 复制到 Linux,application.yml的换行符变成\r\n,导致配置解析异常。用sed -i 's/\r$//' config/application.yml转一下就好。
4.2 现象:agent 端显示已连上,UI 里看不到任何 Trace
这个是最常见的翻车场景。UI 页面能打开,agent 进程也正常,但 15 分钟过去一条 Trace 都没有。原因大概率是 agent 的上报地址写错了端口。
SkyWalking 的 agent 走 gRPC 上报,端口是 11800,不是 UI 查询用的 12800。很多人把collector.backend_service填成了127.0.0.1:12800,gRPC 握手失败后 agent 会不断重试但界面不报错。正确的启动参数是这样:
java -javaagent:/opt/apache-skywalking-apm-es7-8.5.0/agent/skywalking-agent.jar \ -Dskywalking.agent.service_name=order-service \ -Dskywalking.collector.backend_service=127.0.0.1:11800 \ -jar app.jaragent.service_name决定 UI 里的服务名,collector.backend_service必须指向 OAP 的 gRPC 端口。启动后去agent/logs/skywalking-api.log看有没有gRPC相关的错误,没有错误且出现Segment上报日志,说明数据进来了。
排查时还有一个技巧:测试环境把采样率临时调到 100%,保证能看到样例;生产再调回默认值。如果你调了采样率还是没有 Trace,再检查 OAP 和 agent 的 namespace 是否一致,不一致会导致服务名被改写,数据能进但查不到。
4.3 现象:es7 包误连到 ES8 集群,一写数据就是 mapping 异常
OAP 日志里大量出现mapper [xxx] of different type或failed to parse field时,先别急着调参数,确认你的 ES 到底是大版本几。
curl -s http://localhost:9200 | grep cluster_nameES 8 的 REST 响应里带version.number,一看便知。如果你手里只有 es7 包但集群是 ES8,直接把发行包换成对应的apache-skywalking-apm-es8-8.5.0.tar重新部署。这不是玄学,是包和存储的大版本不匹配,ES8 的 rest client 对索引模板的处理方式和 ES7 不一样,强行混用只会越调越乱。
这条坑的教训是:接手任何一套 SkyWalking 环境,第一件事问清楚 ES 大版本,再决定用哪个发行包。
4.4 现象:解压 tar 后 webapp 起不来,报 Permission denied
webapp无法启动且日志里出现Permission denied,一般是解压方式不对导致可执行权限丢失。特别是从 Windows 或者 NAS 上下载后解压,文件权限位经常被重置。
在 Linux 上重新解压,并补上可执行权限:
chmod +x bin/*.sh webapp/bin/*.sh ./bin/startup.sh如果你确实需要在 Windows 上解压,Windows 10 自带tar.exe,可以直接tar -xf apache-skywalking-apm-es7-8.5.0.tar解压。一个不建议的操作是把 tar 包后缀改成 zip 再用资源管理器双击解压,那样符号链接和权限都会丢失,拿到 Linux 上大概率跑不起来。
4.5 现象:agent 版本比 OAP 新一大截,数据时断时续
UI 里有些服务有数据,有些服务没有,agent 日志里能看到 gRPC 协议错误。这通常是 agent 和 OAP 的版本跨度太大,接口字段对不上。
SkyWalking 的 agent 和 OAP 通过 gRPC 通信,不同的 8.x 小版本之间兼容性尚可,但跨大版本就会出现字段缺失或多余的问题。我的做法是保持 agent 与 OAP 同版本,比如 OAP 是 8.5.0,agent 就固定用 8.5.0。如果你线上已经混用了多个版本,先统一升级到同一大版本,再逐个收敛 agent。
版本对齐这件事,值得写进 APM 运维规范。很多线上问题最后都不是配置问题,而是版本漂移。
5. 进阶:用 tar 与 xargs 批量铺开,把日常验证变成十分钟脚本
当你有多套环境要部署时,手工一个个tar -xf实在太慢。而且 APM 这种基础组件,环境越多,越需要统一的操作方式。
5.1 批量解包与统一放置的最小命令
把下载目录里所有 es7 相关的安装包解压到统一目录,用tar加xargs一次搞定:
mkdir -p /opt/skywalking/ find /data/pkg -type f -name "apache-skywalking-apm-es7-*.tar" -print0 | \ xargs -0 -I {} tar -xf {} -C /opt/skywalking/find的-print0和xargs的-0是为了处理文件名里带空格的情况,-I {}表示逐个替换包名。这条命令的价值在于:无论有几个版本的安装包,只要命名符合apache-skywalking-apm-es7-*.tar的模式,都会自动被解压到/opt/skywalking/,不会遗漏。
如果是要跨机器传整套环境,我习惯先打成压缩包再传:
tar -czf skywalking-es7-8.5.0-bundle.tgz apache-skywalking-apm-es7-8.5.0/注意这里加了-z做 gzip 压缩,和原始的.tar不一样,传输更快。目标机器上再用tar -xzf恢复。
5.2 把配置和 agent 插件一起打包:换环境不再靠后悔药
环境 A 调试好的application.yml、agent/plugins里启用的插件,要同步到环境 B 时,不要一个个文件复制,用 tar 打包相对路径更保险:
tar -cf oap-env-backup.tar \ -C apache-skywalking-apm-es7-8.5.0 \ config agent/plugins webapp/webapp.yml-C先切到包根目录,后面的路径都是相对路径。这样恢复时不会覆盖到包目录之外的位置,避免把别的东西冲掉。
恢复同样简单:
tar -xf oap-env-backup.tar -C /opt/new/apache-skywalking-apm-es7-8.5.0/恢复后记得检查webapp/webapp.yml里的端口,新环境可能已经有服务占用 8080,冲突的话 UI 会起不来。
5.3 日常验证脚本:探活、索引增长、最近 Trace 三连
我现在每接管一套 SkyWalking,第一件事就是把下面这个脚本放进 crontab,每天自动跑:
#!/usr/bin/env bash OAP_HTTP=localhost:12800 UI_HTTP=localhost:8080 ES_HTTP=localhost:9200 curl -s -o /dev/null -w "oap=%{http_code}\n" $OAP_HTTP/health curl -s -o /dev/null -w "ui=%{http_code}\n" $UI_HTTP/ curl -s "$ES_HTTP/_cat/indices/skywalking_v9_segment-*?h=index,docs.count&s=index:desc" | head -3OAP 的 health 返回 200 说明服务存活,UI 返回 200 说明前端可用,索引列表里能看到当天的skywalking_v9_segment且 docs.count 在上涨,说明数据链路是通的。如果前两项正常但索引不涨,直接顺着 4.2 的路径查 agent 上报。
这套脚本帮我挡掉了不少“半夜被叫起来看为什么没有数据”的场面。半年后再看,版本、端口、ES 大版本这些信息早就该写进交接文档了,而不是等出事再翻。希望帮到你。
本文还有配套的精品资源,点击获取