Cron4jPlugin定时插件在多tomcat的负载均衡中会执行多次

发布于 2022-01-06 06:45:22 字数 76 浏览 911 评论 3

咨询下,用Cron4jPlugin定时配置定时任务,在多tomcat的负载均衡中会多次的执行,有没有其他方式来解决这个问题,只想执行一次?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

情绪失控 2022-01-08 00:36:33

回复真是太及时了,简直秒回,感谢波总,我试试。

眉黛浅 2022-01-07 22:05:36

回复
@gaopeng8 : 代码刚刚被改进过,上一次的少一个 if 判断: // 只有 lock 更新成了自己生成的 lock 值,才能表明被自己抢到了 if (task.getLock().equals(lock) { return task; } 注意再回看一下代码

混吃等死 2022-01-07 21:00:44

利用数据库或者 redis 担当一个共享数据的地方,让多个 Cron4jPlugin 去共享数据库或共享的 redis 中去取要调度的任务

 

例如使用 mysql 数据库, 建一张 task 表, 其中有下面字段:

task(id, cron, class, lock)

其中 id 是任务 id,cron 是任务调度用的表达式,lock 是抢占该任务的锁,关键在于如何抢点锁,下面是示例代码:

public Task getTask() {
  // 获取一条未被抢占的 task 记录的 id 值
  Integer taskId = Db.queryId("select id from task where lock is null");
  
  // 所有 task 已被抢占
  if (taskId == null) {
     return null;
  }
  
  // 获取一个全球唯一的不可能重复的 uuid 值,作为本 JVM 进程抢占 task 的 lock 值
  String lock = StrKit.getRandomUUID();
  
  // 更新该 task 的 lock 值抢占该 task,注意 where 条件中的 lock is null 避免多个进程抢占同一个 task
  int n = Db.update("update task set lock = ? where id = ? and lock is null", lock, taskId);
  
  // n > 0 时表示抢占成功
  if (n > 0) {
     Task task = new Task().findById(taskId);

     // 只有 lock 更新成了自己生成的 lock 值,才能表明被自己抢到了
     if (task.getLock().equals(lock) {
       return task;
     }
  }

  return null;
}

   上面的 getTask 方法可能会返回 null,这是由于多进程/线程会有争抢的情况出现,可以使用在 for 循环中执行该 getTask() 方法重试抢几次的策略

   如果还觉得并发下不保险,可以在上面代码中添加事务:

Db.tx( () -> {
   这里放上前面 getTask 中的代码,抢占成功 return true, 否则 return false;
});

 

最后,通过 getTask() 得到 Task 对象以后,取出 Task 中的 cron 表达式以及 class 值来 new Cron4jPlugin(...).start()

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文