Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/341.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 寻找spring应用程序的持久计时器_Java_Spring_Timer_Scheduled Tasks_Quartz Scheduler - Fatal编程技术网

Java 寻找spring应用程序的持久计时器

Java 寻找spring应用程序的持久计时器,java,spring,timer,scheduled-tasks,quartz-scheduler,Java,Spring,Timer,Scheduled Tasks,Quartz Scheduler,我正在寻找一个可以让我 定义一个将在将来某个特定时间调用一次的工作进程(不需要重新调度/cron-like功能),即计时器 工作人员应接受包含一些参数/输入的上下文 所有这些都应该在工作程序的数据库(或文件)中持久化 worker应该由spring管理——spring应该实例化worker,这样它就可以被注入依赖项 能够通过API动态地创建计时器,而不仅仅是通过SpringXMLBeans静态地创建计时器 很高兴有: 支持群集,即有多个节点可以承载一个工作进程。DB中的每个store jobn都

我正在寻找一个可以让我

  • 定义一个将在将来某个特定时间调用一次的工作进程(不需要重新调度/cron-like功能),即计时器
  • 工作人员应接受包含一些参数/输入的上下文
  • 所有这些都应该在工作程序的数据库(或文件)中持久化
  • worker应该由spring管理——spring应该实例化worker,这样它就可以被注入依赖项
  • 能够通过API动态地创建计时器,而不仅仅是通过SpringXMLBeans静态地创建计时器
  • 很高兴有:

  • 支持群集,即有多个节点可以承载一个工作进程。DB中的每个store jobn都会在其中一个节点上引起一个工作的调用动作
  • 我已经检查了几个备选方案,没有一个符合要求:

    • 石英
    当使用org.springframework.scheduling.quartz.JobDetailBean时,quartz会创建您的worker实例(而不是通过spring),这样您就无法获得Dependency iJet(这将导致我使用我想要避免的服务定位器)

    使用org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean时,无法获取上下文。您的工作者公开了一个不接受任何参数的公共方法。此外,当使用MethodInvokingJobDetailFactoryBean时,您不能使用持久性(从Javadoc格式)

    注意:通过此FactoryBean创建的作业详细信息不可序列化,因此不适用于持久作业存储。对于希望持久性作业委托给特定服务方法的每种情况,您都需要将自己的Quartz作业实现为一个瘦包装器

    • Spring的计时器和简单的JDK计时器不支持持久性/集群特性
    我知道我可以使用DB和Spring(甚至JDK)定时器来实现,但我更喜欢使用3r party库


    有什么建议吗

    您的要求3和4对我来说没有什么意义:您如何将整个包(worker+work)序列化,并让它神奇地醒来并开始工作?你的跑步系统中的某些东西不应该在适当的时候这样做吗?这不应该是工人吗


    我的方法是:创建一个计时器,Spring可以实例化并向其注入依赖项。然后,该计时器将从持久性存储中加载其工作/任务,安排它们执行并执行它们。您的类可以是
    java.util.Timer
    的包装器,根本不处理调度内容。您必须自己实现集群相关逻辑,以便只有一个计时器/工作者可以执行工作/任务。

    如果您希望创建作业详细信息以在运行时生成触发器/作业详细信息,并且仍然能够在您可以参考的bean上使用Spring DI,它展示了如何与ObjectFactoryCreatingFactoryBean结合使用,在运行时使用Spring注入的Bean创建Quartz触发对象。

    对于那些对Quartz的替代方案感兴趣的人,请查看
    db scheduler
    ()。持久性任务/执行计划保存在单个数据库表中。集群中的调度器保证只执行一次

  • 是的,请参见下面的代码示例

  • 当前仅限于单个字符串标识符,没有格式限制。调度器将来可能会扩展,更好地支持作业详细信息/参数

  • 执行时间和上下文在数据库中是持久的。当调度程序启动时,将任务名称绑定到工作进程。只要Spring实现了
    ExecutionHandler
    接口,就可以实例化worker

  • 见第3段)

  • 是的,请参见下面的代码示例
  • 代码示例:

    private static void springWorkerExample(DataSource dataSource, MySpringWorker mySpringWorker) {
    
        // instantiate and start the scheduler somewhere in your application
        final Scheduler scheduler = Scheduler
                .create(dataSource)
                .threads(2)
                .build();
        scheduler.start();
    
        // define a task and a handler that named task, MySpringWorker implements the ExecutionHandler interface
        final OneTimeTask oneTimeTask = ComposableTask.onetimeTask("my-onetime-task", mySpringWorker);
    
        // schedule a future execution for the task with a custom id (currently the only form for context supported)
        scheduler.scheduleForExecution(LocalDateTime.now().plusDays(1), oneTimeTask.instance("1001"));
    }
    
    
    public static class MySpringWorker implements ExecutionHandler {
        public MySpringWorker() {
            // could be instantiated by Spring
        }
    
        @Override
        public void execute(TaskInstance taskInstance, ExecutionContext executionContext) {
            // called when the execution-time is reached
            System.out.println("Executed task with id="+taskInstance.getId());
        }
    }
    

    请注意,我需要每个工作只被调用一次没有重复。每个工作进程都不会更改其状态(即jobDataMap)。从持久性POV来看,我需要:存储作业定义(何时触发以及执行什么)和jobDataMap,它们在调度期间不会发生变化。您的计时器“bean”与DB可以强制执行单个执行。“获胜”计时器(实际执行任务的计时器)记录在数据库中,以防止其他计时器获取任务;还将记录成功执行的任务。其余部分实际上取决于您的需要:计时器是否应该轮询DB以获取新任务?如何提交新任务?当一个任务没有被错误执行时会发生什么?是否应该由其他计时器接管?该任务是立即执行还是稍后执行?这正是我所需要的。Thankslink已失效,调用JobDetailFactoryBean的方法仍然无法使用quartz
    jdbc
    模式。请添加您是作者的免责声明。