【发布时间】:2010-07-28 02:16:40
【问题描述】:
我正在尝试为并行运行的定期任务找到最佳解决方案。要求:
- Java(没有休眠的 Spring)。
- 任务由前端应用程序管理并存储在 MySQL DB 中(字段:
id、frequency(以秒为单位)、other attributes/settings about task scenario>)。 -- 类似 crontab 的东西,只有frequency(秒)字段,而不是分钟/小时/天/月/星期几。
我在想:
-
TaskImporter线程从 DB 轮询任务(通过TasksDAO.findToProcess())并将它们提交到队列。 -
java.util.concurrent.ThreadPoolExecutor并行运行任务(来自队列)。
这个架构中最棘手的部分是TasksDAO.findToProcess():
- 我如何知道哪些任务现在可以运行?
- 我正在考虑
next_run任务字段,它将在选择后立即填充 (UPDATE tasks SET next_run = TIMESTAMPADD(SECOND, NOW(), frequency) WHERE id = ?(SELECT * FROM tasks WHERE next_run IS NULL OR next_run <= NOW() FOR UPDATE)。问题:必须为大量 SELECT 任务运行大量更新(更新每个任务或批量更新)+ 并发问题(见下文)。
- 我正在考虑
- 能够运行多个并发处理应用程序(云),使用/轮询相同的数据库。
- 所有并发处理应用程序必须只运行一次具体任务。必须锁定所有其他应用程序的所有 SELECT,直到应用程序 A 完成所有选定任务的更新 (
next_run)。问题:锁定生产表(前端应用程序)会减慢速度。桌镜?
- 所有并发处理应用程序必须只运行一次具体任务。必须锁定所有其他应用程序的所有 SELECT,直到应用程序 A 完成所有选定任务的更新 (
我喜欢简单而干净的解决方案,并且相信有更好的方法来实现这个处理应用程序。你有看到吗? :)
提前致谢。
编辑: 由于同步延迟,不能选择使用 Quartz 作为调度程序/执行程序。前端应用程序不是 Java 语言,因此无法与 Quartz 交互,除了面向 Web 服务的解决方案,这也不是一个选项,因为前端应用程序有更多与前面提到的任务相关的数据,需要直接访问所有DB中的数据(读+写)。
【问题讨论】:
标签: java multithreading architecture parallel-processing threadpool