2014-10-16 7 views
5

Ich habe zwei Tomee-Instanzen gruppiert.Making @Schedule nur einmal in einer Clusterumgebung ausführen

Jedes hat eine Methode wie kommentierten

@Schedule(dayOfWeek = "*") 
public void runMeDaily() {...} 

ich diese Methode möchte nur einmal am Tag laufen. Nicht zweimal am Tag (eine für jede Instanz)

Ich könnte eine Flagge wie hier beschrieben verwenden Run @Scheduled task only on one WebLogic cluster node? oder wählen Sie einfach einige Knoten, aber ich frage mich, ob es eine elegantere Möglichkeit, das zu tun ist.

Diese Frage hängt etwas mit EJB3.1 @Schedule in clustered environment zusammen, aber ich benutze JBOSS nicht. (und es wird nicht beantwortet)

+0

https://github.com/SpringOnePlatform2016/dsyer-locks-and-leaders – MariuszS

Antwort

1

ich nur diese eine nicht-Java EE-Lösung lösen könnte, die spezifisch für die Plattform (proprietär). In meinem Fall verwende ich TomEE + und Quartz. Wenn Quartz im Clustermodus (org.quartz.jobStore.isClustered = true) ausgeführt wird und die Timer in einer einzelnen Datenbank beibehalten werden, muss Quartz eine Instanz auswählen, die den Timer auslöst. Daher wird es nur einmal ausgeführt.

Dieser Link war sehr nützlich - http://rmannibucau.wordpress.com/2012/08/22/tomee-quartz-configuration-for-scheduled-methods/

Es ist eine Schande, Java EE kein Verhalten für das nicht angibt. (noch, ich hoffe) :-)

2

Ich benutze den gleichen Ansatz wie in anderen Thread - überprüfen, dass bestimmte Host ist der richtige Job zu laufen. Aber ..

Ich bin nicht sehr Info ee Werkzeuge, aber im Frühjahr können Sie Profile dafür verwenden. Wahrscheinlich können Sie eine ähnliche Lösung für Ihre Bedürfnisse finden. Werfen Sie einen Blick auf http://spring.io/blog/2011/06/21/spring-3-1-m2-testing-with-configuration-classes-and-profiles

Sie zwei separate Bohnen definieren:

@Configuration 
@Profile("dev") 
public class StandaloneDataConfig { 

@Bean 
public DataSource dataSource() { 
    return new EmbeddedDatabaseBuilder() 
     .setType(EmbeddedDatabaseType.HSQL) 
     .addScript("classpath:com/bank/config/sql/schema.sql") 
     .addScript("classpath:com/bank/config/sql/test-data.sql") 
     .build(); 
} 
} 

@Configuration 
@Profile("production") 
public class JndiDataConfig { 

@Bean 
public DataSource dataSource() throws Exception { 
    Context ctx = new InitialContext(); 
    return (DataSource) ctx.lookup("java:comp/env/jdbc/datasource"); 
} 
} 

und entscheiden, welches durch Umschalten Profil zu aktivieren. Ihre Klasse mit der mit @Schedule versehenen Methode würde also nur für ein bestimmtes Profil geladen. Natürlich müssen Sie dann Ihre App so konfigurieren, dass nur das Profil der Knoten aktiviert wird. In der Frühlings-App wäre es so einfach wie das -Dupring.profiles.active = Profil zu einem von ihnen zu übergeben.

+0

tolle Idee, ich werde einen Blick darauf werfen :-) Ich fürchte, ich kann ' In diesem Projekt wechselst du jetzt in den Frühling, aber ich werde deine Option in der nächsten sicherlich berücksichtigen. Danke! – Leo

+0

Wie ich schon sagte, Sie können wahrscheinlich etwas Ähnliches in ejb finden. – freakman

-1

Ich löste dieses Problem, indem ich eine der Box als Master machte. im Grunde eine Umgebungsvariable auf einer der Box wie Master = True.

und lesen Sie es in Ihrem Java-Code durch system.getenv ("Master"). Wenn es vorhanden und wahr ist, dann führe deinen Code aus.

Grund Schnipsel

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

}