В чем разница Spring WebFlux и Spring MVC
Что проверяют
Понимаете ли вы разницу в модели потоков, а не только в типах возвращаемых значений, и можете ли объяснить, когда реактивный стек оправдан. Следом почти всегда спрашивают, что будет, если внутри WebFlux вызвать JDBC, и как на выбор повлияли виртуальные потоки.
Как отвечать
- Spring MVC: построен на Servlet API, модель «поток на запрос». В Spring Boot по умолчанию работает на Tomcat с пулом до 200 потоков, блокирующий вызов в базу держит поток до ответа;
- Spring WebFlux: построен на Reactive Streams и Project Reactor, методы возвращают
MonoиFlux. По умолчанию работает на Netty с небольшим числом потоков цикла событий, примерно по числу ядер, и держит тысячи соединений, пока запросы ждут ввода-вывода. Может работать и на Tomcat или Jetty через неблокирующий Servlet API; - программная модель: в обоих стеках есть аннотированные контроллеры
@RestControllerи функциональные эндпоинты (RouterFunctionв WebFlux, WebMvc.fn в MVC). Разница не в аннотациях; - экосистема: в WebFlux весь путь должен быть неблокирующим: R2DBC вместо JDBC,
WebClientвместо блокирующих клиентов, реактивные драйверы.ThreadLocalне работает, поэтому MDC иSecurityContextHolderзаменяются Reactor Context иReactiveSecurityContextHolder; - обратное давление: подписчик сам задаёт, сколько элементов готов принять.
Отдельно скажите про виртуальные потоки: на Java 21 и Spring Boot 3.2+ свойство spring.threads.virtual.enabled=true переводит MVC на них, и блокирующий код перестаёт упираться в размер пула. Для многих сервисов это снимает главный довод в пользу WebFlux.
Где спотыкаются
Говорят, что MVC подходит только для малых нагрузок. Он держит высокую нагрузку, просто масштабируется потоками. WebFlux не ускоряет отдельный запрос, он экономит потоки при большом числе ожидающих соединений.
Вызывают блокирующий код в цепочке WebFlux: JDBC, block(), Thread.sleep. Поток цикла событий встаёт, и сервис перестаёт отвечать всем. Неизбежный блокирующий вызов уводят на Schedulers.boundedElastic().
Недооценивают цену: трудная отладка, нечитаемые стектрейсы, другая модель тестов через StepVerifier и WebTestClient.