【问题标题】:Concurrent periodic task running并发周期性任务运行
【发布时间】:2010-07-28 02:16:40
【问题描述】:

我正在尝试为并行运行的定期任务找到最佳解决方案。要求:

  1. Java(没有休眠的 Spring)。
  2. 任务由前端应用程序管理并存储在 MySQL DB 中(字段:idfrequency(以秒为单位)、other attributes/settings about task scenario>)。 -- 类似 crontab 的东西,只有 frequency(秒)字段,而不是分钟/小时/天/月/星期几。

我在想:

  1. TaskImporter 线程从 DB 轮询任务(通过 TasksDAO.findToProcess())并将它们提交到队列。
  2. java.util.concurrent.ThreadPoolExecutor 并行运行任务(来自队列)。

这个架构中最棘手的部分是TasksDAO.findToProcess()

  1. 我如何知道哪些任务现在可以运行?
    • 我正在考虑 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 任务运行大量更新(更新每个任务或批量更新)+ 并发问题(见下文)。
  2. 能够运行多个并发处理应用程序(云),使用/轮询相同的数据库。
    • 所有并发处理应用程序必须只运行一次具体任务。必须锁定所有其他应用程序的所有 SELECT,直到应用程序 A 完成所有选定任务的更新 (next_run)。问题:锁定生产表(前端应用程序)会减慢速度。桌镜?

我喜欢简单而干净的解决方案,并且相信有更好的方法来实现这个处理应用程序。你有看到吗? :)

提前致谢。


编辑: 由于同步延迟,不能选择使用 Quartz 作为调度程序/执行程序。前端应用程序不是 Java 语言,因此无法与 Quartz 交互,除了面向 Web 服务的解决方案,这也不是一个选项,因为前端应用程序有更多与前面提到的任务相关的数据,需要直接访问所有DB中的数据(读+写)。

【问题讨论】:

    标签: java multithreading architecture parallel-processing threadpool


    【解决方案1】:

    我建议使用 Quartz 之类的调度 API,而不是使用自制实现。 它提供了大量的API来实现逻辑和方便。您还将更好地控制工作。 http://www.quartz-scheduler.org/ http://www.quartz-scheduler.org/docs/tutorial/index.html

    【讨论】:

    • 我在这里看到的唯一风险是 DB 和 Quartz 调度程序同步延迟,这可能会导致某些作业在被取消或运行频率更改后运行。可以做些什么来避免这些情况?
    • 使用 Quartz 时,您可以使用其 API 而不是您当前拥有的数据库来添加/安排任务。 Quartz 提供了将这些任务调度保存到 DB 的方法。所以你的前端会有所改变,实际上完全使用 Quartz API 来添加/调度任务,而不使用你当前的数据库。
    • 太好了,我将使用 JDBCJobStore 将我的作业存储在数据库中(它们必须在非 Java 前端可见并且必须与其他数据相关联)。谢谢!
    • 强烈建议不要修改存储在 Quartz DB 表中的任何数据,因此此方法将无法按预期工作。不接受更多选项的答案。
    • 是的,它的真实数据不应该在 Quartz DB 中被修改。但是您认为要更新哪些与 Quartz 相关的数据?是必需的吗?就像使用 Quartz 时一样,可以从 Quartz API 获取下一个运行时间。您不需要将它单独存储在 DB 中或修改它由 Quartz 管理。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    • 2017-07-10
    • 2021-02-05
    • 2013-06-08
    • 2019-05-25
    • 1970-01-01
    • 2018-11-28
    相关资源
    最近更新 更多