new ThreadFactory() {
    private final AtomicInteger n = new AtomicInteger();
    public Thread newThread(Runnable r) {
        return new Thread(r, "order-pool-" + n.incrementAndGet());
    }
}

线上 CPU 高,jstack 导出 800 行,线程名清一色 pool-1-thread-N 和 pool-2-thread-N,分不清哪个池在跑订单哪个在跑推送。先别急着动参数,把报错原文和时间点记下来,顺序反了容易白折腾。

原因不复杂,默认线程工厂用池编号加线程序号命名,和业务无关。多个池的编号还会随创建顺序变化,重启一次全不一样。

「线程命名规范」改完先别急着全量,挑一台机器放半天,真有问题这段时间就能看出来。改完隔一天再看一次,当场正常不代表能稳住。

测试环境和线上的差别,往往就在版本号和那几行被忽略的配置上。线上出问题先对时间点,跟发布、备份、任务执行的时刻排一排,能省掉一半功夫。

处理上按这个顺序:自定义 ThreadFactory 名字带上业务名和序号;把池名写进日志的 MDC 异常时能直接对上;用 jstack 抓一次 确认能按名字过滤出对应池;线程数变化时名字里的序号不要复用错位。

改完只确认一件事:jstack 里能直接匹配到 order-pool-12,定位到具体业务池。

作者 9823189