并发周期任务运行
我正在尝试寻找并行运行的周期性任务的最佳解决方案。要求:
- Java(Spring w/o Hibernate)。
- 任务由前端应用程序管理并存储在 MySQL DB 中(字段:
id
、频率
(以秒为单位)、<有关任务的其他属性/设置场景
>)。 -- 类似 crontab 的东西,只有频率(秒)字段,而不是分钟/小时/天/月/周中的天。
我正在考虑:
- TaskImporter线程从数据库轮询任务(通过TasksDAO.findToProcess())并将它们提交到队列。
java.util.concurrent.ThreadPoolExecutor
并行运行任务(来自队列)。
该架构中最棘手的部分是TasksDAO.findToProcess():
- 我如何知道现在应该运行哪些任务?
- 我正在考虑将填充的
next_run
任务字段(UPDATEtasks SET next_run = TIMESTAMPADD(SECOND, NOW(),Frequency) WHERE id = ?
选择后立即(SELECT * FROMtasksWHEREnext_runISNULLORnext_run<=NOW()FORUPDATE
)问题:必须为大量 SELECT'ed 任务运行大量更新(UPDATEforUPDATE)。每个任务或批量更新)+并发问题(见下文)。
- 我正在考虑将填充的
- 能够使用/轮询相同的数据库来运行多个并发处理应用程序(云)。
- 所有并发处理应用程序必须仅运行一次具体任务。必须锁定来自所有其他应用的所有 SELECT,直到应用 A 完成所有选定任务的更新 (
next_run
)。问题:锁定生产表(前端应用程序)会减慢速度。台镜?
- 所有并发处理应用程序必须仅运行一次具体任务。必须锁定来自所有其他应用的所有 SELECT,直到应用 A 完成所有选定任务的更新 (
我喜欢简单干净的解决方案,并相信有更好的方法来实现这个处理应用程序。你看到了吗? :)
提前致谢。
编辑:由于同步延迟,使用 Quartz 作为调度程序/执行程序不是一个选项。前端应用程序不是用Java编写的,因此无法与Quartz交互,除了面向Web服务的解决方案,这也不是一个选择,因为前端应用程序有更多与前面提到的任务相关的数据,并且需要直接访问所有任务DB 中的数据(读+写)。
I'm trying to find the best solution for periodic task running in parallel. Requirements:
- Java (Spring w/o Hibernate).
- Tasks are being managed by front-end application and stored in MySQL DB (fields:
id
,frequency
(in seconds), <other attributes/settings about task scenario
>). -- Something like crontab, only withfrequency
(seconds) field, instead of minutes/hours/days/months/days of weeks.
I'm thinking about:
TaskImporter
thread polling Tasks from DB (viaTasksDAO.findToProcess()
) and submitting them to queue.java.util.concurrent.ThreadPoolExecutor
running tasks (from queue) in parallel.
The most tricky part of this architecture is TasksDAO.findToProcess()
:
- How do I know which tasks is time to run right now?
- I'm thinking about
next_run
Task field, which would be populated (UPDATE tasks SET next_run = TIMESTAMPADD(SECOND, NOW(), frequency) WHERE id = ?
straight after selection (SELECT * FROM tasks WHERE next_run IS NULL OR next_run <= NOW() FOR UPDATE
). The problem: Have to run lots of UPDATES for lots of SELECT'ed tasks (UPDATE for each Task or bulk UPDATE) + concurrency problems (see below).
- I'm thinking about
- Ability to run several concurrent processing applications (cloud), using/polling same DB.
- All of the concurring processing applications must run concrete task only once. Must lock all SELECT's from all other apps, until app A finishes updating (
next_run
) of all selected tasks. The problem: locking production table (front-end app) would slow things down. Table mirror?
- All of the concurring processing applications must run concrete task only once. Must lock all SELECT's from all other apps, until app A finishes updating (
I love simple and clean solutions and believe there's a better way to implement this processing application. Do you see any? :)
Thanks in advance.
EDIT: Using Quartz as a scheduler/executor is not an option because of syncing latency. Front-end app is not in Java and so is not able to interact with Quartz, except Webservice-oriented solution, which is not an option too, because front-end app has more data associated with previously mentioned Tasks and needs direct access to all data in DB (read+write).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我建议使用像 Quartz 这样的调度 API,而不是使用自行开发的实现。
它提供了大量的API来实现逻辑和方便。您还将更好地控制工作。
http://www.quartz-scheduler.org/
http://www.quartz-scheduler.org/docs/tutorial/index.html html
I would suggest using Scheduling API like Quartz rather than using Home grown implementation.
It provides lot of API for implementation of logic and convenience. You will also have better control over jobs.
http://www.quartz-scheduler.org/
http://www.quartz-scheduler.org/docs/tutorial/index.html