这套东西我用了大半年,从最开始一头雾水到后来给十几个服务全部接上,中间踩的坑不少。如果你正被线上接口时不时慢几秒、数据库压力忽高忽低、多服务调用链路上出了问题不知道先查谁这些问题折磨,那这篇文章应该能帮你省下至少两天的摸索时间。我会从零开始,把Skywalking的前置概念、服务端安装、Java应用接探针、常见坑一次讲完,尽量做到你照着敲就能跑起来。
先说清楚一件事:Skywalking是干什么的。它是国内开源圈用得比较多的APM系统,也就是应用性能监控。在微服务架构下,一次用户请求往往要经过网关、多个业务服务、Redis、数据库、MQ,任何一个环节变慢,整个接口都会跟着慢。以前排查这种问题靠翻日志,一个个服务去查,效率极低。Skywalking做的事,就是通过无侵入的探针把整个请求链路串起来,把每一段调用耗时、调用关系、异常信息都展示在同一个界面里。所谓分布式监控,最重要的就是链路追踪和可视化这两个能力。
这篇文章适合几类人看:正在搭建监控体系的开发或运维,刚接触微服务想搞懂全链路追踪怎么做的新人,以及已经装了Skywalking但遇到各种报错搞不定的朋友。内容组织上,我会先讲核心架构和概念,再讲安装部署,然后是Agent接入,最后是常见问题排障和实战经验,全程基于8.9.1版本展开,这也是目前用得最稳的版本——9.x改动比较大而8.x生态成熟资料多,你如果只想快速落地就选8.9.1,不会有毛病。
1. 先搞懂Skywalking的核心架构与工作原理
1.1 链路追踪的基本概念:Trace、Span、Segment
在动手指安装之前,一定要搞懂Skywalking里几个基础概念,不然你看界面会一脸懵。
链路追踪的模型是这样的:一次用户请求从入口进来,会跨多个服务完成。Skywalking把这次完整请求叫一个Trace,中文叫链路。整个链路被拆成很多个Span,每个Span代表链路中的一次具体调用行为,比如A服务调用了B服务的某个接口,这个过程就是一个Span。Span和Span之间有父子关系,通过TraceId关联在一起。
这里还有一个概念叫Segment,它指的是单个服务实例内产生的一组Span集合。打个比方,你去办一件事,先到A窗口填表,再到B窗口盖章,再到C窗口领证,整件事就是Trace,每个窗口的办理动作是Span,而你在B窗口里填表、排队、递交材料这些小动作组合起来就是一个Segment。理解了这层关系,你在界面上看链路详情时就会踏实很多:Trace是全局视角,Segment能告诉你某一个服务内部到底发生了哪些事。
Skywalking的Agent会负责自动生成这些数据,不需要你手动埋点。它基于字节码增强技术,在应用启动时通过Java Agent挂载探针,对很多主流框架如Spring Cloud、Dubbo、gRPC、JDBC驱动、Redis客户端等自动做字节码层面的插桩,把每次RPC、HTTP调用、SQL执行、缓存访问的耗时和上下文信息采集下来,然后通过gRPC上报给OAP服务端。
1.2 三个核心角色:Agent、OAP、UI
Skywalking整体分三部分,理解这三个角色你排障时才会知道问题出在哪一环。
- Agent:部署在业务应用进程内的探针。它负责采集数据、生成Trace和指标,通过gRPC协议上报给后端。对Java应用来说,就是一个jar包,启动时通过
-javaagent参数挂载进去,不需要改业务代码。 - OAP(Observability Analysis Platform):这名字很直白,就是负责接收、解析、聚合、存储数据的后端服务。Agent上报的链路数据、指标数据、日志数据都汇聚到这里。OAP会把Trace数据整理成拓扑关系和指标,再写入存储系统。它有gRPC端口11800和HTTP端口12800,一个给Agent上报用,一个给UI或外部调用查询用。
- UI:Skywalking的Web可视化控制台(默认端口8080)。你在这里看拓扑图、链路详情、告警信息、性能剖析结果。UI本身不保存数据,所有数据都从OAP的HTTP接口实时拉取。
这三个组件是上下游关系:Agent采集上报,OAP处理存储,UI展示查询。链路数据从采集到展示,完整路径是:业务应用中的Agent -> gRPC上报到OAP -> OAP写入存储(默认H2,生产一般用ES) -> UI从OAP查询并渲染。
1.3 为什么选Skywalking:对比Zipkin和Pinpoint
很多朋友会纠结监控工具怎么选。目前开源的APM方案里,Zipkin、Pinpoint、Skywalking是常被放一起比较的三个。
Zipkin侧重Tracing,安装简单,但只有链路追踪功能,没有指标聚合、告警、拓扑图这些能力,而且它对主流组件做的是框架级埋点,覆盖度不如字节码增强的Agent。Pinpoint做链路追踪确实强大,UI交互也很炫,但组件相对重,数据模型复杂,代码侵入性略强,性能损耗相对偏高。Skywalking的优势在于:一是Agent无侵入,业务零改动,插件生态覆盖广,从网关到数据库到消息队列都有现成插件;二是功能齐全,链路追踪、服务拓扑、指标看板、告警、日志集成都有了;三是支持多种存储后端,单机测试用H2开箱即用,生产切ES,数据量大了也不成问题;四是社区活跃,文档中文资料多,遇到问题基本都能搜到解决方案。
从我生产环境的实际使用感受看,Skywalking的Agent对服务本身的性能影响基本控制在5%以内,在可接受范围内,而且必要时候可以按需关闭部分插件或调整采样率。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 安装前的版本选择与部署规划
2.1 版本选择建议:8.9.1是当前最稳的起点
Skywalking的版本演进比较快,目前主流的稳定分支是8.x和9.x。8.x系列里我个人比较推荐8.9.1,因为在8.x里相对完善,和各大主流的微服务框架、中间件版本兼容性经过了比较多验证,网上遇到的问题和解决方案也积累得很多。9.x改动很大,比如支持了集群模式在UI里的可视化配置、告警规则配置更细,还引入了新的存储结构,对刚上手的朋友来说,踩坑成本会比8.x高一些。
还有一个需要特别注意的是Agent和服务端的版本匹配问题。Skywalking对Agent和服务端的版本一致性要求比较严格,Agent小版本号最好和服务端保持大版本一致。比如服务端用8.9.1,Agent也用8.9.1,不要服务端用9.x、Agent用8.x,否则上报时会出现协议不兼容、数据不显示的问题。这是新手最容易忽略的地方。
2.2 部署架构选型:单机测试还是生产集群
先说单机部署,也就是开发或测试环境。一台Linux服务器或Windows机器就够了,装好JDK 8+,下载官方发行版,解压后直接启动OAP和UI,存储用默认的H2即可。H2是Skywalking内置的嵌入式数据库,装完就能用,零配置,开箱即此,不需要额外安装。但H2只适合小数据量场景,生产环境千万不要用,数据量一大就会卡死或者丢数据。
生产环境部署,建议做OAP集群,存储用ES。OAP可以多节点部署,通过Nacos或ZooKeeper等注册中心或者gRPC集群发现机制实现节点互相发现,数据统一写入ES集群。UI前面还可以加一层Nginx做访问入口和认证。不过这里先不展开太多,后面我会给出一套生产级的Docker Compose方案。
2.3 安装前的环境准备清单
在动手之前,你需要确认以下内容:
- JDK:服务端OAP要求JDK 8或以上,建议装JDK 8+或者JDK 11都行,不要只装JRE,因为OAP启动脚本还需要javac等工具链里的能力。
- 内存:OAP默认会分配JVM内存,单机测试至少要有2G可用内存,生产环境视数据规模而定,我见过最少的4G,多的32G,先按服务规模来。
- 端口:确认11800(gRPC)、12800(HTTP)、8080(UI)这三个端口没有被占用。
- 时间同步:所有服务节点,包括Agent所在业务应用服务器、OAP服务器,时间要同步,不然链路数据的时序会乱了,排查问题都会误导你。用NTP同步一下就好。
- 防火墙/安全组:生产环境别把11800和8080暴露到公网。业务服务器需要能访问OAP的11800端口,管理员或你需要访问8080查看面板。
确认完这些,就可以进入安装了。
3. 服务端安装:一步一步从零跑起来
3.1 下载与目录结构解析
去Skywalking官网下载中心,选择Apache SkyWalking 8.9.1 for H2/MySQL/TiDB/PostgreSQL(带BanyanDB的不建议新手用,BanyanDB是SkyWalking自研的时序数据库,生态还不算特别成熟)。下载的是apache-skywalking-apm-8.9.1.tar.gz压缩包,大概两百多MB。
下载完成后解压。如果你是Windows,用解压工具解压到比如D:\skywalking目录;Linux或者macOS用命令:
bash复制cd /opt
wget https://archive.apache.org/dist/skywalking/8.9.1/apache-skywalking-apm-8.9.1.tar.gz
tar -zxvf apache-skywalking-apm-8.9.1.tar.gz
mv apache-skywalking-apm-bin skywalking
cd skywalking
解压后的目录结构大致如下:
bin/:启动脚本核心目录,oapService.sh是启动OAP的脚本,webappService.sh是启动UI的脚本,startup.sh会一次启动两者。Windows对应的是.bat文件。config/:OAP服务端配置目录,application.yml在这里,是OAP最核心的配置文件。webapp/:UI服务的配置目录,webapp.yml在这里,用来配置UI访问端口和OAP地址。oap_libs/:OAP运行依赖的jar包集合。agent/:Java探针目录,skywalking-agent.jar在这里,后面给Java应用接入时会用到。licenses/:开源协议文件。
看清楚结构和启动脚本,安装基本就成功一半了。很多朋友解压完直接双击startup,结果启动失败又不知道该查哪个文件,就是没弄清这些目录各管什么。
3.2 默认配置首次启动与日志查看
先不要改配置,直接启动一次。进入bin目录:
bash复制cd /opt/skywalking/bin
./startup.sh
Windows就双击或命令行执行:
cmd复制cd D:\skywalking\bin
startup.bat
启动后大约等20~30秒,OAP初始化存储、加载插件需要一点时间。这时看一下日志确认是否成功:
bash复制tail -f /opt/skywalking/logs/skywalking-oap-server.log
看到类似OAP start successfully的字样就是成功了。UI日志在logs/webapp.log,如果UI启动失败会在这里体现。如果端口被占用,OAP的日志会直接报BindException或者Address already in use,那就换端口或者清理占用进程。
启动成功后,浏览器访问http://服务器IP:8080,如果能看到Skywalking的Web界面,说明服务端已经全部起来了。第一次打开,UI上一片空白是正常的,因为还没有任何Agent上报数据。此时打开浏览器调试工具,能看到UI在请求http://服务器IP:12800的后端接口,这是UI从OAP拉数据的过程,只要这里能通,说明UI和OAP链路正常。
3.3 OAP核心配置项说明
等验证完默认启动OK,就该看几个关键配置项了。OAP的application.yml是核心,里面有几处你迟早要改。
- 端口配置:
core模块下,gRPC/plain的端口对应11800,rest端口对应12800。默认值就行,但如果你有端口冲突,要在这里改。注意Agent上报地址里面的端口也要对应改。 - 存储配置:
storage/selector决定用什么存储,默认是${SW_STORAGE:h2}。这段写法表示用的H2,如果你要通过环境变量强制覆盖,就把SW_STORAGE设置为elasticsearch或mysql。 - 关闭默认的采样限制:
core模块里的default配置项有sampling相关设置。生产上如果不想丢链路数据,记得确认采样率是100%,不过注意数据量会上升。 - gRPC线程池:
receiver-sharing-server和receiver-trace等模块里的workerCacheSize等参数,默认够用,不推荐新手乱调。
这里要强调一下环境变量覆盖配置的机制:Skywalking的配置文件里很多配置项形如${SW_STORAGE:h2},这是环境变量加默认值的写法。启动OAP前可以通过设置环境变量来覆盖配置,比如设置SW_STORAGE=elasticsearch切存储,设置SW_NAMESPACE区分多环境。启动脚本用export设置即可。因为生产环境不建议直接改application.yml,用环境变量管理配置更方便容器化和多环境部署。
3.4 Docker方式快速部署
如果你不想在宿主机上装JDK,或者想快速起一个带ES的完整环境,推荐用Docker Compose。Skywalking官方在GitHub仓库提供了编排模板,但那个版本比较新,依赖的ES版本也比较高。这里给一个我自己修改过、验证可用的精简版方案。
先创建一个docker-compose.yml:
yaml复制version: '3.8'
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:7.17.9
container_name: es
environment:
- discovery.type=single-node
- xpack.security.enabled=false
- ES_JAVA_OPTS=-Xms1g -Xmx1g
ports:
- "9200:9200"
volumes:
- es_data:/usr/share/elasticsearch/data
networks:
- skywalking
oap:
image: apache/skywalking-oap-server:8.9.1
container_name: oap
depends_on:
- elasticsearch
environment:
- SW_STORAGE=elasticsearch
- SW_STORAGE_ES_CLUSTER_NODES=elasticsearch:9200
- SW_HEALTH_CHECKER=default
ports:
- "11800:11800"
- "12800:12800"
networks:
- skywalking
ui:
image: apache/skywalking-ui:8.9.1
container_name: skywalking-ui
depends_on:
- oap
environment:
- SW_OAP_ADDRESS=http://oap:12800
ports:
- "8080:8080"
networks:
- skywalking
volumes:
es_data:
networks:
skywalking:
driver: bridge
执行:
bash复制docker-compose up -d
容器启动后,等待一分钟左右让ES和OAP完成初始化,然后访问8080端口。这套方案的好处是环境干净,不污染宿主机,而且ES存储从一开始就是配置好的,不是H2。后面要把这个环境用在生产,只需要调大ES的JVM参数,把ES节点从单节点改成multi-node即可。
4. Java应用接入Agent:核心实操环节
4.1 Agent目录与配置优先级
服务端就跑起来了,现在是重头戏:把业务应用接进来。进入解压目录下的agent/文件夹,你会看到:
skywalking-agent.jar:探针主包,启动时通过-javaagent指定它即可。config/agent.config:默认的Agent配置文件。plugins/:各种插件jar包,比如spring-cloud-gateway-plugin-xxx.jar、dubbo-plugin-xxx.jar、jdbc-plugin-xxx.jar等,框架的自动插桩能力全在这里。绝大多数情况你不需要动这个文件夹,除非有特定的插件版本冲突。
Agent配置遵循一个优先级规则:系统属性 > 环境变量 > agent.config配置文件。简单说,你在JVM启动参数里用-D设置的配置项优先级最高,会覆盖配置文件里的默认值;然后是环境变量,形式是把配置项的点号换成下划线并加上大写的SW_前缀。比如配置文件里的agent.service_name,对应环境变量SW_AGENT_NAME,系统属性是-Dskywalking.agent.service_name。这个规则特别重要,因为同一种配置在不同部署环境生效范围不一样,尤其要注意在Docker容器化时环境变量和启动参数的差异。
4.2 Agent核心配置参数详解
打开agent/config/agent.config,你会看到几十个配置项,但大多数保持默认就行,核心需要了解的就这几个:
- agent.service_name:服务名称。这决定了在UI拓扑图上一台服务显示的叫什么名字,非常关键。默认是
Your_ApplicationName,一定不能忘记改。如果不改,多个应用上报后全部显示同一个名字,链路完全没法看。 - collector.backend_service:OAP的gRPC地址,默认是
127.0.0.1:11800。如果Agent和OAP不在同一台机器,这里必须改成OAP服务器的IP和端口。 - agent.sample_n_per_3_secs:采样率配置,单位是每3秒采样多少条链路。默认值是一个比较保守的数,但如果你要做全量追踪,可以把它调大,比如设成
-1代表关闭采样,全量上报。生产环境根据流量定,流量大建议设置合理的采样值。 - agent.logging.level:Agent自身日志级别,默认
INFO,排障时临时调到DEBUG能帮你看清Agent到底有没有上报数据、有没有报错。 - agent.ignore_context:忽略特定路径,不太常用,但如果有健康检查或者非关键接口刷屏,可以在这里设置忽略。
每次修改配置文件的建议是,先在命令行参数或环境变量层面覆盖,而不是直接改默认配置文件。这样可以保证同一个Agent压缩包在多个环境通用,避免配置文件的漂移问题。
4.3 给SpringBoot项目加入探针:完整示例
这是最常用也是最容易出错的场景。假设你有一个SpringBoot服务,原先启动命令大概是:
bash复制java -jar my-order-service.jar
加了Skywalking探针之后,启动命令变成:
bash复制java -javaagent:/opt/skywalking/agent/skywalking-agent.jar \
-Dskywalking.agent.service_name=my-order-service \
-Dskywalking.collector.backend_service=192.168.1.100:11800 \
-jar my-order-service.jar
这里逐个拆解每个参数:
-javaagent:后面的路径是探针jar包的全路径,如果是Windows环境,路径用正斜杠或反斜杠都可,建议放到一个没有空格的目录,比如D:\skywalking\agent\skywalking-agent.jar。-Dskywalking.agent.service_name=my-order-service:给这个服务的命名,必须唯一且有意义。用中划线分隔的命名风格最佳。-Dskywalking.collector.backend_service=192.168.1.100:11800:前面写OAP服务器的实际IP,不是127.0.0.1。这个配置我见过太多人忘记改,导致Agent一直上报到本机,而本机根本没起OAP,日志里全是连接失败。
在IDE里调试时,在启动类的VM options里填入同样的参数即可。比如IDEA的Run/Debug Configurations -> VM options里写:
code复制-javaagent:D:\skywalking\agent\skywalking-agent.jar
-Dskywalking.agent.service_name=my-order-service
-Dskywalking.collector.backend_service=192.168.1.100:11800
这样IDE启动也一样能被采集到,开发阶段看链路很方便。
4.4 Agent接入后的验证方法
启动应用后,先看Agent自己的日志确认没有异常。Agent日志在logs/目录下,默认文件名是skywalking-agent.log。重点看有没有类似Plugin [xxx] activated的启动日志——这说明插件加载成功了。接着看有没有Connection to OAP failed这类报错,如果有,大概率是网络不通或者端口没开。
然后访问一下你的业务接口,制造一点流量,再去Skywalking UI查看。正常情况下,过十几秒UI的拓扑图和服务列表中就会出现你的服务了。如果过了几分钟还是没有数据,按下面步骤排查:
- 确认Agent启动参数真的生效了,可以在应用启动日志里搜
skywalking关键词,能看到Agent打出的banner日志。 - 确认网络连通,在业务服务器上执行
telnet OAP服务器IP 11800,看端口通不通。 - 确认OAP的日志没有代理上报的报错,比如
gRPC receiver相关的错误信息。 - 回到Agent配置文件,把
agent.logging.level临时改成DEBUG,重启后观察Agent日志里的上报逻辑。
这套排查顺序几乎能解决大部分Agent不上报的问题。
4.5 非Java语言应用接入简介
生产环境肯定不止纯Java。Skywalking官方目前也提供了Go(skywalking-go)、Python(skywalking-python)、Node.js(skywalking-nodejs)、Lua等语言的Agent或SDK,通过gRPC和OAP通信,链路模型和Java端是同一个体系。Python和Node.js基本都是通过SDK在应用代码里做简单的初始化,并加入中间件插件来采集,不再像Java那样完全无侵入。如果你的技术栈是Go,要注意Go的探针是有版本限制的,它通过Go的-buildmode=plugin插桩方式实现,接入方式上比Java稍麻烦,需要额外开一个SKWAgent。这里不展开每个语言的具体写法,实际使用的时候去官方文档查对应语言的README即可,核心思路是一致的:注册Agent、配置collector地址、应用框架的HTTP/RPC插件负责埋点。
5. Skywalking界面核心功能与使用技巧
5.1 服务拓扑图:一眼看穿系统依赖
打开UI,默认就会进入拓扑图页面。你可能从一个空的界面看到各个服务以圆点的形式分布在图中,有连线代表有调用关系。连线的粗细和颜色代表请求量、健康程度和延迟,在这个图上能特别直观地看到所有服务的上下游依赖。
我第一次用的时候特别震撼,一张图把十几个服务谁调谁、调用频率多高全画出来了。尤其做架构汇报或者新人上手讲解系统,这个页面截个图比什么文档都好使。
拓扑图页面有几个隐藏功能值得试试:
- 每个节点上可以点击,看这个服务的指标详情、告警事件、实例列表。
- 拖动任意节点可以调整位置,方便截图。
- 右上角可以切换时间范围,比如你刚发布了一个新版本,切到最近5分钟,拓扑图上的异常和延迟一目了然。
5.2 链路追踪数据怎么看:从Trace到Span的具体排障
这是Skywalking最核心的功能,也是定位问题的主要入口。在UI左侧找到"追踪"页面,按时间范围、服务名、端点名、TraceId查询链路列表。每一行链路的展示字段有URL、总耗时、状态(成功/失败)、跨度数量。选一条慢的或失败的链路点进去,会看到刚才讲的Trace视图。
链路详情页按时间轴展开了一整条请求的所有Span。每个Span能看到:
- 是哪个服务的哪个方法或接口
- 调用了哪个下游组件(如SQL、Redis、MQ)
- 开始时间和耗时
- 有没有异常和错误堆栈
- 上下游Span的父子关系和层级
排障时只要顺着一层层看耗时,很快就能定位到最耗时的Span。比如有一次用户反馈下单慢,我在链路详情里发现耗时基本全花在了一个数据库更新操作的SQL上,结果一查是表缺索引。这种问题在以前的排查模式下可能要翻半天日志才能定位,现在直接看到SQL耗时和具体语句,节省了太多时间。
链路里还有一个非常赞的功能:每个Span都保存了完整的HTTP请求头、请求体、响应状态,点开就能看到实际传参,排查参数传递错误和返回异常特别方便。不过要注意生产环境日志脱敏,Skywalking提供了脱敏和忽略敏感参数的插件apm-trace-ignore-plugin,建议配置上,避免敏感信息上报。
5.3 服务指标与实例健康看板
除了链路追踪,Skywalking也提供了多种维度的指标监控。在"仪表盘"页面,默认有很多模板,可以切换查看服务的全局指标、实例指标和端点指标。常用的指标包括:请求平均响应时间、吞吐量(CPM)、成功率、JVM内存使用、Full GC次数、CPU使用率、线程数等。
这些指标直接来自Agent采集和OAP的聚合,不需要额外部署探针。对于Java服务,JVM监控尤其实用,你可以在不接Prometheus的情况下就能看到堆内存使用曲线、GC暂停情况,对于排查内存泄漏和GC问题非常有帮助。
注意一个细节:指标数据默认会按分钟聚合,太细时间粒度(比如秒级)在大跨度时间范围内会被自动降精度,这是性能优化设计,不是丢了数据。所以如果你查一个7天的趋势图看到几分钟一个点,是正常的。
5.4 告警功能配置与通知
Skywalking自带告警能力,虽然不如Prometheus那么灵活,但胜在和链路数据一体化,不需要额外配置数据源。告警规则在OAP服务端的config/alarm-settings.yml文件里定义,默认已经内置了一些规则,比如服务响应时间超阈值、服务成功率下降、JVM GC时间过长等。
你需要重点了解的是怎么改成自己的规则,以及怎么通知到钉钉或企业微信。以钉钉为例,在alarm-settings.yml里配置一个hook:
yaml复制rules:
service_resp_time_rule:
metrics-name: service_resp_time
op: ">"
threshold: 1000
period: 10
count: 3
message: 服务 [{name}] 的平均响应时间在最近10分钟内超过1秒
webhooks:
- type: dingtalk
url: https://oapi.dingtalk.com/robot/send?access_token=xxxxxxxx
这段配置的含义是:对名为service_resp_time的指标,在10分钟窗口内,如果超过阈值1000毫秒的次数达到3次,就会触发告警并发送到钉钉机器人。op除了>,还支持>=、<、<=等比较运算符。
告警配置改完要重启OAP才生效。排障告警不触发时,先确认是不是规则里的metrics-name写错了,可以在UI的仪表盘里找到对应指标的标准名称做对照。
5.5 性能剖析:定位代码级瓶颈
性能剖析(Profiling)是Skywalking的高级功能,也是很多资料里不常细讲的宝藏。它允许你在不重新部署、不中断服务的情况下,对指定服务、指定端点进行短时间的方法级采样,抓取一个请求执行过程中的调用栈和每个方法的耗时。
这个功能在定位慢方法时比链路追踪更细致。链路追踪只能到Span级别,比如告诉你SQL慢、HTTP调用慢,但如果一个纯本地计算方法异常耗时,链路里是看不出来的。性能剖析可以把这段逻辑拆开,定位到具体是哪个类哪个方法卡了多久。
使用的时候,在拓扑图或追踪页面找到目标服务,选择"性能剖析"开启对某个端点的采样,设置采样时间(比如5分钟),然后去触发几次压力请求。采样完成后,UI会生成每个方法的调用树和耗时分布。我用了好多次,有几个优化点就是这样直接捞出来的。
6. 常见问题排查与生产实践建议
6.1 高频问题速查表
结合我自己和身边朋友遇到的典型问题,整理成一张速查表:
| 现象 | 可能原因 | 排查方法 |
|---|---|---|
| UI连不上OAP | OAP没启动或端口没监听 | 检查11800/12800端口,`netstat -anp |
| Agent启动日志报Connection refused | collector.backend_service配错 | telnet OAP_IP 11800测连通性 |
| 服务端一切正常但UI无数据 | Agent没接上或上报延迟 | 触发几次请求等30秒,看Agent日志的Debug级别 |
| UI看到两个同名服务但内容不同 | service_name配置重复 | 检查每个应用的启动参数,改成唯一服务名 |
| SQL语句没有采集到 | 数据库驱动版本太新或太老 | 到plugins/目录看是否有对应驱动的插件版本,必要时升级 |
| ES存储方式下UI查询特别慢 | ES索引分片或OAP的TTL没优化 | 检查ES索引segment-*数量,调整OAP数据TTL |
| 找不到Docker Compose里UI的http接口 | UI页面在通过webapp.yml指向OAP的12800 | 确认SW_OAP_ADDRESS环境变量是否正确 |
| 容器内Agent报连接失败但本机telnet正常 | 容器网络没有映射或跨界 | 用--network host或确认端口映射完整 |
这张表我已经把日常中遇到概率最高的几个情况列进去了。大部分排障的根本思路就一条:顺着数据流向层层查。Agent -> gRPC -> OAP -> 存储 -> UI,一段一段确认通不通,问题基本能定位。
6.2 存储方案选型建议:H2、ES还是MySQL
Skywalking支持多种存储,但适合的场景不一样。
H2:开发测试首选。零部署,启动OAP自动建库。但H2是嵌入式数据库,数据写满后文件会膨胀,也不支持分布式,不适合并发量大的场景。
ES:生产环境主流选择。大数据量写入和聚合查询效率高,官方也围绕ES做了很多优化,比如索引模板、ILM、数据滚动等。要让ES索引和Skywalking版本匹配,8.9.1版本建议配ES 7.x。ES的JVM堆内存要给够,至少1G起步,生产按数据量给8G到16G。
MySQL/TiDB/PostgreSQL:中低数据量可用,适合那种不想单独维护ES集群的中小团队。但链路数据多行存储,写入压力大,MySQL在高并发写入下会成为瓶颈。如果你确定要长期用MySQL,注意定时清理历史数据。
我的建议是:测试环境H2,正式环境直接上ES。ES集群如果团队没人管,可以先用托管云数据库或简单单节点ES起步,规避运维复杂度。
6.3 生产接入渐进式推进的经验
这里分享几条我实际部署中总结的经验,希望你能避开。
先从边缘服务开始试。刚接入时不要一口吃成胖子把所有服务全接上,选一到两个非核心的边缘服务先接,验证链路、告警、UI都正常了,再逐步扩大到全链路。这个过程大概两周左右,中途会暴露不少问题,比如有的老服务JDK版本太老Agent不支持、有些框架版本兼容性不好,提前处理完,后面批量接入才平稳。
Agent版本统一管理。建议把所有服务用的skywalking-agent.jar统一放到公司内部获取依赖的制品库或者共享目录,打一个固定的目录路径规范,从源头避免各环境Agent版本不一致导致的协议问题。
配置项用启动参数强制指定,别依赖agent.config。特别是agent.service_name和collector.backend_service,务必在启动命令里显式写明。同一个Agent压缩包拷到各机器,只要启动参数不同就能区分环境,配置文件里永远留默认值,就不会出现配置漂移了。
保留OAP和ES日志至少两周。排障时需要结合OAP的接收日志和ES的写入日志来定位问题,如果日志被滚动清理得太快,出了问题无从追溯。建议把logs/目录挂到持久化卷上,结合外部日志系统采集归档。
6.4 性能损耗与数据量控制的平衡
接入Agent后,性能损耗是每个团队都会担心的问题。从我的实测数据看,Skywalking Agent在普通Java服务上带来的额外延迟大约在1ms到3ms之间,CPU占用涨幅大概在1%以内,内存占用在几十MB级别。如果你把采样率调到100%,流量大的服务数据量会非常可观,OAP和ES的压力会更明显。因此生产环境的常规做法是:
- 核心服务全量采样,分析问题时不丢数据。
- 非核心服务可以适当降低采样率,比如每3秒采样10条链路。
- 对健康检查接口,用
agent.ignore_context配一下忽略路径,避免无意义的数据刷屏。 - 定期清理历史链路数据,Skywalking的OAP里可以配置TTL,默认是保留3天链路数据、7天的指标数据。按业务需求调整,别让ES无限膨胀。
控制好采样和数据清理,Skywalking在绝大多数生产规模下都能稳定运行。
7. 总结一下实操中必须记住的几个点
最后再分享一个我觉得很实用的经验。
在接入了Skywalking之后,我们团队把故障排查的例行流程彻底改了。以前线上出故障,第一反应是登录服务器翻日志、看监控面板,折腾一圈才定位到问题。现在第一反应是打开Skywalking的拓扑图和链路页面,先看是哪个服务、哪条链路出了状况,基本几分钟就能缩小到具体服务和具体方法,再带着这个结论去查日志,效率高了好几个量级。
如果你还在犹豫要不要上Skywalking,我的建议是别犹豫,先花一个下午按照这篇文章把单机环境搭起来,把你手头的业务服务接进去跑一跑,眼见为实。无论你们用的是Spring Cloud还是Dubbo体系,是单体还是微服务,Skywalking都能提供有价值的观测视角。等你习惯了看链路数据解决问题,就再也回不去以前那种纯靠猜和翻日志排查问题的老方式了。
