Когда поступает HTTP-запрос, «обычное» веб-приложение сопоставляет запрос с конкретным потоком из пула потоков. Этот назначенный поток остается с запросом до тех пор, пока ответ не будет возвращен в сокет запроса. Попутно нам может потребоваться получить данные из некоторой веб-службы или базы данных, прочитать или записать в файл или выполнить другие вызовы ввода-вывода, во время которых поток блокируется и должен ждать, пока не получит ответ. Для приложений с высокой частотой запросов пул потоков может в какой-то момент исчерпаться, и тогда новые запросы больше не будут обрабатываться.
Здесь нам может помочь реактивное программирование. Вместо того, чтобы иметь большой пул потоков и модель «поток на запрос», реактивное приложение имеет только один поток на каждое ядро ЦП, которое продолжает работать, и если оно попадает в операцию ввода-вывода, оно разгружает эту операцию и работает над чем-то еще до тех пор, пока IO завершено. Мы говорим, что такое приложение неблокирующее.
Подход появился, когда группа компаний объединилась в инициативе Reactive Streams, чтобы определить ключевые принципы и четыре интерфейса JVM. После этого они практически каждый пошли своим путем, чтобы создать реактивную библиотеку на основе этих соглашений. Одна из этих библиотек, Project Reactor, является основой, на которой Spring построил свою реактивную веб-платформу Spring WebFlux.
Этот реактивный стек позволяет нам создавать неблокирующие веб-приложения в структуре, которая выглядит знакомой с точки зрения классов, методов и аннотаций, если вы работали с Spring MVC, но фактическая реализация методов может быть с довольно сложной кривой обучения.