线程池拒绝策略是主动调控流量、保障核心业务可用性的关键开关,需与降级联动设计,按任务重要性分层隔离、物理拆分线程池,拒绝即触发记录、告警、轻量降级或闭环补偿,并配套入口限流、超时控制与任务落库等底座措施。

线程池拒绝策略不是等系统快崩了才启动的补丁,而是主动调控流量、守住核心业务可用性的关键开关。它必须和降级方案联动设计,才能做到“不丢关键任务、不拖垮上游、可观测可干预”。
按任务重要性分层隔离,拒绝策略才有意义
混用线程池会让拒绝策略失效——核心支付任务和日志上报挤在同一个池子里,一旦慢查询卡住线程,下单请求只能排队等死。必须物理拆分:
- 核心池:只跑订单创建、库存预占、风控决策等毫秒级链路;配有界队列(如 ArrayBlockingQueue,容量 100–300) + CallerRunsPolicy;目标是宁可响应变慢,也不丢任务、不抛异常、不阻塞容器线程
- 非核心池:专用于报表导出、AI推理、MQ重试、埋点上报等;配较小队列(20–50)+ AbortPolicy 或自定义告警策略;即使全满失败,也不影响核心池一根线程
拒绝不是终点,而是降级动作的起点
一次 RejectedExecutionException 必须触发明确的业务响应,不能只打日志或静默吞掉:
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 记录完整上下文:traceId、任务类型(如 “order-pay”)、线程池名、队列当前长度、活跃线程数、拒绝时间
- 分级告警:P0(支付类拒绝)立即电话告警;P1(通知类)企业微信+钉钉;P2(日志类)仅记指标不打扰
- 同步执行轻量降级:比如返回缓存结果、空响应、本地 fallback 方法;严禁在拒绝逻辑里发起远程调用或 DB 写入
高可靠场景必须闭环:拒绝 → 持久化 → 补偿
对“一次都不能少”的任务(如资金对账、履约确认),光靠 CallerRuns 不够,需构建可验证、可恢复的闭环:
立即学习“Java免费学习笔记(深入)”;
- 自定义策略中将任务序列化为 JSON,写入 Redis Stream(带唯一 taskId 和时间戳)
- 后台定时任务(如每 5 秒)扫描 Redis,将待处理任务重新 submit 到线程池,并做幂等校验(查 DB 或 Redis 是否已成功)
- Redis 设置 72 小时过期,失败超 3 次的任务转入人工核查队列
配套措施缺一不可
拒绝策略再好,没有底座支撑也会失效:
- 入口限流:在网关或 Controller 层加 Sentinel QPS 控制,防止突发流量直接打满线程池
- 外部调用必设超时:HTTP 连接+读取超时 ≤ 3s,避免一个慢依赖拖死整池
- 任务提交前落库标记:如写 DB 记录 task_status = 'pending',后续可反查是否丢失或卡住

















