2010-02-12 5 views
19

Ich habe eine Webanwendung mit Servlet und JSP entwickelt. Ich benutze keinen Rahmen per se, stattdessen verwende ich meinen eigenen MVC-Rahmen. Ich benutze MySQL als Backend.regelmäßige Aufgabe auf der Serverseite für Servlet ausführen JSP MVC Website

Ich möchte folgendes tun: alle 15 Minuten in einer XML-Datei

irgendwo

  1. Abgleich einige Daten aus der Datenbank jede Stunde
  2. generieren und zu speichern Statistiken über Daten Das Problem ist: Derzeit läuft mein gesamter Code als Ergebnis der Anfrage von einem Client.

    Wie führe ich periodische Aufgaben auf der Serverseite aus?

    Eine Lösung, die ich gerade habe, ist es, einen Thread in der Init-Funktion des Controllers zu erstellen. Gibt es noch andere Optionen?

Antwort

41

Sie können ServletContextListener verwenden, um einige Initialisierungen beim Start von webapp auszuführen. Die Standard-Java-API zum Ausführen periodischer Tasks wäre eine Kombination aus Timer und TimerTask. Hier ist ein Kick-off Beispiel:

public void contextInitialized(ServletContextEvent event) { 
    Timer timer = new Timer(true); 
    timer.scheduleAtFixedRate(new CleanDBTask(), 0, oneHourInMillis); 
    timer.scheduleAtFixedRate(new StatisticsTask(), 0, oneQuartInMillis); 
} 

wo die beiden Aufgaben aussehen können wie:

public class CleanDBTask extends TimerTask { 
    public void run() { 
     // Implement. 
    } 
} 

Timer Verwendung ist jedoch nicht in Java EE empfohlen. Wenn der Task eine Ausnahme auslöst, wird der gesamte Thread Timer gelöscht, und Sie müssen den gesamten Server im Grunde neu starten, damit er erneut ausgeführt wird. Die Timer reagiert auch empfindlich auf Änderungen im Systemtakt.

Die neuere und robustere java.util.concurrent Weg wäre eine Kombination von ScheduledExecutorService und nur eine Runnable. Hier ist ein Kick-off Beispiel:

private ScheduledExecutorService scheduler; 

public void contextInitialized(ServletContextEvent event) { 
    scheduler = Executors.newSingleThreadScheduledExecutor(); 
    scheduler.scheduleAtFixedRate(new CleanDBTask(), 0, 1, TimeUnit.HOURS); 
    scheduler.scheduleAtFixedRate(new StatisticsTask(), 0, 15, TimeUnit.MINUTES); 
} 

public void contextDestroyed(ServletContextEvent event) { 
    scheduler.shutdownNow(); 
} 
+2

Gerade BalusC fantastische Antwort hinzufügen mögen, dass '' ScheduledExecutorService' die scheduleAtFixedRate' und 'scheduleWithFixedDelay' Methoden künftig Hinrichtung unterdrücken, wenn Ausnahme in einem Durchlauf aufgetreten ist. Denken Sie also daran, mit Ihren Ausnahmen umzugehen. 'Wenn bei der Ausführung der Task eine Ausnahme auftritt, werden nachfolgende Ausführungen unterdrückt.' – dvd