java-ee - 怎么处理JavaEE应用中异步处理数据的异常

 残伤贱爱 发布于 2022-10-30 14:35

目前的应用中,用户可以上传压缩文件,csv文件等到服务器,后他会解析这些文件并把抽取出来的记录存储到数据库中,考虑到这个过程很耗时,所以采用异步的方案:

1 用户上传文件

2 创建一个job,并存储到数据库,这个job包含了文件名、文件路径、状态(未开始)等信息

3 请求结束,提示用户任务已经提交

4 后台通过ExecutorService启动线程用来操作文件,同时更新job,把状态改为进行中,处理结束后,更新状态为已完成,并删掉原文件

5 用户刷新页面可以查看当前的处理状态

看起来没问题,但是万一在处理过程中发生了捕获不了的异常 比如停电、tomcat窗口被意外关闭怎么办?

我考虑过在应用启动的时候检查所有未完成的job,然后启动这些job,但是由于部署的是集群A B C,面临几个问题:

假设 A和B都由于某种原因down了,然后重启,他们会同时试图启动未完成的失败的任务,也就是说同一个任务可能会被不同的服务器同时执行

假设Adown了,然后重启,这时候B正在执行一个任务,但是A认为这个任务未完成,就尝试重试,又导致了冲突

这种情况大家一般是怎么处理的?

2 个回答
  • 如果遇到停电、Tomcat异常中止等情况,一定会再重启。

    重启服务之后第一件事先检查 进行中 的任务,将其标记为 异常中止 或者 未开始,目的是让处理程序能重新开始处理这些任务(本来 未开始 就可以实现目标,但是如果用 异常中止 更适合日志或者人工检查)。

    之后的过程就和最开始处理一样的了。

    另外,如果你有多个处理程序,可以考虑专门写一个“分配程序”来分配任务,而不是由处理程序自己去取,这样可以更大限度的避免重复处理。当然这个“分配程序”除了分配和修改状态别的啥也不干,以保证效率。

    2022-10-31 21:40 回答
  • 数据表里多记录一项:当前job运行时所属节点信息,比如任务正在运行在B节点上,那么A重启的时候看到这条任务所属B,那么就不管咯。
    不知是否满足你的要求?

    另外可以考虑Quartz之类的框架,自带任务持久化功能,支持集群~

    2022-10-31 21:40 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有