Question

J'utilise Java et je veux garder un servlet fonctionnant en continu dans ma demande, mais je ne reçois pas comment le faire. Mon servlet a une méthode qui donne compte de l'utilisateur à partir d'une base de données sur une base quotidienne, ainsi que le nombre total des utilisateurs de la base de données entière. Donc, je veux garder le servlet en cours d'exécution en continu pour cela.

Était-ce utile?

La solution

Votre problème est que vous méprendre sur le but du servlet . Il est intented à agir sur les requêtes HTTP, rien de plus. Vous voulez juste une tâche d'arrière-plan qui fonctionne une fois sur une base quotidienne.

EJB disponible? Utilisez @Schedule

Si votre environnement arrive à EJB support (par exemple un vrai serveur Java EE tels que wildfly, JBoss, tomee, Payara, GlassFish, etc.), puis utilisez @Schedule à la place. Voici quelques exemples:

@Singleton
public class BackgroundJobManager {

    @Schedule(hour="0", minute="0", second="0", persistent=false)
    public void someDailyJob() {
        // Do your job here which should run every start of day.
    }

    @Schedule(hour="*/1", minute="0", second="0", persistent=false)
    public void someHourlyJob() {
        // Do your job here which should run every hour of day.
    }

    @Schedule(hour="*", minute="*/15", second="0", persistent=false)
    public void someQuarterlyJob() {
        // Do your job here which should run every 15 minute of hour.
    }

    @Schedule(hour="*", minute="*", second="*/5", persistent=false)
    public void someFiveSecondelyJob() {
        // Do your job here which should run every 5 seconds.
    }

} 

Oui, c'est vraiment tout. Le conteneur collecte automatiquement et de le gérer.

EJB indisponible? Utilisez ScheduledExecutorService

Si votre environnement ne prend pas en charge EJB (vous ne l'utilisez pas un vrai serveur Java EE, mais un barebone servletcontainer comme Tomcat, Jetty, etc.), puis utilisez ScheduledExecutorService . Cela peut être initié par un ServletContextListener . Voici un exemple de coup d'envoi:

@WebListener
public class BackgroundJobManager implements ServletContextListener {

    private ScheduledExecutorService scheduler;

    @Override
    public void contextInitialized(ServletContextEvent event) {
        scheduler = Executors.newSingleThreadScheduledExecutor();
        scheduler.scheduleAtFixedRate(new SomeDailyJob(), 0, 1, TimeUnit.DAYS);
        scheduler.scheduleAtFixedRate(new SomeHourlyJob(), 0, 1, TimeUnit.HOURS);
        scheduler.scheduleAtFixedRate(new SomeQuarterlyJob(), 0, 15, TimeUnit.MINUTES);
        scheduler.scheduleAtFixedRate(new SomeFiveSecondelyJob(), 0, 5, TimeUnit.SECONDS);
    }

    @Override
    public void contextDestroyed(ServletContextEvent event) {
        scheduler.shutdownNow();
    }

}

Lorsque les catégories d'emplois ressemblent à ceci:

public class SomeDailyJob implements Runnable {

    @Override
    public void run() {
        // Do your daily job here.
    }

}
public class SomeHourlyJob implements Runnable {

    @Override
    public void run() {
        // Do your hourly job here.
    }

}
public class SomeQuarterlyJob implements Runnable {

    @Override
    public void run() {
        // Do your quarterly job here.
    }

}
public class SomeFiveSecondelyJob implements Runnable {

    @Override
    public void run() {
        // Do your quarterly job here.
    }

}

Ne pensez jamais sur l'utilisation java.util.Timer / java.lang.Thread dans un environnement Java EE / Servlet

Last but not least, jamais utiliser directement java.util.Timer et / ou java.lang.Thread en Java EE. Ceci est la recette des ennuis. Une explication élaborée peut être trouvée dans cette réponse liée à JSF sur la même question: fils frayant dans un bean géré JSF pour les tâches planifiées en utilisant une minuterie.

Autres conseils

Je suggère d'utiliser une bibliothèque comme le quartz afin d'exécuter la tâche à intervalles réguliers. Qu'est-ce que le servlet vraiment faire? Il vous envoie un rapport?

Mettre en œuvre deux classes et appel startTask() dans main.

public void startTask()
{
    // Create a Runnable
    Runnable task = new Runnable() {
        public void run() {
            while (true) {
                runTask();
            }
        }
    };

    // Run the task in a background thread
    Thread backgroundThread = new Thread(task);
    // Terminate the running thread if the application exits
    backgroundThread.setDaemon(true);
    // Start the thread
    backgroundThread.start();
}

public void runTask()
{
    try {
        // do something...         
        Thread.sleep(1000);

    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

Dans un système de production qui peut avoir de multiples récipients non jee en cours d'exécution. Utilisez anot planificateur d'entreprise comme planificateur Quartz qui peut être configuré pour utiliser une base de données pour la tâche maamgememt.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top