Благодаря этой статье мы в основном объясним проблемы, возникающие в сервлете 3.0 асинхронной обработки в разработке Java и решениях. Ниже приведены конкретное содержание:
Servlet 3.0 начал предоставлять асинхронное контекст для поддержки асинхронной обработки запросов. Итак, какие преимущества может принести асинхронную обработку запросов?
Вообще говоря, способ обработки запросов веб -контейнеров - это назначить поток каждому запросу. Мы все знаем, что создание потоков не без затрат, а пул потоков веб -контейнеров имеет верхний предел.
Очень предсказуемая проблема заключается в том, что в условиях высокой нагрузки пул потоков занят, поэтому последующий запрос можно только ждать. Если вам не повезет, клиент сообщит об ошибке времени ожидания.
До появления Asynccontext единственный способ решить эту проблему - расширить пул потоков веб -контейнера.
Но с этим все еще есть проблема, рассмотрим следующие сценарии:
Существует веб-контейнер с размером пула потоков 200. Существует веб-приложение, которое имеет два сервлета, время, которое требуется сервис-а-a для обработки одного запроса, составляет 10 с, а время, которое требуется сервис-B для обработки одного запроса, составляет 1s.
Теперь мы сталкиваемся с высокой нагрузкой, с более чем 200 запросами на Сервлет-А. Если в настоящее время запрошен сервис-B, мы подождем, потому что все потоки HTTP были заняты сервисом-A.
В настоящее время инженер обнаружил проблему и расширил размер бассейна резьбов до 400, но нагрузка продолжала расти. Теперь есть 400 запросов на Сервлет-А, и Сервлет-B все еще не может ответить.
Вы видели проблему? Поскольку http-поток и рабочий поток соединены вместе, он заполнит потоковую передачу HTTP, когда будет выполнено большое количество запросов для трудоемкой операции, что приведет к тому, что весь веб-контейнер не может ответить.
Однако, если мы используем Asynccontext, мы можем передать трудоемкую операцию в другой поток, чтобы поток HTTP был выпущен, и мы могли обрабатывать другие запросы.
Обратите внимание, что только использование Asynccontext может достичь указанного выше эффекта. Если вы напрямую используете New Thread () или аналогичные методы, поток HTTP не будет возвращен в контейнер.
Вот официальный пример:
@Webservlet (urlpatterns = {"/asyncservlet"}, asyncsupported = true) public class asyncservlet расширяет httpservlet {/ * ... те же переменные и метод инициирования, как и в SyncServlet .../@Override public Void Doget (httpsErvEerquest recement) response.setContentType ("text/html; charset = utf-8"); Окончательный асинхронное текст acontext = request.startasync (); acontext.start (new Runnable () {public void run () {string param = acontext.getRequest (). getParameter ("param"); String result = resource.process (param); httpservletresponse response = acontext.getresponse (); / * ... print to action ... / acontext response.complete.complete (); }} ловушка
В этом официальном примере каждый поток HTTP откроет еще один рабочий поток для обработки запроса, а затем вернет поток HTTP в веб -контейнер. Но посмотрите на Javadoc метода asynccontext.start ():
Приводит к тому, что контейнер отправляет потоку, возможно, из управляемого пула потоков, запустить указанные запуска.
На самом деле, здесь нет регулирования, откуда исходит рабочая нить. Может быть, это еще один бассейн потоков, кроме бассейна HTTP? Или это просто бассейн HTTP?
Ограниченная полезность статьи AsyncContext.Start () Считывает: разные веб -контейнеры имеют разные реализации для этого, но Tomcat фактически использует пул потоков HTTP для обработки asynccontext.start ().
Это означает, что мы изначально хотели выпустить поток HTTP, но на самом деле это не так, потому что поток HTTP все еще используется в качестве потока работника, но этот поток не то же самое, что поток HTTP, получающий запрос.
Мы также можем увидеть этот вывод через эталон Jmeter AsyncServlet1 и SyncServlet, и результаты двух пропускной способности аналогичны. Метод запуска: запустите Main, а затем используйте jmeter для запуска Bentermark.jmx (http thread pool = 200 под конфигурацией по умолчанию Tomcat).
Использование исполнителей
Ранее я видел, что Tomcat не поддерживает бассейн рабочих потоков отдельно, поэтому мы должны найти способ сделать это сами, см. AsyncServlet2, который использует Executorservice с пулом потоков для обработки AsyncContext.
Другие способы
Следовательно, нет фиксированного способа использования асинхронного контекста. Вы можете использовать различные методы для решения этого в соответствии с фактическими потребностями. По этой причине вам нужны некоторые знания о параллельном программировании Java.
Неправильное понимание производительности
Цель Asynccontext не в том, чтобы улучшить производительность, и она не дает непосредственно улучшать производительность. Он обеспечивает механизм для отделки HTTP и рабочей потока, тем самым улучшая отзывчивость веб -контейнеров.
Однако в какой -то момент асинхронное контекст может повысить производительность, но это зависит от того, как написан ваш код.
Например: количество пулов потоков HTTP в веб -контейнере составляет 200, а сервт использует бассейн 300 рабочих потоков для обработки AsyncContext.
По сравнению с пулом потоков работников Sync Worker = пул потоков HTTP = 200, в этом случае у нас есть пул рабочих потоков 300, так что это определенно принесет некоторые улучшения производительности (в конце концов, есть больше людей).
Напротив, если количество рабочих потоков составляет <= количество потоков HTTP, не будет улучшения производительности, поскольку узкое место для обработки запросов находится в потоке работников.
Вы можете изменить размер пула потоков Asyncservlet2 и сравнить его с результатами Syncservlet Clinkmark для проверки этого вывода.
Не думайте, что бассейн рабочих потоков должен быть больше, чем пул потоков HTTP. Причины следующие:
Две обязанности разные. Одним из них является то, что веб -контейнер используется для получения внешних запросов , а другой - обработать бизнес -логику.
Создание потоков стоит по цене. Если пул потоков HTTP уже большой, то создание более крупного пула потоков работников приведет к слишком большому количеству контекста переключателя и накладных расходов памяти.
Цель AsyncContext-выпустить потоковую передачу HTTP, чтобы избежать долгосрочного использования операций и, таким образом, заставляя веб-контейнер не может ответить.
Таким образом, в большинстве случаев бассейн рабочих потоков не будет очень большим, а различные бассейны рабочих потоков будут построены в соответствии с различными предприятиями.
Например: размер бассейна пула веб -контейнеров составляет 200, а размер пула рабочих потоков составляет 10 для медленного сервлета. Таким образом, независимо от того, сколько запросов используется для замедления операций, это не заполнит потоковую передачу HTTP и не приведет к тому, что другие запросы не могут обработать.