对账任务本该跑 4800 笔,结果只处理了 3590 笔,日志里一条 RejectedExecutionException 都没有,差额 1210 笔全是状态一直挂着的单。乍看像缓存或者权限的锅,追下去往往不是。
ThreadPoolExecutor pool = new ThreadPoolExecutor(
16, 32, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<>(2000),
new ThreadPoolExecutor.AbortPolicy());
追下去是这么回事:DiscardPolicy 的 rejectedExecution 是空实现,任务被丢掉时既不抛异常也不打日志。提交方看到 submit 正常返回,以为任务已经在跑。
「DiscardPolicy 静默丢弃」相关的日志我一般连着看前后五分钟,单看一条报错经常判断不出是哪一步失败。测试环境和线上的差别,往往就在版本号和那几行被忽略的配置上。
线上出问题先对时间点,跟发布、备份、任务执行的时刻排一排,能省掉一半功夫。日志级别临时调高可以,记得改回去,长期开着既占磁盘又掩盖真问题。
具体做法是,换成 AbortPolicy 或自定义策略 丢弃前把任务标识写进日志;在自定义策略里累加丢弃计数 接到监控面板;对账类任务改成有返回值 提交后校验完成数;上线后核对总数和成功数是否相等。
验收就看一点,任务总数和成功数对得上,拒绝发生时日志里有任务号和队列长度。
