2012-01-16 145 views
12

我们在集群WebLogic 10.3.4环境中运行Spring 3.0.x Web应用程序(.war),并且每晚都有@Scheduled作业。但是,随着应用程序部署到每个节点(使用AdminServer的Web控制台中的部署向导),作业每晚在每个节点上启动,从而同时运行多次。仅在一个WebLogic群集节点上运行@ Scheduled任务?

我们应该如何防止这种情况发生?

我知道象Quartz这样的库允许通过数据库锁表协调集群环境内的作业,或者我甚至可以自己实现类似这样的事情。但是,由于这似乎是一个相当常见的情况,我不知道Spring是否已经提供了一个选项,可以轻松绕过这个问题,而无需将新库添加到我的项目或手动解决方法。

请让我知道,如果有任何悬而未决的问题。我也在Spring Community forums上问过这个问题。非常感谢你的帮助。

+0

您想实现某种故障转移吗?如果这样配置配置文件在这里不会真的有用,并且无论如何您都需要一些同步。我们有一个类似的要求,最终得到一个锁表,它也提供了一些快速执行摘要。 – mrembisz 2012-01-16 11:56:46

+0

@mrembisz不,我们(现在)不在寻找故障转移,因为这会使事情变得非常复杂。 – 2012-01-16 12:26:25

回答

2

我们正在应用程序数据库中使用共享锁定表来实现我们自己的同步逻辑。这允许所有群集节点在自己启动之前检查一个作业是否已经运行。

+0

你在这里使用什么隔离级别? Read_committed或可序列化? – 2015-12-22 19:10:35

5

我们只有一项任务发送每日摘要电子邮件。为了避免额外的依赖性,我们只需检查每个节点的主机名是否与配置的系统属性相对应。

private boolean isTriggerNode() { 
    String triggerHostmame = System.getProperty("trigger.hostname");; 
    String hostName = InetAddress.getLocalHost().getHostName(); 
    return hostName.equals(triggerHostmame); 
} 

public void execute() { 
    if (isTriggerNode()) { 
     //send email 
    } 
} 
+0

这是一个不错的主意,感谢分享! – 2013-05-15 17:49:03

3

要小心,因为在使用共享锁表实现自己的同步逻辑的解决方案,你总有其中两个群集节点正在读/在同一时间从表中编写并发问题。

最佳是执行在1分贝交易以下步骤: - 共享锁表 读取的值 - 如果没有其他节点具有锁,以锁定 - 更新该表指示你把锁

+0

嗨Mathias。即使已经有一段时间了,感谢您的有益建议。我们实际上在单个事务中执行了锁定条目的检查和写入。好点和常见的陷阱。 – 2013-08-05 14:18:56

0

您可以尝试从WebLogic使用TimerManager(集群环境中的Job Scheduler)作为TaskScheduler实现(TimerManagerTaskScheduler)。它应该在集群环境中工作。

Andrea

3

我解决了这个问题,使其中一个框作为主。 基本上在master = true之类的框中设置一个环境变量。

并通过system.getenv(“master”)在您的java代码中读取它。 如果它的存在和它的真实然后运行你的代码。

基本片断

@schedule() 
void process(){ 
boolean master=Boolean.parseBoolean(system.getenv("master")); 
if(master) 
{ 
    //your logic 
} 

} 
+1

我认为这不是最好的解决方案,可以想象你有两个节点的集群,你把第一个节点作为主节点,第二个节点不是。之后由于任何原因第一个节点出现故障,那么您的作业将不会被执行,因为应该处理作业的节点不会被执行,因此您将失去集群环境中的最重要功能“高可用性” – AmjadD 2016-10-13 14:58:27

0

我们可以对集群的其他机器不使用以下的cron字符串运行批处理作业。它不会运行到2099年。

0 0 0 1 1?2099

相关问题