500 个服务时快 6 倍:我们如何将 Kibana APM 服务地图从 Canvas 重构到 React DOM

作者:来自 Elastic Jenny Pavlova

每个服务节点都会显示告警、 SLO 和异常健康状态,因此你可以仅筛选违反阈值的服务,并将结果嵌入到任何 Kibana 仪表板中,同时支持在整个拓扑中使用完整的键盘导航。

我们基于 React Flow 重构了 Elastic Observability 中的 Kibana APM 服务地图。在拥有 500 个服务时,渲染时间仅为 64ms,相比之前基于 Cytoscape.js 的实现快约 6 倍,同时 JavaScript 体积减少了 60%( 69 KiB 对比 172 KiB )。服务节点现在会显示告警、 SL 和异常健康状态,因此你可以仅筛选违反阈值的服务,并将结果嵌入到任何 Kibana 仪表板中,同时支持在整个拓扑中使用完整的键盘导航。从告警到定位失败的依赖项仅需四次点击: Elastic APM 的嵌入式服务地图更深入地介绍了告警面板、 SLO 徽章以及仪表板嵌入功能。

下面分别是这次重构之前和之后的服务地图:

以前:

现在:

为什么 APM 服务地图从 Cytoscape.js 图可视化迁移到 React Flow

迁移带来的收益非常直观: React Flow 将节点渲染为真正的 React 组件,而不是通过 Canvas 绘制循环,因此即使面对大型拓扑,平移和缩放依然保持流畅;我们的 Elastic UI ( EUI )节点和徽章能够原生渲染(不再需要每次更新时重新渲染整个 Canvas);此外,基于 DOM 的渲染使节点能够天然被屏幕阅读器识别,而基于 Canvas 的渲染则无法做到这一点。

它也更加轻量:图形库从 172.4 KiB( cytoscape.js )减少到 69 KiB( @xyflow/react ),减少了约 103 KiB 的 JavaScript 下载体积,#248470 。

使用 React Flow 后, APM 服务地图快了多少?

