应通过持续监控getrejectedexecutioncount()增长趋势,并结合队列水位、活跃线程占比等指标交叉验证是否常态化超载;拒绝计数需滑动窗口统计,满足拒绝率≥0.1%且连续5周期不降、队列使用率>90%超60秒、活跃线程恒等于maximumpoolsize三者同时成立才判定为常态化超载。
直接看 getrejectedexecutioncount() 的持续增长趋势,再结合队列积压、活跃线程占比等指标交叉验证,才能判断是不是常态化超载——不是单看“有没有拒绝”,而是看“拒绝是否稳定发生”。
拒绝计数器本身怎么用才规范
ThreadPoolExecutor 提供的 getRejectedExecutionCount() 是原子整型,线程安全,无需额外同步。但要注意三点:
- 它从 0 开始,首次拒绝后才非零,监控逻辑必须在 executor 初始化完成之后启动
- 不能靠单次采样值做判断,比如“当前是 17”没意义;要关注“过去 30 秒内每秒采样值是否持续 ≥3”
- 避免高频轮询(如每毫秒调一次),推荐每秒采样 1–2 次,配合滑动窗口(如 10 秒滚动求和)平滑毛刺
常态化超载的判定组合条件
仅拒绝数上升 ≠ 系统超载,需满足以下三者同时成立,才可定性为“常态化超载”:
- 拒绝率持续超标:过去 15 分钟内,拒绝任务数 / 已提交任务总数 ≥ 0.1%,且该比率连续 5 个采样周期未回落
-
队列长期高水位:队列使用率(
queue.size() / queue.capacity)持续 >90% 超过 60 秒,或无界队列下queue.size()稳定 >5000 -
活跃线程触顶不回落:
getActiveCount()长期等于maximumPoolSize,且getCompletedTaskCount()增速明显低于getTaskCount()
代码评审时重点检查的几类问题
在 CR 中看到线程池配置,应快速定位这四点是否闭环:
- 是否暴露了
getRejectedExecutionCount()指标到监控系统(如 Prometheus endpoint 或日志埋点) - 拒绝策略是否自定义为轻量异步行为(如只打日志 + 异步发告警),而非在拒绝路径中执行 DB 写入或 MQ 发送
- 是否配套限流降级逻辑(如 Sentinel 规则联动拒绝率阈值,自动触发 QPS 削峰)
- 是否区分了瞬时毛刺与常态化超载——例如用「连续 3 次采样拒绝数 >5」代替「只要 reject > 0 就告警」
附:一个可落地的 CR 检查清单片段
评审时可直接贴这段话进评论区:
- ✅ 拒绝计数已接入监控大盘,采样频率为 1Hz,滑动窗口 10 秒
- ✅ 自定义拒绝策略中无阻塞 I/O,日志含
queue.size()和activeCount() - ⚠️ 当前拒绝率 0.12%(15 分钟均值),建议检查
corePoolSize是否偏低或外部依赖响应变慢 - ❌ 缺少与限流组件的联动机制,无法实现拒绝率回升时自动收紧上游流量











