perf: 第三方系统调用指标采集优化 #4333#4334
Merged
Merged
Conversation
1.根因:父线程 JobContext 通过 ContextSnapshot 被多个工作线程共享,metricTagsMap 内的 ArrayList 在并发追加 Tag 时抛出 ArrayIndexOutOfBoundsException,导致第三方系统调用指标采集异常。 2.修复方案:工作线程在恢复父线程上下文后,立即克隆出一份隔离的 JobContext 副本放回 ThreadLocal;只读字段复用父线程引用,可写集合字段(metricTagsMap、debugMessage、httpMetricTags)在副本中重置为 null,由子线程按需初始化,彻底避免共享同一份集合。 3.关键改动: - JobContext 新增 copyForChildThread() 方法,明确克隆策略并重置可变集合字段。 - JobContextUtil 新增 isolateContextForChildThread() 工具方法,封装"取当前 JobContext 并替换为隔离副本"的语义。 - WatchableThreadPoolExecutor.runWithContext() 在 setThreadLocals() 之后调用 isolateContextForChildThread(),使所有 submit/invokeAll/invokeAny 入口统一受益。 - ConcurrencyUtil.InnerTask.run() 同步调用 isolateContextForChildThread(),覆盖经由该工具类提交到外部线程池的子任务路径。 4.新增 JobContextTest 验证 copyForChildThread 的引用复用与可变集合重置语义;新增 WatchableThreadPoolExecutorTest 用 16 线程并发 500 tag 模拟 Issue 场景,断言子线程互不干扰且父线程 metricTagsMap 不被污染。
1.去除不再使用的httpMetricName字段。
wuyzh39
approved these changes
Jun 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
问题背景
并发场景下偶现
BizCmdbClient.FindModuleHostRelationTask因HttpMetricUtil.addTagForCurrentMetric抛ArrayIndexOutOfBoundsException,导致第三方系统(CMDB)调用指标采集失败。根因:父线程
JobContext通过ContextSnapshot被传播到子线程时引用共享,metricTagsMap内的ArrayList在多个工作线程并发追加 Tag 时越界。修改内容
让被传播到子线程的
JobContext独立化,从根因消除依赖JobContext可写字段的并发问题(不仅限于metricTagsMap):JobContext新增copyForChildThread():浅拷贝只读字段,可写集合(metricTagsMap/debugMessage/httpMetricTags)在副本中置为null,由子线程按需懒初始化。JobContextUtil新增isolateContextForChildThread(),封装“取当前 JobContext → 替换为隔离副本放回 ThreadLocal”的语义。WatchableThreadPoolExecutor.runWithContext()在setThreadLocals()之后调用isolateContextForChildThread(),使所有submit/invokeAll/invokeAny入口统一受益。ConcurrencyUtil.InnerTask.run()同步调用,覆盖经由该工具类提交到外部线程池的子任务路径(如getResultWithRetry并发分页)。