当前位置: 首页 > 面试题库 >

使用“ crontab语法”进行EJB调度任务

欧阳杰
2023-03-14
问题内容

我试图找出解决以下问题的可能性。

a)我想拥有一个使用“ crontab语法”来计划任务的数据库表,其结构将如下所示:

    | -Id- | --- Crontab语法--- || ---------任务---------- |
    | 1 | 30 * * * * * | MyClass.TaskA(args [])|
    | 2 | 0 1 * * 1-5 * | MyClass.TaskB(args [])|
    | | | |

上表将随时由外部应用程序进行修改。添加或删除的任务应立即影响调度程序。

b)调度程序本身应驻留在Java应用程序服务器上。它应该与数据库表中活动的计划任务不断进行同步。每当发生调度事件时,都应触发/调用以“任务”中的值为参数的EJB。

我不是在寻找上述问题的答案。但是,可以将哪些框架用于crontab解析以及应该以哪种方式部署代表调度程序的EJB进行一些输入。

提前致谢。


问题答案:

请参阅EJB 3.1 @ScheduleAPI。我们为该规范选择的API比cron更接近Quartz语法-两者之间的微小差异。

这是一个注释示例:

package org.superbiz.corn;

import javax.ejb.Lock;
import javax.ejb.LockType;
import javax.ejb.Schedule;
import javax.ejb.Schedules;
import javax.ejb.Singleton;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * This is where we schedule all of Farmer Brown's corn jobs
 */
@Singleton
@Lock(LockType.READ) // allows timers to execute in parallel
public class FarmerBrown {

    private final AtomicInteger checks = new AtomicInteger();

    @Schedules({
            @Schedule(month = "5", dayOfMonth = "20-Last", minute = "0", hour = "8"),
            @Schedule(month = "6", dayOfMonth = "1-10", minute = "0", hour = "8")
    })
    private void plantTheCorn() {
        // Dig out the planter!!!
    }

    @Schedules({
            @Schedule(month = "9", dayOfMonth = "20-Last", minute = "0", hour = "8"),
            @Schedule(month = "10", dayOfMonth = "1-10", minute = "0", hour = "8")
    })
    private void harvestTheCorn() {
        // Dig out the combine!!!
    }

    @Schedule(second = "*", minute = "*", hour = "*")
    private void checkOnTheDaughters() {
        checks.incrementAndGet();
    }

    public int getChecks() {
        return checks.get();
    }
}

完整的源代码在这里

您可以通过ScheduleExpression类以编程方式执行相同的操作,该类只是上述批注的可构造版本。如果计划是在代码中完成的,则上面的示例如下所示:

package org.superbiz.corn;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.ejb.Lock;
import javax.ejb.LockType;
import javax.ejb.ScheduleExpression;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import javax.ejb.Timeout;
import javax.ejb.Timer;
import javax.ejb.TimerConfig;
import javax.ejb.TimerService;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * This is where we schedule all of Farmer Brown's corn jobs
 *
 * @version $Revision$ $Date$
 */
@Singleton
@Lock(LockType.READ) // allows timers to execute in parallel
@Startup
public class FarmerBrown {

    private final AtomicInteger checks = new AtomicInteger();

    @Resource
    private TimerService timerService;

    @PostConstruct
    private void construct() {
        final TimerConfig plantTheCorn = new TimerConfig("plantTheCorn", false);
        timerService.createCalendarTimer(new ScheduleExpression().month(5).dayOfMonth("20-Last").minute(0).hour(8), plantTheCorn);
        timerService.createCalendarTimer(new ScheduleExpression().month(6).dayOfMonth("1-10").minute(0).hour(8), plantTheCorn);

        final TimerConfig harvestTheCorn = new TimerConfig("harvestTheCorn", false);
        timerService.createCalendarTimer(new ScheduleExpression().month(9).dayOfMonth("20-Last").minute(0).hour(8), harvestTheCorn);
        timerService.createCalendarTimer(new ScheduleExpression().month(10).dayOfMonth("1-10").minute(0).hour(8), harvestTheCorn);

        final TimerConfig checkOnTheDaughters = new TimerConfig("checkOnTheDaughters", false);
        timerService.createCalendarTimer(new ScheduleExpression().second("*").minute("*").hour("*"), checkOnTheDaughters);
    }

