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

Что рекомендуется для нереста потоков из сервлета в Tomcat

Возможно повторение! Я использую Tomcat в качестве своего сервера и хочу знать, что лучше всего запускать потоки в сервлете с детерминированными результатами. Я запускаю некоторые длительные обновления из действия сервлета и хотел бы, чтобы запрос был завершен, а обновления выполнялись в фоновом режиме. Вместо добавления промежуточного программного обеспечения для обмена сообщениями, такого как RabbitMQ, я думал, что могу создать поток, который может работать в фоновом режиме и заканчиваться в свое время. Я читал в других потоках SO, что сервер завершает потоки, порожденные сервером, чтобы он хорошо управлял ресурсами.

Есть ли рекомендуемый способ нереста потоков, фоновые задания при использовании Tomcat. Я также использую Spring MVC для приложения.

4b9b3361

Ответ 1

Ваша самая безопасная ставка использует широко распространенный пул потоков приложения с максимальным количеством потоков, так что задачи будут поставлены в очередь в случае необходимости. ExecutorService очень полезен в этом.

При запуске приложения или инициализации сервлета используйте класс Executors:

executor = Executors.newFixedThreadPool(10); // Max 10 threads.

Затем во время службы сервлетов (вы можете игнорировать результат для случая, который вам неинтересен):

Future<ReturnType> result = executor.submit(new CallableTask());

Наконец, во время остановки приложения или уничтожения сервлета:

executor.shutdownNow(); // Returns list of undone tasks, for the case that.

Ответ 2

Возможно, вы можете использовать реализацию CommonJ WorkManager (JSR 237), например Foo-CommonJ:

CommonJ - JSR 237 Таймер и WorkManager

Foo-CommonJ - это таймер JSR 237 и Реализация WorkManager. Это предназначенные для использования в контейнерах, которые не приходят со своими реализация - в основном простой сервлет таких как Tomcat. Это также может быть используется в полностью раздутых приложениях Java EE серверы, на которых нет WorkManager API или иметь нестандартный API, например JBoss.

Зачем использовать WorkManager?

Общим вариантом использования является то, что сервлет или JSP необходимо агрегировать данные из нескольких источников и отображать их в одна страница. Выполнение собственных потоков управляемый environement, как J2EE контейнер не подходит и должен никогда не выполняться на уровне приложений код. В этом случае API WorkManager может использоваться для извлечения данных в параллельны друг другу.

Установка/развертывание CommonJ

Развертывание ресурсов JNDI зависит от поставщика. Эта реализация поставляется с классом Factory, который реализует javax.naming.spi.ObjectFactoryинтерфейс с легкостью развертывается в самых популярных контейнеры. Он также доступен как Служба JBoss. больше...

Обновление:. Чтобы уточнить, вот что Concurrency Утилиты для предварительного просмотра Java EE (выглядит это преемник JSR-236 и JSR-237) пишет о неуправляемых потоках:

2.1 Управляемые контейнером или неуправляемые потоки

Серверы приложений Java EE требуют управления ресурсами в порядке централизовать администрирование и защищать компоненты приложения от потребляя ненужные ресурсы. Это может достигается путем объединения ресурсов и управления ресурсами жизненный цикл. Использование Java SE concurrencyтаких, как java.util.concurrency API, java.lang.Thread и java.util.Timer на сервере компонент приложения, такой как сервлет или EJB проблематичны, поскольку у контейнера и сервера нет знание этих ресурсов.

Расширяя java.util.concurrent API, серверов приложений и Java EE контейнеры могут осознать ресурсы, которые используются и обеспечивают надлежащий контекст выполнения для асинхронные операции для работы с.

В основном это достигается путем предоставления управляемые версии преобладающего java.util.concurrent.ExecutorServiceинтерфейсы.

