OpenMetadata 服务端诊断与压测关联分析/api/v1/system/diagnostics 实战指南【免费下载链接】OpenMetadataThe Open Context Layer for Data and AI , OpenMetadata is the open platform for building trusted data context and business semantics for humans, AI assistants, and agents.项目地址: https://gitcode.com/GitHub_Trending/op/OpenMetadata本文讲解 OpenMetadata 的服务端诊断端点GET /api/v1/system/diagnostics如何与分布式压测脚本perf-test.sh协同工作从六个诊断分区的字段含义、瓶颈检测规则到数据库连接池、Jetty 线程池、GC 压力、Bulk Executor 队列等五类典型瓶颈场景的定位与调优方法。读完本文你可以基于一次压测的 before/after 快照判断高负载下请求时间到底消耗在 JVM、数据库、搜索还是业务逻辑层并给出具体的环境变量级修复手段。一、诊断端点总览一次调用拿到完整性能快照诊断端点提供 OpenMetadata 服务器的一次性性能快照single-call performance snapshot与仓库自带的分布式压测脚本perf-test.sh组合使用能够精确定位高负载场景下时间消耗在哪里并产出可执行的调优建议。1.1 基本调用方式curl -H Authorization: Bearer $TOKEN \ http://localhost:8585/api/v1/system/diagnostics | python3 -m json.tool注意该端点要求管理员权限从源码 DiagnosticsResource.java 可以看到入口方法首先执行authorizer.authorizeAdmin(securityContext)因此必须携带管理员 Bearer Token否则会被拒绝。1.2 响应结构{ timestamp: 2026-03-02T19:00:00Z, jvm: { ... }, jetty: { ... }, database: { ... }, database_queries: { ... }, bulk_executor: { ... }, request_latency: { ... } }源码中各分区按固定顺序组装DiagnosticsResource.javatimestamp之后依次是jvm、jetty、database、bulk_executor、database_queries、request_latency。所有指标数据都来自 JVM MXBean 和 Micrometer 全局注册表Metrics.globalRegistry其中 Jetty 线程池指标由 JettyMetrics.java 在bindTo阶段注册请求延迟指标由 RequestLatencyContext.java 按端点打点。下面逐节解读。二、六大诊断分区字段详解2.1 JVM字段含义heap_used_bytes/heap_max_bytes当前堆内存占用与上限。heap_usage_pct若压测后 85%GC 压力很可能正在制造尾延迟。gc_pause_total_ms自 JVM 启动以来的累计 GC 暂停时间。对比压测前后的差值即可知道测试期间发生了多少 GC。gc_countGC 总次数。压测期间差值很大意味着频繁的 stop-the-world 停顿。thread_count/thread_peak活跃 JVM 线程数可与 Jetty 线程池指标交叉印证。cpu_process_pct进程 CPU 利用率0-100。若长期钉在 100%说明服务器是 CPU 受限CPU-bound。uptime_seconds用于确认服务器没有在测试中途重启。源码实现DiagnosticsResource.java堆与 GC 数据来自MemoryMXBean和GarbageCollectorMXBeangc_pause_total_ms是所有收集器的getCollectionTime()累加值因此差值法才可靠cpu_process_pct依赖com.sun.management.OperatingSystemMXBean在非 Sun/Oracle 风格 JVM 上会返回 -1.0。2.2 Jetty线程池字段含义threads_busy/threads_max正在处理请求的线程数与上限。utilization_pct核心指标。若 90% 且queue_size 0说明线程池已饱和请求正在排队。queue_size等待空闲线程的请求数。非零即意味着排队正在增加延迟。queue_time_avg_ms请求在队列中等待线程的平均时长。virtual_threads_enabled是否启用了 Java 21 虚拟线程启用后线程池不再是瓶颈。从源码看JettyMetrics.java 通过 Gauge 直接绑定QueuedThreadPool的getThreads()/getBusyThreads()/getQueueSize()等方法utilization_pct是诊断端点用busy/current现场计算的比值。virtual_threads_enabled读取环境变量SERVER_ENABLE_VIRTUAL_THREAD是否设为true见 JettyMetrics.java启用后额外注册虚拟线程相关 Gauge。queue_time_avg_ms使用指数滑动平均平滑处理JettyMetrics.java避免瞬时毛刺误导判断。2.3 DatabaseHikariCP 连接池字段含义pool_active/pool_max活跃数据库连接数与池上限。pool_usage_pct核心指标。若 80%大概率存在连接竞争请求在等待空闲连接。pool_pending正在等待数据库连接的线程数。压测期间 0 说明池子偏小。pool_idle空闲连接数。压测期间为 0 说明池子已被打满。connection_acquire_avg_ms从池中获取连接的平均耗时。高值50ms表明池竞争。connection_acquire_max_ms观测到的最大获取连接耗时。connection_acquire_count获取连接操作的总次数。这些字段直接映射 Micrometer 的 HikariCP 指标DiagnosticsResource.javahikaricp.connections.active/idle/max/pending以及hikaricp.connections.acquire计时器均值、最大值、次数。pool_usage_pct由端点现场按active/max计算。2.4 Database Queries按类型剖析将数据库查询时长按操作类型select / insert / update / delete拆解字段含义total_operations所有类型的 DB 操作总数。{type}.count该类型查询的次数。{type}.mean_ms平均查询时长。{type}.max_ms最大查询时长。尖峰往往提示锁竞争或全表扫描。{type}.p95_ms95 分位查询时长。100ms 时应排查慢查询。{type}.total_ms该类型查询累计耗时。实现上DiagnosticsResource.java端点遍历db.query.duration计时器并带type标签对四种类型分别聚合 count / mean / max / total并从HistogramSnapshot中提取 0.95 分位值——因此p95_ms依赖直方图数据若计时器未配置直方图则不会输出该字段。如何读这份剖析如果select.p95_ms是 200ms 而insert.p95_ms只有 20ms说明读查询才是瓶颈通常指向缺失索引或 N1 查询模式。2.5 Bulk Executor字段含义queue_depth/queue_capacity异步处理队列中的任务数与队列容量。queue_usage_pct70% 时接近拒绝阈值开始出现 HTTP 503。active_threads/max_threads正在处理批量操作的 worker 线程数与上限。has_capacity为false意味着下一次批量提交将以 503 被拒绝。对应实现 BulkExecutor.java 是一个带准入控制admission control的单例有界线程池 ArrayBlockingQueue核心保证是请求一旦被接受就一定会完成但当队列满时会以 503 拒绝新请求。线程数、队列大小来自BulkOperationConfigurationmaxThreads/queueSize/timeoutSeconds诊断端点直接读取运行中的实例状态。2.6 Request Latency按端点拆解这是最具可执行性的分区。对每个METHOD /endpoint组合字段含义count该端点处理的请求总数。avg_total_ms平均端到端延迟。avg_db_ms/db_pct耗在数据库查询上的时间及占比。avg_search_ms/search_pct耗在搜索 / Elasticsearch 操作上的时间。avg_internal_ms/internal_pct耗在 Java 代码上的时间序列化、校验、业务逻辑。avg_db_ops/avg_search_ops每请求平均的 DB / 搜索往返次数。打点来源是 RequestLatencyContext.java请求开始时注册request.latency.total计时器并打上endpointmethod标签结束时再分别结算request.latency.database、request.latency.search等分项计时器诊断端点按相同标签组合取出均值计算百分比DiagnosticsResource.java。如何读这份拆解如果PUT /v1/tables显示db_pct: 56%则该请求 56% 的时间耗在数据库查询上再结合database.pool_usage_pct: 85%就能判断瓶颈在 DB 连接池。三、与压测脚本的集成perf-test.sh 会在三个时间点自动查询诊断端点压测前— 基线快照diagnostics_before压测中— 健康监控每 10 秒采样一次diagnostics_during见脚本内 HealthMonitor 的diagnostics_interval10压测后— 终态快照diagnostics_after3.1 带诊断的压测命令# 基本用法诊断数据自动采集 ./perf-test.sh --scale small --server http://localhost:8585 --admin-port 8586 # 显式指定 Token ./perf-test.sh --scale medium --server http://localhost:8585 \ --admin-port 8586 --token $MY_TOKEN --output /tmp/bench.json--admin-port同时启用 Prometheus 抓取和诊断采集即便不设置它诊断也能工作走主 API 端口 8585。脚本的其他用法scale 档位、workers 参数、quick 模式可参考 USAGE.md 与 CLUSTER-SIZING-RUNBOOK.md。3.2 控制台输出在基准测试表格之后会看到SERVER-SIDE BREAKDOWN段落SERVER-SIDE BREAKDOWN (from /api/v1/system/diagnostics): JVM: heap 1.2GB/2GB (60%), GC pauses 450ms during load Jetty: 142/150 threads busy (95%), queue depth: 23 DB Pool: 85/100 active (85%), 12 pending connections Bulk Executor: queue 450/1000 (45%) Latency Breakdown (PUT endpoints): Endpoint Total DB% Search% Internal% /v1/tables 320ms 56.2% 14.1% 29.7% /v1/topics 180ms 48.0% 22.0% 30.0% /v1/dashboards 250ms 52.0% 18.0% 30.0% BOTTLENECK: DB bottleneck on PUT /v1/tables: 56.2% of request time in DB, pool at 85.0% utilization3.3 JSON 报告解析报告包含顶层diagnostics_before和diagnostics_after对象以及cluster_sizing.server_side_analysiscat /tmp/bench.json | python3 -c import json, sys r json.load(sys.stdin) # 检查诊断数据是否可用 diag r.get(diagnostics_after, {}) if diag: jvm diag[jvm] print(fHeap: {jvm[\heap_usage_pct\]}%) print(fGC pauses: {jvm[\gc_pause_total_ms\]}ms) jetty diag[jetty] print(fJetty: {jetty[\threads_busy\]}/{jetty[\threads_max\]} ({jetty[\utilization_pct\]}%)) db diag[database] print(fDB pool: {db[\pool_active\]}/{db[\pool_max\]} ({db[\pool_usage_pct\]}%)) for ep, data in diag.get(request_latency, {}).items(): print(f{ep}: total{data[\avg_total_ms\]}ms fDB{data[\db_pct\]}% Search{data[\search_pct\]}% fInternal{data[\internal_pct\]}%) else: print(Diagnostics not available (server may be older version)) 四、瓶颈检测规则压测脚本会自动套用以下规则并将结果写入 findings条件诊断结论推荐修复db_pct 60%且pool_usage_pct 80%数据库是瓶颈export DB_CONNECTION_POOL_MAX_SIZE150jetty.utilization_pct 90%且queue_size 0线程池饱和export SERVER_MAX_THREADS300或启用虚拟线程任一端点search_pct 30%搜索索引正在消耗延迟export ELASTICSEARCH_MAX_CONN_TOTAL50bulk_executor.queue_usage_pct 70%接近批量拒绝阈值export BULK_OPERATION_QUEUE_SIZE2000压测后jvm.heap_usage_pct 85%内存压力 / GC 尾延迟增大 JVM 堆-Xmxdatabase_queries.{type}.p95_ms 100ms该类型存在慢查询加索引、优化 SQLconnection_acquire_avg_ms 50ms连接池竞争export DB_CONNECTION_POOL_MAX_SIZE150五、典型场景与处置场景 1高延迟数据库是瓶颈症状p95 延迟 2sdb_pct60%pool_usage_pct80%。Latency Breakdown: /v1/tables 320ms DB62% Search12% Internal26% DB Pool: 95/100 active (95%), 8 pending发生了什么每个 PUT 都需要多次 DB 往返。95% 的池利用率加上 8 个 pending 连接意味着请求在等待空闲连接。修复export DB_CONNECTION_POOL_MAX_SIZE150 export DB_CONNECTION_TIMEOUT10000 # 快速失败而不是等 30 秒场景 2线程池耗尽症状Connection refused 错误utilization_pct95%queue_size持续增长。Jetty: 148/150 threads busy (99%), queue depth: 45发生了什么所有 Jetty 线程都在忙碌新请求不断排队增加延迟队列填满后连接会被拒绝。修复export SERVER_MAX_THREADS300 # 或者启用虚拟线程I/O 密集负载的首选 export SERVER_ENABLE_VIRTUAL_THREADtrue场景 3GC 压力症状周期性延迟尖峰heap_usage_pct85%GC 暂停差值大。JVM: heap 1.8GB/2GB (90%), GC pauses 2300ms during load发生了什么JVM 大量时间花在垃圾回收上表现为周期性延迟尖峰和吞吐量下降。修复# 增大堆 export OPENMETADATA_HEAP_OPTS-Xmx4g -Xms4g场景 4Bulk Executor 队列填满症状PUT 端点出现 HTTP 503 错误。Bulk Executor: queue 980/1000 (98%) has_capacity: false发生了什么异步处理队列已满需要批量处理的新请求被 503 拒绝——这正是 BulkExecutor 准入控制的设计行为队列满则拒绝而非无限积压。修复export BULK_OPERATION_QUEUE_SIZE2000 export BULK_OPERATION_MAX_THREADS20场景 5慢 SQL症状p95 高database_queries.select.p95_ms100msdb_pct60%。DB Query Profile (total operations: 125,000): Type Count Mean Max select 80,000 12.3ms 450.0ms insert 40,000 25.1ms 890.0ms Connection acquire avg: 85.2ms发生了什么单条查询本身慢p95 100ms同时获取连接耗时偏高说明既有查询性能问题也有池竞争。修复# 扩大池子减少获取竞争 export DB_CONNECTION_POOL_MAX_SIZE150 # 缩短连接超时快速失败 export DB_CONNECTION_TIMEOUT10000 # 考虑为慢 SELECT 查询添加数据库索引六、Before / After 快照对比最有价值的分析来自压测前后的诊断对比指标压测前压测后解读heap_usage_pct25%85%压测期间发生了大量内存分配gc_pause_total_ms2002500测试期间产生了 2.3 秒 GC 停顿pool_active295连接池从空闲到接近打满pool_pending08出现了连接竞争queue_depth0450压测下批量队列开始堆积如果健康监控数据里存在diagnostics_during采样可以把这些指标随时间画成曲线精确看到瓶颈是在哪个时刻浮现的。七、优雅降级Graceful Fallback如果服务器版本没有诊断端点旧版本压测脚本会打印提示Diagnostics endpoint returned status404 (may not be available)回退到 Prometheus 抓取前提是设置了--admin-port控制台输出中跳过SERVER-SIDE BREAKDOWN段落JSON 报告中省略diagnostics_before/diagnostics_after诊断不是硬性依赖——有它没有它压测脚本都能跑通。八、延伸阅读仓库内相关路径本文档原始版本DIAGNOSTICS.md诊断端点实现DiagnosticsResource.javaJetty 线程池指标注册JettyMetrics.java请求延迟打点上下文RequestLatencyContext.java批量执行器与准入控制BulkExecutor.javaMicrometer 指标捆绑MicrometerBundle.java压测脚本perf-test.sh配套文档 USAGE.md、CLUSTER-SIZING-RUNBOOK.md适用前提与限制诊断端点要求管理员 Token 与 API 前缀/apip95_ms依赖 Micrometer 直方图快照虚拟线程能力依赖 Java 21 与SERVER_ENABLE_VIRTUAL_THREAD环境变量文中所有环境变量如DB_CONNECTION_POOL_MAX_SIZE、SERVER_MAX_THREADS、BULK_OPERATION_QUEUE_SIZE均为服务器启动时的配置修改后需重启生效且具体取值应结合压测报告中的cluster_sizing建议确定。【免费下载链接】OpenMetadataThe Open Context Layer for Data and AI , OpenMetadata is the open platform for building trusted data context and business semantics for humans, AI assistants, and agents.项目地址: https://gitcode.com/GitHub_Trending/op/OpenMetadata创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