    @Timeout
    public void timeout(Timer timer) {
        if ("plantTheCorn".equals(timer.getInfo())) {
            plantTheCorn();
        } else if ("harvestTheCorn".equals(timer.getInfo())) {
            harvestTheCorn();
        } else if ("checkOnTheDaughters".equals(timer.getInfo())) {
            checkOnTheDaughters();
        }
    }

    private void plantTheCorn() {
        // Dig out the planter!!!
    }

    private void harvestTheCorn() {
        // Dig out the combine!!!
    }

    private void checkOnTheDaughters() {
        checks.incrementAndGet();
    }

    public int getChecks() {
        return checks.get();
    }
}

此示例的来源在这里

附带说明,两个示例都可以在纯IDE中运行,并且具有使用Embeddable
EJBContainer
API的测试用例,这也是EJB 3.1中的新增功能。

@Schedule vs ScheduleExpression

  • @时间表
    • 静态配置
    • 可能有许多调度方法
    • 无法传递参数
    • 无法取消

以上都是在部署描述符中完成的,因此仅限于可以预先配置的内容。动态性更高的版本使用TimerService的以下签名:

TimerService.createCalendarTimer(javax.ejb.ScheduleExpression,javax.ejb.TimerConfig)

  • ScheduleExpression
    • 动态创建
    • 恰好一个@Timeout支持所有ScheduleExpression
    • 超时方法必须javax.ejb.Timer作为参数
    • 可以传递参数
    • 调用方将参数包装在TimerConfig.setInfo(Serializable)对象中
    • @Timeout方法通过Timer.getInfo()访问它们
    • 可以被调用者或@Timeout方法取消

还要注意,这里有一个拦截器@AroundTimeout注释,其功能与拦截器相同,@AroundInvoke并允许拦截器参与bean的计时器功能。



 类似资料:
  • 本文向大家介绍浅析Linux中crontab任务调度,包括了浅析Linux中crontab任务调度的使用技巧和注意事项,需要的朋友参考一下 一.创建调度任务 指令 crontab -e 进入当前用户编辑界面 crontab -u 用户名 -e 进入指定用户编辑界面 进入crontab任务编辑界面 任务编写格式 #每分钟执行查看一次/ect目录,把目录内容写进/tml/a.txt下 */ 1 * *

  • 我们有一个.NET项目,它检查远程计算机上是否存在一个文件。我们需要对一个部门内的多台远程计算机(数千台)执行此操作,每台计算机每天都在预定义的时间执行。执行时间是在数据库中指定的,它经常变化,每台远程计算机的执行时间都是不同的(有些可能是相同的)。为了实现这一点,我们计划使用Quartz调度器。由于我们是石英的新手,我们想知道如何实现这一点。在高层,我们需要这些- 调度程序应该在每天的特定时间启

  • 每隔一段时间需要调度任务执行,也许你想注册一个任务在客户端完成连接5分钟后执行,一个常见的用例是发送一个消息“你还活着?”到远端通,如果远端没有反应,则可以关闭通道(连接)和释放资源。 本节介绍使用强大的 EventLoop 实现任务调度,还会简单介绍 Java API的任务调度,以方便和 Netty 比较加深理解。 使用普通的 Java API 调度任务 在 Java 中使用 JDK 提供的 S

  • 问题内容: 在crontab中,星期几字段是从还是从? 我看到与此相关的信息冲突。我见过的维基百科州和其他网站都是。 同时这将是暗示或或者使用或不正确?也就是说,cron还会继续运行吗? 问题答案: 而这两种立场星期天,你可以使用你想要的,所以写0-6或1-7具有相同的结果。 此外,通过@Henrik的建议,也可以按天数,如缩短名称来代替数字,等: 图形化: 最后,如果要逐日指定,则可以用逗号分隔

  • 最近更新日期:20// 学习了基础篇也一阵子了,你会发现到为什么系统常常会主动的进行一些任务?这些任务到底是谁在设置工作的? 如果你想要让自己设计的备份程序可以自动的在系统下面执行,而不需要手动来启动他,又该如何处置? 这些例行的工作可能又分为“单一”工作与“循环”工作,在系统内又是哪些服务在负责? 还有还有,如果你想要每年在老婆的生日前一天就发出一封信件提醒自己不要忘记,可以办的到吗? 嘿嘿!这

  • 我正在尝试为我的Redux项目创建一个将使用对象而不是数组的深度复制映射方法。我读到在Redux中,每个状态都不应该改变前面状态中的任何东西。