pool.setUncaughtExceptionHandler((t, e) ->
log.error("task failed in {}", t.getName(), e));
一批 1000 个任务,实际成功 700 个,日志里没有任何异常栈,监控显示任务全部提交成功,失败率 30% 过了两天才被发现。这类现象通常不是突然出现的,往前翻半天日志能看到苗头。
追下去是这么回事:用 submit 提交时异常被封在 Future 里,不调 get 就永远看不到。execute 才会把异常交给 UncaughtExceptionHandler。
「任务异常被吞」确认了原因之后,改动尽量只碰那一处,顺手改的东西后面最容易出问题。同一份配置存在多处的,先确认改的是被加载的那一份。
新版本先放一台机器上跑一天再全量,问题一般在这段时间暴露。备份不是备了就行,恢复一次才算数,很多备份文件打开才发现是空的。
处理上按这个顺序:给线程池设置 UncaughtExceptionHandler 记录线程和异常;submit 的返回值统一处理 取结果时捕获 ExecutionException;或者在任务内部 try-catch 后上报失败计数;统计成功数和提交数 差额超过阈值就告警。
确认没问题再收工,失败任务在日志里有完整堆栈,成功数与提交数的差额能被监控看到。
