Как обрабатывать несколько запросов параллельно с помощью @RestController SpringBoot? ⇐ JAVA
Как обрабатывать несколько запросов параллельно с помощью @RestController SpringBoot?
Я относительно новичок в Spring Boot и начал с очень простого примера с их начального сайта, а именно (на стороне контроллера):
@RestController публичный класс HelloController { @RequestMapping("/") индекс публичной строки() { return «Привет от Spring Boot!»; } } Теперь я хочу, чтобы несколько (потенциально длительных) запросов одного и того же контроллера могли обслуживаться параллельно.
Поскольку я уже узнал, что экземпляр @RestController будет создан как синглтон, для меня ясно, что несколько запросов (которые обрабатываются одним и тем же методом) будут обработаны последовательно. Обновление: Моя вина: я думал, что это связано с тем, что контроллер был одноэлементным. Но это правда: почему тогда он не может работать параллельно?
Поэтому я изменил приведенный выше пример следующим образом, чтобы новый экземпляр контроллера создавался при каждом запросе и с некоторыми средствами проверки того, что на самом деле происходит:
@RestController @Scope (значение = «запрос») публичный класс HelloController { частный статический счетчик AtomicInteger = новый AtomicInteger (0); общественный HelloController() { count.incrementAndGet(); } @PostConstruct общественная недействительность инициализации () { System.out.println("запрос на запуск" + count); } @PreDestroy общественная недействительность onDestroy () { System.out.println("завершить запрос" + count); } @RequestMapping("/") public String index() выдает InterruptedException { LocalDateTime сейчас = LocalDateTime.now(); TimeUnit.SECONDS.sleep(15); System.out.println(сейчас); return "Привет от Spring Boot!" + now + " " + count.get(); } } Теперь я ожидаю увидеть, что запросы обрабатываются параллельно примерно за 15 секунд, но на самом деле я вижу только то, что они явно обрабатываются последовательно и что это занимает 30 секунд (на стандартном выводе):
запустить запрос 1 2017-02-11T14:19:47.429 завершить запрос 1 начать запрос 2 2017-02-11T14:20:02.467 завершить запрос 2 Итак, мой вопрос: как я могу добиться, чтобы такие запросы обрабатывались параллельно, поскольку явно недостаточно создавать экземпляр для каждого запроса?
Небольшое замечание: я уже пробовал использовать аннотацию @Asnync в сочетании с @EnableAsync для класса приложения, но это похоже на принцип «выстрелил и забыл», например что я не могу получить ответ для отображения на стороне клиента.
Несколько записей здесь о stackoverflow (например, эта и эта) были интересны, но также не ответили на мой вопрос, как и это руководство по асинхронным методам.
Обновление. Поскольку несколько человек отметили, что проблема может быть связана с тем, как я тестировал, я попытался запустить ее в другом браузере. Интересно, что у меня возникли те же проблемы как в Chrome, так и в Firefox. Но при выполнении одного запроса от каждого он показал ожидаемое поведение (параллельное обслуживание запросов) – так что меня обманули браузеры...
Я относительно новичок в Spring Boot и начал с очень простого примера с их начального сайта, а именно (на стороне контроллера):
@RestController публичный класс HelloController { @RequestMapping("/") индекс публичной строки() { return «Привет от Spring Boot!»; } } Теперь я хочу, чтобы несколько (потенциально длительных) запросов одного и того же контроллера могли обслуживаться параллельно.
Поскольку я уже узнал, что экземпляр @RestController будет создан как синглтон, для меня ясно, что несколько запросов (которые обрабатываются одним и тем же методом) будут обработаны последовательно. Обновление: Моя вина: я думал, что это связано с тем, что контроллер был одноэлементным. Но это правда: почему тогда он не может работать параллельно?
Поэтому я изменил приведенный выше пример следующим образом, чтобы новый экземпляр контроллера создавался при каждом запросе и с некоторыми средствами проверки того, что на самом деле происходит:
@RestController @Scope (значение = «запрос») публичный класс HelloController { частный статический счетчик AtomicInteger = новый AtomicInteger (0); общественный HelloController() { count.incrementAndGet(); } @PostConstruct общественная недействительность инициализации () { System.out.println("запрос на запуск" + count); } @PreDestroy общественная недействительность onDestroy () { System.out.println("завершить запрос" + count); } @RequestMapping("/") public String index() выдает InterruptedException { LocalDateTime сейчас = LocalDateTime.now(); TimeUnit.SECONDS.sleep(15); System.out.println(сейчас); return "Привет от Spring Boot!" + now + " " + count.get(); } } Теперь я ожидаю увидеть, что запросы обрабатываются параллельно примерно за 15 секунд, но на самом деле я вижу только то, что они явно обрабатываются последовательно и что это занимает 30 секунд (на стандартном выводе):
запустить запрос 1 2017-02-11T14:19:47.429 завершить запрос 1 начать запрос 2 2017-02-11T14:20:02.467 завершить запрос 2 Итак, мой вопрос: как я могу добиться, чтобы такие запросы обрабатывались параллельно, поскольку явно недостаточно создавать экземпляр для каждого запроса?
Небольшое замечание: я уже пробовал использовать аннотацию @Asnync в сочетании с @EnableAsync для класса приложения, но это похоже на принцип «выстрелил и забыл», например что я не могу получить ответ для отображения на стороне клиента.
Несколько записей здесь о stackoverflow (например, эта и эта) были интересны, но также не ответили на мой вопрос, как и это руководство по асинхронным методам.
Обновление. Поскольку несколько человек отметили, что проблема может быть связана с тем, как я тестировал, я попытался запустить ее в другом браузере. Интересно, что у меня возникли те же проблемы как в Chrome, так и в Firefox. Но при выполнении одного запроса от каждого он показал ожидаемое поведение (параллельное обслуживание запросов) – так что меня обманули браузеры...
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение