Exécution d’un programme Java d’arrière-plan dans Tomcat

Quelqu’un peut-il conseiller ici? Je suis dans une situation où les utilisateurs soumettent des requêtes d’exploration de données de manière interactive via un JSP Java et un servlet à une de mes applications qui élaborera de manière dynamic des règles d’association sur les données et plus encore.

Comme un tel travail peut prendre un certain temps, je pense à une sorte de processus sur le serveur pour exécuter une telle requête en arrière-plan afin de ne pas “verrouiller” la session et éventuellement utiliser des quantités massives de mémoire au désortingment du système.

Étant donné que le système est constitué d’une série de JSP et de servlets Java exécutés dans un conteneur Tomcat sur une firebase database MySQL, est-ce que quelqu’un peut proposer une solution?

Merci

Mr Morgan

    Utilisez un ExecutorService .

    Il y a quelques choses que vous devez faire, marquez le thread comme un thread de démon pour qu’il n’attache pas Tomcat dans les scénarios d’erreur, et vous devez arrêter l’exécuteur lorsque votre contexte de servlet est détruit (par exemple lorsque vous redéployez ou arrêtez votre application). Pour ce faire, utilisez un ServletContextListener:

    public class ExecutorContextListener implements ServletContextListener { private ExecutorService executor; public void contextInitialized(ServletContextEvent arg0) { ServletContext context = arg0.getServletContext(); int nr_executors = 1; ThreadFactory daemonFactory = new DaemonThreadFactory(); try { nr_executors = Integer.parseInt(context.getInitParameter("nr-executors")); } catch (NumberFormatException ignore ) {} if(nr_executors <= 1) { executor = Executors.newSingleThreadExecutor(daemonFactory); } else { executor = Executors.newFixedThreadPool(nr_executors,daemonFactory); } context.setAttribute("MY_EXECUTOR", executor); } public void contextDestroyed(ServletContextEvent arg0) { ServletContext context = arg0.getServletContext(); executor.shutdownNow(); // or process/wait until all pending jobs are done } } import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; /** * Hands out threads from the wrapped threadfactory with setDeamon(true), so the * threads won't keep the JVM alive when it should otherwise exit. */ public class DaemonThreadFactory implements ThreadFactory { private final ThreadFactory factory; /** * Construct a ThreadFactory with setDeamon(true) using * Executors.defaultThreadFactory() */ public DaemonThreadFactory() { this(Executors.defaultThreadFactory()); } /** * Construct a ThreadFactory with setDeamon(true) wrapping the given factory * * @param thread * factory to wrap */ public DaemonThreadFactory(ThreadFactory factory) { if (factory == null) throw new NullPointerException("factory cannot be null"); this.factory = factory; } public Thread newThread(Runnable r) { final Thread t = factory.newThread(r); t.setDaemon(true); return t; } } 

    Vous devrez append l'écouteur de contexte à votre fichier web.xml, où vous pourrez également spécifier le nombre de threads sur lesquels vous souhaitez exécuter les jobs d'arrière-plan:

       com.example.ExecutorContextListener  

    Vous pouvez accéder à l'exécuteur à partir de votre servlet et lui soumettre des travaux:

     ExecutorService executor = (ExecutorService )getServletContext().getAtsortingbute("MY_EXECUTOR"); ... executor.submit(myJob); 

    Si vous utilisez Spring, tout cela peut être encore plus simple

    Je pense que le programmateur Quartz devrait pouvoir accomplir ce que vous voulez faire ici. Voici quelques exemples de Quartz . En utilisant ceci, vous pouvez lancer un cron qui interroge rapidement pour traiter les demandes entrantes. Je l’ai effectivement fait pour l’un de mes projets.

    Une solution légère (par opposition à l’utilisation d’un ordonnanceur comme le quartz) consisterait à placer le traitement dans un thread d’arrière-plan et à l’exécuter via un ExecutorService.

    http://download.oracle.com/javase/6/docs/api/java/util/concurrent/Executors.html
    http://download.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html

    Peut-être que JMS est ce que vous recherchez vraiment, mais cela demande un effort supplémentaire pour l’utiliser sur Tomcat car il ne s’agit que de Servlet Container. Vous pouvez basculer vers un véritable AppServer tel que Glassfish ou JBoss ou append la fonctionnalité JMS à Tomcat par vous-même (lien ci-dessous).

    http://blogs.captechconsulting.com/blog/jairo-vazquez/tomcat-and-jms