在决定将 APM 服务地图从 Cytoscape.js 迁移到 React Flow 之前,我们对两个图形库在 100、200 和 500 个服务规模下进行了基准测试(使用合成链式拓扑,通过 Lighthouse 和组件级耗时进行测量,并对多次运行结果取平均值, #248470 ):

服务数量 Cytoscape.js 渲染 React Flow 渲染 提升幅度
100 61.6 ms 15.0 ms 约 76%
200 102.5 ms 28.1 ms 约 73%
500 392.5 ms 64.1 ms 约 84%

在拥有 500 个服务时, React Flow 仅需约 64 ms 即可完成地图渲染,而 Cytoscape.js 需要约 393 ms,速度约快 6 倍。仅图布局计算这一步就提升了约 70%--78% 的性能。主线程总阻塞时间减少了约 20%,尽管所有内容都作为真实 DOM 渲染,峰值内存占用也略有降低。更多结果可参考基准测试结果评论。

APM 服务地图中的键盘导航与无障碍支持

现在,当你在拓扑中导航时,服务地图会实时播报你当前所在的位置,并为每一次交互提供屏幕阅读器的实时上下文( #251444 )。

基于空间位置的方向键导航: 方向键会根据视觉上的相对位置进行导航,而不是按照文档的逻辑顺序。即使在复杂的蛇形布局中,焦点也会移动到你按下方向键所对应方向上最近的服务。

直接快捷键: 按下 Enter 或 Space 可打开详情面板( flyout ),按下 Escape 可关闭。

实时播报: 每一次交互都会通过屏幕阅读器进行播报,例如"已选择从 A 到 B 的连接"。

APM 服务地图布局算法如何工作

APM 服务地图使用 Dagre 进行层次化图布局,然后应用蛇形折叠( serpentine folding ),避免较长的依赖链生成难以阅读的超高宽高比长条布局:

1)Dagre 层次化布局: 我们使用图布局引擎 Dagre,并支持在水平和垂直布局方向之间切换,你可以在选项面板中进行修改。如果 Dagre 无法计算布局,服务地图会回退到确定性的网格布局,从而保持可交互性并避免出现错误。

2)针对长链的蛇形折叠( serpentine folding ): 较长的依赖流水线会形成狭长且难以阅读的条状布局,需要大量缩放才能查看。当宽高比变得过于极端时,我们会将各层( rank )折叠为上下堆叠、来回蛇形排列的带状结构,使"适应视图( fit view )"能够更紧密地缩放到实际的服务区域。如果拓扑本身已经足够紧凑,或者跨带状结构的边过多,则会跳过蛇形折叠。( #272900 )

服务依赖关系映射与 Kibana 仪表板嵌入背后的实现原理

视觉上的焕然一新最容易被注意到,而支撑重构后服务地图的一些架构变化包括:

使用统一资源节点,实现更简洁的服务依赖关系映射

我们现在会将外部依赖统一归并为资源节点( resource node ),从而减少视觉噪音。我们还修复了消息队列 span 的分组方式,使这类模式不再产生孤立节点( orphaned node )。( #252713)

基于 ES|QL 和 Lens 驱动的服务地图详情面板图表

服务详情面板( flyout )中的基础设施和 RED 指标图表现在基于 ES|QL 和 Kibana 核心的 Lens 可视化引擎构建,使服务地图能够提供与整个 Kibana 一致的图表使用体验。( #273713 )

将服务地图嵌入到任何 Kibana 仪表板

将服务地图添加到仪表板只需一次点击。在 APM 的任意服务地图视图中打开"复制到仪表板( Copy to dashboard )"菜单,当前的环境、服务过滤器、 KQL 查询以及过滤器标签( filter chips )都会一并带到仪表板中。像 now-15m 这样的相对时间范围会原样保留,而不会冻结为绝对时间戳,因此该面板会在仪表板中持续保持实时更新。(#272277)

嵌入后,面板会根据所在位置自动进行调整。它会根据当前视图模式显示或隐藏相应的控件,并遵循全局时间设置,同时不会覆盖你配置的相对时间范围。( #274551 )

APM 服务地图的下一步计划

服务地图重构是一个基础,而不是终点。除了 9.5 中已经提供的功能之外,后续的一些功能已经列入 APM 服务地图路线图。

贡献者

我负责领导这次迁移,并与一支优秀的团队一起构建了这些功能。感谢 Samuel Brito、Gonçalo Rica Pais da Silva、Irene Blanco Fabregat、Carlos Crespo、Miriam Aparicio Garcia、Sandra G 和 Nathan Smith 在工程方面的贡献,也感谢 Karolina Kurstak 和 Roshan Gonsalkorale 在设计和产品工作方面的支持。

原文:APM service map 6x faster: Kibana's React Flow migration --- Elastic Observability Labs

相关推荐
Elastic 中国社区官方博客5 小时前
Kubernetes attributes processor v1:它对 EDOT Collector 意味着什么
java·大数据·elasticsearch·搜索引擎·贪心算法·kubernetes·全文检索
Elastic 中国社区官方博客6 小时前
Elasticsearch Serverless 如何通过 hollow shards 将索引节点关闭次数降低 30%
大数据·数据库·elasticsearch·搜索引擎·serverless·全文检索
w***488212 小时前
SpringBoot整合easy-es
spring boot·后端·elasticsearch
guo_wen_qiang12 小时前
云服务器elasticsearch环境搭建-单台
运维·elasticsearch·容器
Elasticsearch12 小时前
使用 Jev 作为 search reranker:基准测试与实现方法
elasticsearch
Elastic 中国社区官方博客14 小时前
14 个 alerts,1 个 incident:使用 Elasticsearch 中的 ES|QL 衡量 alerting rule 噪声
大数据·运维·数据库·elasticsearch·搜索引擎·全文检索
SelectDB技术团队1 天前
一条日志两套引擎的账:把 Elasticsearch 检索与分析合并到同一份数据的落地写法
大数据·数据库·elasticsearch·搜索引擎·全文检索·日志·apache doris
Elastic 中国社区官方博客1 天前
使用 Lucene 搜索你的 Bean —— Elasticsearch
大数据·开发语言·人工智能·elasticsearch·搜索引擎·全文检索·lucene
闲蛋小超人笑嘻嘻1 天前
Git Worktree 详解
大数据·elasticsearch·搜索引擎
MayBaymax1 天前
Elasticsearch 原理与用法
java·elasticsearch