当前位置: 首页 > 知识库问答 >
问题:

如何在特定时间窗口中运行方法

谷永贞
2023-03-14

我有一个微服务,它会收到一条消息,大概是这样的:

["00:12", "12:20", "15:40"]

是否有任何开箱即用的解决方案允许方法每天在给定时间运行?使用 Spring 中的 cron 不涉及在运行时更改时间。我需要使用更灵活的选项(更改运行时,多次启动)

谢谢!

共有2个答案

江永安
2023-03-14

最佳解决方案取决于(几乎总是)您的基础设施必须工作的环境。

您可以使用@Scheduled(即在集群环境中运行的SpringScheduled Task),但它在集群中的性能不佳(通常只有一个节点在运行作业)。

我将提出一种在简单性,效率和可靠性之间取得良好平衡的解决方案。稍后我将讨论它的一些属性。

建议的解决方案:

  1. 使用具有保证原子性的有序列表(消息队列、redis排序列表、db表…)。
  2. 客户的请求,它会简单地将一个项目添加到该列表中。
  3. 您将根据需要培养尽可能多的工人,他们可以是一个、几个或根据需要自动扩展。
  4. 每个工作人员将(原子地)检查他是否必须处理作业。注意:最佳方法是对列表有一个钩子,这样当列表发生变化时,它们就会得到推送,这样就不需要重复读取列表(工作人员只需等待最近的时刻)。

这种方法值得注意的特性:

  1. 可能有一个或多个节点同时运行作业。
  2. 节点可能会损坏、需要很长时间等,而不会影响挂起的作业(只需看到没有空闲工作线程即可执行自动缩放)。
  3. 您可以轻松检查作业是否丢失(例如,运行它的节点已损坏),是否尝试多次运行但没有成功,等等......
  4. 状态为持续,您可以检查是否错过了作业,恢复作业等...
  5. 根据您需要解决方案的效率,它可以非常复杂(钩子,自动缩放状态等)或非常简单(简单的开始转换;从作业中选择1个ID 时间

杜绍元
2023-03-14

Spring有@Scheduled注释。有几种方法可以配置它,一种方法是像 unix cron 作业一样配置它。

例如像这样:

@Scheduled(cron = "0 15 10 15 * ?")
public void scheduleTaskUsingCronExpression() {
 
    long now = System.currentTimeMillis() / 1000;
    System.out.println(
      "schedule tasks using cron jobs - " + now);
}

这里的任务安排在每月15日上午10:15执行。

但是也有一些方法可以在运行时动态地配置延迟或速率,例如如下(取自baeldung.com):

@Configuration
@EnableScheduling
public class DynamicSchedulingConfig implements SchedulingConfigurer {

    @Autowired
    private TickService tickService;

    @Bean
    public Executor taskExecutor() {
        return Executors.newSingleThreadScheduledExecutor();
    }

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.setScheduler(taskExecutor());
        taskRegistrar.addTriggerTask(
          new Runnable() {
              @Override
              public void run() {
                  tickService.tick();
              }
          },
          new Trigger() {
              @Override
              public Date nextExecutionTime(TriggerContext context) {
                  Optional<Date> lastCompletionTime =
                    Optional.ofNullable(context.lastCompletionTime());
                  Instant nextExecutionTime =
                    lastCompletionTime.orElseGet(Date::new).toInstant()
                      .plusMillis(tickService.getDelay());
                  return Date.from(nextExecutionTime);
              }
          }
        );
    }

}

Instant nextExecutionTime = ...这一行可以替换为你自己的逻辑来设置下一个执行时间,就像解析数组中的时间一样。

看看这个baeldung教程:https://www.baeldung.com/spring-scheduled-tasks

另外,请查看这里的cron符号:https://www.netiq.com/documentation/cloud-manager-2-5/ncm-reference/data/bexyssf.html

 类似资料:
  • 问题内容: 我想编写一个简单的python脚本来完成特定的工作。我花了一些时间从网站链接信息。 在正确的时间单击这些链接的最佳方法是什么?我是否需要计算当前电流与列表中的电流之间的时间间隔并睡眠一会儿? 我真的停留在这一点上,并欢迎任何可能有用的想法。 问题答案: 看一下Python的sched模块。

  • 我尝试了各种方法来关闭我在互联网上可以找到的tkinter窗口。我问这个问题的唯一原因是,尽管已经被问了很多次,我仍然无法让它起作用。 基本上,我正在制作一个简单的“倒计时”游戏(就像电视节目一样),其中包括一个30秒的大倒计时。数字会正确地打勾,但是除非用户手动关闭窗口,否则程序不会继续。显然,这首先违背了计时器的目的,但是我如何让它在我想要的时候自动关闭呢? 下面是一个不起作用的非常简单的示例

  • 我对Java还很陌生,我试着查了一下,但没有找到任何有用的东西。我想知道我怎么能检测到一个特定的窗口关闭了?我一直在使用windowClosing(),但这适用于关闭的任何窗口,因此如果窗口B关闭,我希望由于窗口a关闭而发生的事件也会发生。我如何只在窗口A关闭的情况下进行检测?抱歉,如果这是一个糟糕的措辞,我不知道那么多Java术语。提前致谢:)

  • 是否可以在特定的时间调用java中的方法?例如,我有一段这样的代码: 如何在java中实现这一点?

  • 问题内容: 我需要帮助在特定时间(如下午2点)在服务器上运行Java程序(以索引新文件)。 有人告诉我Java有一些叫做Job的东西,但我不知道该如何使用。我尝试了这个: 但是有了这个程序仍在运行。 如何在指定时间运行程序? 问题答案: 有一个名为Quartz的API ,您的程序可以在其中调度“作业”,并在该时刻运行它。 在给出示例之前,请尝试使用此链接。 编辑:首先,您必须创建一个实现org.q

  • 问题内容: 我有一个Web应用程序,每小时与中央数据库同步四次。该过程通常需要2分钟。我想将此进程作为线程在X:55,X:10,X:25和X:40运行,以便用户知道在X:00,X:15,X:30和X:45他们有数据库的干净副本。这只是管理期望。我已经通过了执行器,但是调度是通过它完成的,我认为不能保证以小时为单位的实际运行时间。我可以使用第一个延迟来启动,以便第一个接近启动时间和每15分钟的计划,