ThreadPoolTaskExecutor 异步任务 对于长时间大数据的执行,执行一半线程终止。

生产环境上,对于较大的数据导出,使用了ThreadPoolTaskExecutor 的异步任务。
实际使用中发现,对于较大的数据导出如4G的sqlite的DB文件,异步任务执行到一半的时候不在执行,通过进度最终发现,进度到一定的时候就不在进行任务了,们目前试了2次,一次是1520/3344,一次是1778/3344 停止任务。
我不清楚是不是线程抛出异常了,因为我在现有的日志中没有发现相关异常记录,如果是 我应该怎么记录这个日志呢?
Spring配置

<!-- 核心线程数,默认为1 -->

<!-- 最大线程数,默认为Integer.MAX_VALUE -->

<!-- 队列最大长度,一般需要设置值>=notifyScheduledMainExecutor.maxNum;默认为Integer.MAX_VALUE-->

<!-- 线程池维护线程所允许的空闲时间,默认为60s -->

<!-- 线程池对拒绝任务(无线程可用)的处理策略,目前只支持AbortPolicy、CallerRunsPolicy;默认为后者 -->

<!-- AbortPolicy:直接抛出java.util.concurrent.RejectedExecutionException异常 -->



//自动注入
@Autowired
ThreadPoolTaskExecutor threadPoolTaskExecutor;
//异步任务
ExportDbTaskThread zipPackageThread = new ExportDbTaskThread(resultPackageService,expFile,contextPath,
tbType,filterParam,sortParam,xzqdm+xzqmc,progressId);
threadPoolTaskExecutor.execute(zipPackageThread);

    问题已解决; sqllite 存入blob字段时 以流的形式将多媒体文件读入流中,并在流中组装prmt,导致堆内存溢出,使线程无限等待。

3个回答

问题已解决; sqllite 存入blob字段时 以流的形式将多媒体文件读入流中,并在流中组装prmt,导致堆内存溢出,使线程无限等待。

  • 队列最大长度,一般需要设置值>=notifyScheduledMainExecutor.maxNum;默认为Integer.MAX_VALUE--> 是不是用了fixedThreadPool ,如果是 这个值还是要约束一下

当请求速度远大于处理速度,队列的无限加入,会无限膨胀,造成 资源耗尽,服务宕掉
可以考虑用cachedThreadPool

我对这个问题比较感兴趣,请保持交流

qq_34720342
十锁 1.一条线程 会导出1个DB文件 文件较大 请求频率较低 不会超过队列最大长度 2.服务并没有宕掉,其他服务仍然正常使用,只是本线程执行到一半后不再往数据库写入,数据库连接也没释放,日志系统中并没有相关异常。
5 个月之前 回复

我的几点建议:
首先,确认下代码中有没有可能发生死锁状态,如果任务运行异常而其他任务又在等待它的锁资源,就可能死锁了。
其次,在任务运行中包裹异常处理,保证任务即使异常也能够结束,工作线程能空闲出来继续执行其他任务。
最后,在任务运行的各个主要节点打印一些调试日志。

qq_34720342
十锁 谢谢您的建议! 1.线程的代码逻辑是不断的从数据库查询数据,通过数据在oss上找到对应的多媒体数据(图片,视频等)转存2进制存储到sqllite的DB文件中,我认为不会发生死锁。2,任务运行中有异常处理,并在顶层通过e.printStackTrace() 抛出,但未在log4j的日志中找到相关异常信息。3.任务执行一半后不再继续执行任务,数据库连接不释放。
5 个月之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!