Итак, ничего нового IMO, "старая" проблема не меняется, неуправляемый поток все еще неуправляемых потоков:

  • Они неизвестны серверу приложений и не имеют доступа к контекстной информации Java EE.
  • Они могут использовать ресурсы на задней панели сервера приложений и без какой-либо возможности администрирования контролировать их количество и использование ресурсов, это может повлиять на способность сервера приложений восстанавливать ресурсы из-за сбоя или изящно завершить работу.

Ссылки

Ответ 3

Spring поддерживает асинхронную задачу (в вашем случае длинный) через spring -scheduling. Вместо прямого использования потоков Java я предлагаю использовать его с Quartz.

ресурсы:

Ответ 4

Строго говоря, вам не разрешено создавать потоки в соответствии со спецификацией Java EE. Я также хотел бы рассмотреть возможность атаки на отказ в обслуживании (преднамеренно или иначе), если сразу поступит несколько запросов.

Решение промежуточного программного обеспечения, безусловно, будет более надежным и совместимым со стандартами.

Ответ 5

Я знаю, что это старый вопрос, но люди все время спрашивают об этом, пытаясь сделать это (явно порождая потоки при обработке запроса сервлета) все время... Это очень ошибочный подход - для более чем одна из причин... Просто заявив, что Java EE-контейнеры нахмурились в такой практике, недостаточно, хотя в целом это правда...

Самое главное, никогда нельзя предсказать, сколько одновременных запросов сервлет будет получать в любой момент времени. Веб-приложение, сервлет, по определению, предназначено для обработки нескольких запросов на данной конечной точке за раз. Если вы программируете, вы запрашиваете логику обработки для явного запуска определенного количества параллельных потоков, вы рискуете столкнуться с любой, но неизбежной ситуацией, когда заканчиваются доступные потоки и удушаете ваше приложение. Ваш исполнитель задач всегда настроен на работу с пулом потоков, который ограничен ограниченным разумным размером. Чаще всего он не превышает 10-20 (вы не хотите, чтобы слишком много потоков выполняли вашу логику - в зависимости от характера задачи, ресурсов, за которые они конкурируют, количества процессоров на вашем сервере и т.д.). Скажем, ваш обработчик запросов (например, метод MVC-контроллера) вызывает один или несколько методов @Async-annotated (в этом случае Spring абстрагирует исполнитель задачи и облегчает вам задачу) или явно использует исполнитель задачи. По мере выполнения кода он начинает захватывать доступные потоки из пула. Это прекрасно, если вы всегда обрабатываете один запрос одновременно без немедленных последующих запросов. (В этом случае вы, вероятно, пытаетесь использовать неправильную технологию для решения своей проблемы.) Однако, если это веб-приложение, которое подвергается произвольным (или даже известным) клиентам, которые могут забивать конечную точку с запросами, вы будете быстро исчерпайте пул потоков, и запросы начнут накапливаться, ожидая появления потоков. По этой причине вы должны понимать, что можете ошибаться, если вы рассматриваете такой дизайн.

Лучшим решением может быть этап обработки данных, которые будут обрабатываться асинхронно (это может быть очередь или любой другой тип временного/промежуточного хранилища данных) и вернуть ответ. Имейте внешнее, независимое приложение или даже несколько его экземпляров (развернутых за пределами вашего веб-контейнера) опроса конечной точки (ов) промежуточного процесса и обработки данных в фоновом режиме, возможно, используя конечное количество параллельных потоков. Не только такое решение даст вам преимущество асинхронной/параллельной обработки, но также будет масштабироваться, потому что вы сможете запускать столько экземпляров такого опролле, сколько вам нужно, и их можно распределить, указывая на конечную точку промежуточного уровня. HTH

Ответ 6

Так как Spring 3, вы можете использовать аннотации @Async:

@Service
public class smg {
  ...
  @Async
  public getCounter() {...}
}

с <context:component-scan base-package="ch/test/mytest"> и <task:annotation-driven/> в файле контекста

Обратитесь к этому руководству: http://spring.io/blog/2010/01/05/task-scheduling-simplifications-in-spring-3-0/

Отлично работает для меня на Tomcat7, и вам не нужно управлять пулом потоков.