Подтвердить что ты не робот

Запуск фоновой Java-программы в Tomcat

Может ли кто-нибудь посоветовать здесь? У меня есть ситуация, когда пользователи будут отправлять запросы интеллектуального анализа данных интерактивно через Java JSP и сервлет на мое приложение, которое будет динамически разрабатывать правила ассоциации для данных и многое другое.

Поскольку такое задание может занять некоторое время, я думаю о каком-то процессе на сервере для запуска такого запроса в фоновом режиме, поэтому он не блокирует сеанс и, возможно, использует огромные объемы памяти сервера в ущерб системе.

Как система состоит из серии Java JSP и сервлетов, запущенных в контейнере Tomcat через базу данных MySQL, может ли кто-нибудь посоветовать путь вперед?

Спасибо

Г-н Морган

4b9b3361

Ответ 1

Используйте ExecutorService.

Если вам нужно сделать несколько действий, отметьте поток как поток демона, чтобы он по крайней мере не привязал tomcat в сценариях ошибок, и вы должны остановить исполнителя, когда ваш контекст сервлета будет уничтожен (например, при повторном развертывании или остановите свое приложение. Для этого используйте 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;
    }
}

Вам нужно будет добавить прослушиватель контекста к вашему web.xml, где вы также можете указать количество потоков, которые вы хотите запустить фоновые задания:

  <listener>
    <listener-class>com.example.ExecutorContextListener</listener-class>
  </listener>

Вы можете получить доступ к исполнителю из своего сервлета и отправить ему задания:

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

Если вы используете Spring, все это, вероятно, можно сделать даже проще

Ответ 2

Я думаю, что планировщик Quartz должен быть способен выполнить то, что вы хотите сделать здесь. Вот некоторые примеры из Quartz. Используя это, вы можете запустить cron, который быстро опросит для обработки входящих запросов. Я действительно сделал это для одного из моих проектов.

Ответ 4

Возможно, JMS - это то, что вы действительно ищете, но это требует дополнительных усилий, чтобы использовать это на Tomcat, потому что это только контейнер сервлетов. Вы можете переключиться на реальный AppServer, например Glassfish или JBoss, или добавить JMS-функциональность Tomcat своим собственным (ниже ссылки).

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