Apache SkyWalking 8.7.0 版本深度解析:Agent 新插件、OAP 持久化会话重构与性能优化全览
【免费下载链接】skywalkingAPM, Application Performance Monitoring System项目地址: https://gitcode.com/gh_mirrors/sky/skywalking
本文基于 Apache SkyWalking 官方 8.7.0 版本变更记录(changes-8.7.0.md),逐条拆解该版本在 Project、Java Agent、OAP-Backend、UI 与 Documentation 五个维度上的核心变更,并结合当前仓库源码验证关键实现。读完本文,你将掌握 8.7.0 引入的持久化会话机制、L1 聚合刷新、动态日志、新增插件(Neo4j、Sentinel、ShardingSphere 等)的实战影响,以及该版本对生产部署中 ElasticSearch 配置项(如bulkActions、flushInterval)的调整要点。
一、Project 级变更:工程化与基础设施
1. 依赖管理抽取为 BOM
8.7.0 将依赖版本管理从各模块 pom 中抽取为统一的 BOM 工程,即仓库根目录下的 oap-server-bom/pom.xml。这一改动让所有模块(Agent、OAP Server、WebApp)共享同一份依赖版本声明,降低多模块之间版本漂移的风险,也为后续统一升级(例如本版本中大量的 CVE 修复升级)提供了单一入口。
2. 测试矩阵加入 JDK 16
CI 测试矩阵新增 JDK 16,意味着项目在 JDK 16 环境下完成编译与测试验证。这一变化与仓库中 apm-dist、oap-server 各模块的构建流程直接相关,为开发者在自己环境中使用更高版本 JDK 编译项目提供了先行验证。
3. DataCarrier 新增nothingToConsume消费者事件通知
DataCarrier 是 SkyWalking 自研的轻量级数据缓冲队列组件(位于 oap-server/server-library/library-datacarrier-queue)。8.7.0 为消费者接口新增了空队列事件通知:
当队列中没有元素可消费时,调用
nothingToConsume方法。
源码验证:接口 IConsumer.java 中新增了默认方法:
/** * Notify the implementation, if there is nothing fetched from the queue. * This could be used as a timer to trigger reaction if the queue has no element. */ default void nothingToConsume() { }由于是default方法,已有消费者实现无需改动即可兼容。调用点分别位于 ConsumerThread.java 和 MultipleChannelsConsumer.java。这一机制可被用作“队列空闲定时器”,例如在无数据时执行周期性的批量兜底刷写逻辑。
4. 快照 Docker 镜像推送至 GitHub Container Registry
master 分支代码构建出的快照 Docker 镜像会推送至 GitHub Container Registry,仅供希望协助测试 master 分支代码的人使用,切勿用于生产环境。相关 Docker 构建入口可见 docker/oap/Dockerfile、docker/ui/Dockerfile。
二、Java Agent 变更:新插件与能力增强
1. 支持异步模式下修改 Span 属性
Agent 现在允许在异步模式下修改 Span 属性(例如在回调线程中继续追加 tag 或日志),并修复了spring-webflux-5.x-webclient插件中异步结束(async finish)被重复调用的问题,以及该插件的 NPE。同时 Gateway 插件在配置了 fallback url 时异步结束被重复触发的问题也一并修复。
2. 采集 JVM 参数与 Jar 依赖信息
Agent 新增对 JVM 启动参数(JVM arguments)和 Jar 依赖信息的采集能力,配合 OAP 端 JVMMetric 的扩展,为排查类加载冲突、依赖版本问题提供了第一手数据。
3. 日志上报通道的临时鉴权支持
8.7.0 为日志上报(log report)通道添加了鉴权支持,但该特性及对应 gRPC 通道计划在 Satellite 0.2.0 发布后被移除,属于临时性方案,升级时需关注后续版本变更。
4. 移除弃用的 gRPC 方法
移除了io.grpc.ManagedChannelBuilder#nameResolverFactory这一弃用方法,Agent 底层的 gRPC 通信迁移到新的名称解析机制。
5. 新增与调整的插件
- 新增
Neo4j-4.x插件:支持 Neo4j 图数据库 4.x 版本的链路追踪。 - 新增
ShardingSphere-5.0.0-beta插件,同时移除 ShardingSphere 旧版本(legacy)插件,避免新旧并存。 - 新增 Sentinel 插件:支持阿里 Sentinel 限流组件的调用链追踪。
- 新增
guava-cache插件,并将ehcache-2.x调整为可选(optional)插件,意味着默认不再随 Agent 加载,需要显式开启。 - 增强
mysql-8.x-plugin兼容性,并支持 SqlServer 参数采集。 - 支持 Kafka SASL 登录模块,便于在开启 SASL 认证的 Kafka 集群中使用 Kafka 相关插件。
- ElasticJob 插件更新至 GA 版本,
Spring-Kafka插件方法命名得到规范化整理。 KafkaServiceManagementServiceClient移除生成实例名的逻辑,实例名生成职责被收敛。- okhttp 插件性能优化:通过优化
Class.getDeclaredField()的调用减少反射开销。
6. 配置项修正
默认 agent.config(实际随发行包分发的配置文件)中的profile.duration被修正为profile.max_duration,语义更准确地表达“profile 最大持续时长”。使用 8.7.0 时若发现 profile 时长配置不生效,请检查是否仍在使用旧键名。
7. 其他修复
- 修复 gRPC 响应时间问题;
- 修复
GRPCLogClientAppender无上下文(no context)告警; - 修复若干方法级异常(method exception)错误。
三、OAP-Backend 变更:安全加固、性能与存储会话机制重构
1. 依赖安全升级(CVE 修复)
8.7.0 集中修复了一批第三方依赖的安全漏洞,主要包括:
| 组件 | 修复的 CVE |
|---|---|
| Apollo core | CVE-2020-15170 |
| Kubernetes client | CVE-2020-28052 |
| Elasticsearch 7 client | CVE-2020-7014 |
| jackson 相关库 | CVE-2018-11307、CVE-2018-14718~14721、CVE-2018-19360~19362、CVE-2019-14379、CVE-2019-14540、CVE-2019-14892/14893、CVE-2019-16335、CVE-2019-16942/16943、CVE-2019-17267、CVE-2019-17531、CVE-2019-20330、CVE-2020-8840、CVE-2020-9546~9548、CVE-2018-12022/12023、CVE-2019-12086、CVE-2019-14439、CVE-2020-10672/10673、CVE-2020-10968/10969、CVE-2020-11111~11113、CVE-2020-11619/11620、CVE-2020-14060~14062、CVE-2020-14195、CVE-2020-24616、CVE-2020-24750、CVE-2020-25649、CVE-2020-35490/35491、CVE-2020-35728、CVE-2020-36179~36190 |
| log4j 1.x | 排除(CVE-2019-17571) |
| log4j 2.x | CVE-2020-9488 |
| nacos | CVE-2021-29441、CVE-2021-29442 |
| netty | CVE-2019-20444、CVE-2019-20445、CVE-2019-16869、CVE-2020-11612、CVE-2021-21290、CVE-2021-21295、CVE-2021-21409 |
| consul client | CVE-2018-1000844、CVE-2018-1000850 |
| zookeeper | CVE-2019-0201(集群协调插件现要求 ZooKeeper 服务端 3.5+) |
| snake yaml | CVE-2017-18640 |
| embed tomcat | CVE-2020-13935 |
| commons-lang3 | 升级以避免部分 JDK 版本下的潜在 NPE |
升级注意:ZooKeeper 集群协调插件(cluster-zookeeper-plugin)在 8.7.0 起要求 ZooKeeper 服务端版本不低于 3.5,使用旧版 ZooKeeper 的部署需同步升级。
2. 存储持久化会话(Persistent Session)机制重构
这是 8.7.0 最核心的存储侧改动,直接影响写入吞吐与资源占用:
- 重新实现会话机制:缓存中的指标只依据“最后一次访问时间戳”被移除,而非首次进入缓存的时间,保证热数据不会被意外清出。相关配置项
storageSessionTimeout(会话超时阈值,默认 70000ms)在 CoreModuleConfig.java 中定义,并可通过core/storageSessionTimeout动态配置。 - 会话超时可配置:原先固定/写死的超时行为改为可配置项。
- 区分维度缓存超时:分钟级与小时级指标的缓存超时被延长至约 5 分钟,避免高频刷新。
- 移除同步持久化机制:由于增强后的会话机制不再要求数据在插入/更新后立即可查询,ElasticSearch DAO 中原本的同步持久化逻辑被移除。由此带来一系列连锁调整(见下文)。
- 修复会话超时机制 bug及持久化会话可能“永久缓存元数据指标”的边界问题,新的超时机制专门规避该场景。
3. 持久化参数调整(涉及 Breaking Change)
- 移除
core/maxSyncOperationNum与core/syncThreads:这两个 8.5.0 引入的设置因指标持久化完全异步化而被删除,在application.yml中配置了它们的用户需清理。 - 移除 ElasticSearch 存储选项中的
syncBulkActions:同步批量动作机制已取消。 - 默认
bulkActions提升至 5000(原为 1000),对应环境变量SW_STORAGE_ES_BULK_ACTIONS,即单次批量写入最多积累的 action 数大幅增加,以适配异步刷写模式。 - ElasticSearch 索引刷新间隔(flushInterval)提升至 15s(原为 10s),且指标与记录(record)数据共享同一个
flushInterval(此前记录数据刷新间隔被硬编码为 10s)。 - 小时级与天级指标刷新周期缩减:仅在常规持久化周期的 4 个时点运行,即默认刷新周期为
25s * 4(persistentPeriod默认 25s,见 CoreModuleConfig.java)。 - 索引刷新周期调整为
INT(flushInterval * 2/3):此前索引刷新周期与 bulk 刷新周期相同,在低流量场景(整个周期内流量小于 bulkActions)下可能出现两个周期的 bulk 被并入同一次索引刷新重建,从而引发版本冲突(version_conflict_engine_exception);该问题无法再通过core/persistentPeriod解决,因为 bulk 刷新已不再受持久化定时器控制,因此 8.7.0 改为更短的独立索引刷新周期。 - 元数据列表元素去重:由于异步刷写更激进,元数据列表更可能出现重复元素,8.7.0 在写入时提供 distinct 去重,无需再显式标识。
- 修复批量执行中可能的
version_conflict_engine_exception,并修复 ElasticSearch 6/7 存储选项的 ID 读取——改用物理索引而非模板别名,降低冲突概率。
升级 FAQ:官方在 Documentation 部分补充了 “Elasticsearch exception type=version_conflict_engine_exception since 8.7.0” 的 FAQ,出现该异常时建议对照上文 flush 周期与 bulkActions 的联动关系排查。
4. 性能优化清单
- Envoy ALS 分析器:高流量场景(约 10k RPS)下 CPU 占用减少约 1 核;裁剪 ALS 元数据中的无用字段;缓存正则模式与匹配结果;优化字符串拼接;优化 Envoy 错误日志持久化性能;新增 Envoy
cluster manager指标。 - 指标与实体 ID 缓存:在
Metrics与ISource中缓存 metrics id 与 entity id,减少重复计算。 - L1 聚合刷新周期:新增 L1 聚合刷新周期(
l1FlushPeriod,默认 500ms,见 CoreModuleConfig.java),降低 CPU 负载并有利于 Young GC。 - 指标并发模式调整:移除执行阶段(execution stage)的并发模式(8.5.0 引入),仅保留 prepare 阶段的并发(该阶段并发仍有意义)。
- 批量创建 PrepareRequest:指标持久化时并发创建 PrepareRequest。
- Trace SQL 优化:避免
select *查询,优化 SQL 语句。
5. 功能新增与协议扩展
- OAL 支持从事件(Events)生成指标:扩展了 OAL 的指标来源范围。
- OpenAPI 端点名分组:支持依据 OpenAPI 定义对端点(endpoint)名称进行分组,相关配置与说明可参考 endpoint-grouping-rules.md。
- JVMMetric 新增线程状态与类加载信息指标:OAL 脚本 java-agent.oal 中新增了对应指标定义,例如:
instance_jvm_thread_live_count = from(ServiceInstanceJVMThread.liveCount).longAvg(); instance_jvm_thread_daemon_count = from(ServiceInstanceJVMThread.daemonCount).longAvg(); instance_jvm_thread_peak_count = from(ServiceInstanceJVMThread.peakCount).longAvg(); instance_jvm_thread_runnable_state_thread_count = from(ServiceInstanceJVMThread.runnableStateThreadCount).longAvg(); instance_jvm_thread_blocked_state_thread_count = from(ServiceInstanceJVMThread.blockedStateThreadCount).longAvg(); instance_jvm_thread_waiting_state_thread_count = from(ServiceInstanceJVMThread.waitingStateThreadCount).longAvg(); instance_jvm_thread_timed_waiting_state_thread_count = from(ServiceInstanceJVMThread.timedWaitingStateThreadCount).longAvg();同时自监控(self-observability)与 otel-oc-rules 也新增了线程与类加载器指标(类加载指标见instance_jvm_class_loaded_class_count,定义于 java-agent.oal)。
- 事件查询协议分页:Event 查询协议新增分页能力,UI 端相应实现了 Events 时间线新页面。
- LAL 指标变更(Breaking Change):移除
qps、新增rpm(requests per minute),使用 LAL(Log Analysis Language)的用户需同步修改规则,相关语法可参考 lal.md。 - LAL 静态编译:LAL DSL 改为静态编译并以类型检查方式运行,规则语法错误将在加载期更早暴露。
6. 配置与集成改进
- ElasticSearch6/7 存储支持
connectTimeout与socketTimeout设置:连接与套接字超时不再依赖默认值。 - 支持配置服务端最大请求头大小与 ES 索引模板顺序。
- 动态日志(Dynamical Logging):支持运行时动态更新日志配置,无需重启 OAP,详见 dynamical-logging.md。
- InfluxDB 存储插件修复
Metrics#multiGet问题;修复-meters指标 topic 在配置 namespace 时未创建的问题;修复 Kafka 传输 topic 在有无 namespace 两种情况下重复创建的问题。 - webapp 模块:将 zuul 代理替换为 Spring Cloud Gateway 2.x。
- etcd 集群协调与动态配置升级到 v3.x。
- PrometheusMetricConverter 修复:转换指标到 SampleFamily 时可能抛出
IllegalArgumentException的问题已修复,并过滤 NaN 值样本。 - Kubernetes ConfigMap 配置中心修复:不再漏发 delete 事件。
- 默认关闭 Spring Sleuth meter 分析器;Envoy ALS receiver 仅将 5xx 计为错误。
- 修复
slowDBAccessThreshold动态配置在未配置时的报错。
四、UI 变更:修复与 Events 时间线
8.7.0 的 UI(skywalking-ui)以修复为主:
- 修复日志条件的日期组件;
- 修复重复选项的选择器键(selector keys);
- 修复指标默认配置与图表类型设置;
- 修复 profile UI 的 trace 表格;
- 修复拓扑图中服务端响应时间显示错误;
- 修复日志页数(分页)问题;
- 实现 Events 新页面时间线,并修复事件详情样式。
五、Documentation 变更
- 新增 FAQ:
Elasticsearch exception type=version_conflict_engine_exception since 8.7.0(位于 ES-Server-FAQ.md),解释了 8.7.0 中 flush 机制调整后版本冲突异常的成因与应对。 - 新增 Self Observability 服务发现(k8s)说明。
- 新增 Envoy 1.19 将 Metrics 发送至 OAP 的示例,并升级至 Envoy V3 API(参见 metrics_service_setting.md 与 als_setting.md)。
六、升级与运维要点速查
| 关注点 | 8.7.0 行为 | 行动建议 |
|---|---|---|
| ZooKeeper 集群协调 | 要求服务端 3.5+ | 升级 ZooKeeper 集群 |
profile.duration | 更名为profile.max_duration | 更新 agent.config |
syncBulkActions | 已移除 | 从 ES 存储配置中删除 |
core/maxSyncOperationNum、core/syncThreads | 已移除(8.5.0 引入) | 从 application.yml 中删除 |
bulkActions默认值 | 1000 → 5000 | 按吞吐重新评估批量配置 |
| 索引/数据 flushInterval | 10s → 15s(共享) | 关注低流量下版本冲突 FAQ |
| LAL 指标 | 移除qps,新增rpm | 同步修改 LAL 规则 |
| 日志通道鉴权 | 临时特性,随 Satellite 0.2.0 移除 | 规划替代方案 |
| ehcache-2.x 插件 | 变为可选插件 | 需要时显式开启 |
| 快照 Docker 镜像 | 仅用于测试 master | 生产环境勿使用 |
综上所述,8.7.0 是一次“安全加固 + 存储写路径重构 + 大量性能优化”的组合版本:持久化会话机制的重新实现彻底解耦了“写入即查询”的旧约束,使 ElasticSearch 批量写入可以更大胆地异步化,代价是多个 8.5.0 配置项被移除以及默认参数的大幅调整。升级时建议优先核对上表配置差异,并关注官方针对version_conflict_engine_exception的 FAQ 说明。
【免费下载链接】skywalkingAPM, Application Performance Monitoring System项目地址: https://gitcode.com/gh_mirrors/sky/skywalking
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考