2017-02-19 9 views
0

Использование Spring MVC У меня есть контроллер, который делает запрос API внешней службе, которая может занять много времени. Я делаю это синхронно, потому что хочу вернуть результат внешнего запроса пользователю. В идеале это не блокирует целую цепочку за это время, вроде как асинхронный/ожидающий идиом стиля C#, но я не уверен, как это сделать с Spring (или что-то еще).Обработка длинных процессов в Spring MVC-контроллерах

ответ

1

Вы можете использовать аннотацию @Async для некоторого метода обслуживания для асинхронного выполнения.

+0

спасибо. К сожалению, AFAIK это приведет к асинхронной задаче в пуле потоков, и единственный способ вернуть результат в клиентский запрос - это cal get() в Будущем, который заблокирует поток запросов –

0

Spring MVC построен на вершине сервлета, это означает, что (по умолчанию) все, что вы делаете внутри метода Controller, блокирует поток запросов, предоставляемый Tomcat (Tomcat является контейнером сервлетов по умолчанию для Spring Boot в наши дни). Если вы вызываете другую службу на основе HTTP или запрашиваете базу данных внутри вашего контроллера, вы, вероятно, блокируете IO-вызов. Блокировка вызовов всегда будет блокировать вызывающий поток, асинхронный/ожидающий в C# - это просто синтаксический сахар, например, Springs @Async использует скрытую ThreadPool для выполнения реальной работы.

Если вы не можете вызвать службу восходящего потока с помощью селектора NIO, вам понадобится поток, ожидающий ответа, и в этом случае имеет смысл просто блокировать поток потока Tomcat, я считаю, что по умолчанию количество потоков запросов - 150, но при необходимости вы можете установить его выше. Если восходящую службу можно вызвать с помощью NIO, вам нужен только один поток для всех вызовов этой службы, и вы можете вернуть DeferedResult с вашего контроллера и написать ответ клиенту, как только ответ от восходящей службы будет были произведены.

0

Это просто. Не вызывайте длинный api из вашего основного метода контроллера. Просто верните представление (JSP). Затем вы можете запустить запрос ajax из вашего метода document.ready в вашем представлении (Javascript). Вы можете иметь отдельный обработчик @ResourceRequest в вашем контроллере для обработки вызова ajax. Верните результат api (как JSON или что-то еще) для вызывающего абонента ajax. После того как представление получит ответ ajax, обновите пользовательский интерфейс по своему усмотрению.

Смежные вопросы