Модель потоков Spring WebFlux и Reactor

В настоящее время экспериментирует с реактивным программированием с помощью Spring 5.0.0.RC2, Reactor 3.1.0.M2 и Spring Boot 2.0.0.M2.

Хотите узнать о модели параллелизма и многопоточности, используемой WebFlux и Reactor для правильного кодирования приложения и обработки изменяемого состояния.

В документе Reactor говорится, что библиотека считается независимой от параллелизма, и упоминается абстракция планировщика. Документ WebFlux не дает информации.

Тем не менее, при использовании WebFlux через Spring Boot определяется потоковая модель.

Вот что я получил в результате экспериментов:

  • Модель не является ни 1 потоком событий, ни 1 потоком событий + воркеры.
  • Используются несколько пулов потоков
  • Потоки "Reaction-http-nio-3": возможно, по одному на ядро, обрабатывают входящие HTTP-запросы.
  • Потоки «Thread-7»: используются асинхронными запросами к MongoDB или ресурсам HTTP.
  • Потоки «parallel-1»: по одному на ядро, создаются с помощью Schedulers.parallel () из Reactor, используются операторами задержки и т. п.
  • Общее изменяемое состояние должно быть синхронизировано приложением.
  • ThreadLocal (для состояния приложения, ведения журнала MDC и т. Д.) Не привязаны к запросу, поэтому не очень интересны

Это верно ? Что такое модель параллелизма и потоков в WebFlux: например, каковы пулы потоков по умолчанию?

Спасибо за информацию


person Florian Beaufumé    schedule 10.07.2017    source источник
comment
модель параллелизма и многопоточности WebFlux и Reactor зависит от кода вашего приложения. Ни Spring WebFlux, ни Reactor не навязывают вам модель параллелизма. Вы захотите изучить параллельное реактивное программирование.   -  person Abhijit Sarkar    schedule 10.07.2017
comment
На самом деле вы запрашиваете потоковую модель Spring, Reactor, Netty, вашего реактивного диска базы данных и т. Д. Никто не может ответить на этот вопрос правильно.   -  person Brian Clozel    schedule 30.08.2017
comment
@BrianClozel, можете ли вы указать некоторые места в документации о конфигурации потоковой передачи по умолчанию в spring-webflux? По умолчанию потоки цикла событий раскручиваются, как vertx, на основе ядра процессора?   -  person zennon    schedule 01.02.2018
comment
@BrianClozel, я тоже в замешательстве. В нашем приложении мы видим эластичный-2, эластичный-выталкивающий-1, параллельный-1, реактор-http-nio-1, реактор-http-nio-2, реактор-http-nio-3 ... до реактора-http- nio-40: Количество потоков: 40 потоков этого типа. Эта Spring Boot 2.0.0.RC1 работает на образе Alpine Docker. В том же приложении на моем 4-ядерном ноутбуке есть 4 потока response-http-nio. Так что сбивает с толку, что они означают, и нигде в документе нет надлежащего упоминания любого из них. Так грустно видеть такое пренебрежение со стороны команды Spring.   -  person ROCKY    schedule 24.02.2018
comment
Существует обширная документация для Spring WebFlux docs.spring.io/spring/docs/current/spring-framework-reference/. Вместо того, чтобы называть эти усилия пренебрежением, пожалуйста, помогите улучшить его, определив, чего не хватает, например, см. jira. spring.io/browse/SPR-16538.   -  person Rossen Stoyanchev    schedule 15.03.2018
comment
@RossenStoyanchev Это все еще не объясняет ошибку, которую мы наблюдаем. При использовании дистрибутива Alpine Linux и Spring Webflux потоки реактора собираются до 40 потоков. То же приложение, если оно используется с другими дистрибутивами Linux, такими как centos или ноутбук с Windows, по умолчанию использует 2 * доступных ядра.   -  person ROCKY    schedule 25.03.2018


Ответы (1)


После вопроса Настоящая документация действительно дает некоторые подсказки о модели параллелизма и потоках, которые можно было бы ожидать (но я все еще думаю, что Spring новички).

В нем обсуждается разница между Spring MVC и Spring WebFlux (модель с одним потоком на запрос и цикл событий):

В Spring MVC и приложениях сервлетов в целом предполагается, что приложения могут блокировать текущий поток, например для удаленных вызовов, и по этой причине контейнеры сервлетов используют большой пул потоков, чтобы поглотить потенциальную блокировку во время обработки запроса.

В Spring WebFlux и неблокирующих серверах в целом предполагается, что приложения не будут блокироваться, и поэтому неблокирующие серверы используют небольшой пул потоков фиксированного размера (рабочие циклы событий) для обработки запросов. Вызов API блокировки

Но обратите внимание, что приложения Spring MVC также могут вносить некоторую асинхронность (см. Servlet 3 Async). И я предлагаю эту презентацию для обсуждения Сервлет 3.1 NIO и WebFlux.

Вернемся к документации: он также предполагает, что при работе с реактивными потоками у вас есть некоторый контроль:

Что делать, если вам действительно нужна библиотека блокировки?

И Reactor, и RxJava предоставляют оператор publishOn для продолжения обработки в другом потоке.

(Для получения дополнительной информации см. планирование в Reactor)

Здесь также обсуждаются темы, которые вы можете ожидать в приложениях WebFlux (мой жирный):

Модель потоков

Какие потоки вы должны ожидать увидеть на сервере, работающем с Spring WebFlux?

  • На «ванильном» сервере Spring WebFlux (например, без доступа к данным или других дополнительных зависимостей) вы можете ожидать один поток для сервера и несколько других для обработки запросов (обычно столько, сколько ядер ЦП) < / сильный>. Контейнеры сервлетов, однако, могут начинаться с большего количества потоков (например, 10 на Tomcat) для поддержки как сервлета, блокирующего ввод-вывод, так и сервлета 3.1, неблокирующего использования ввода-вывода.
  • Реактивный WebClient работает в стиле цикла событий. Таким образом, вы увидите небольшое фиксированное количество потоков обработки, связанных с этим, например "response-http-nio-" с соединителем Reactor Netty. Однако, если Reactor Netty используется как для клиента, так и для сервера, по умолчанию они будут совместно использовать ресурсы цикла событий.
  • Reactor и RxJava предоставляют абстракции пула потоков, называемые планировщиками, для использования с оператором publishOn, который используется для переключения обработки в другой пул потоков. У планировщиков есть имена, которые предлагают конкретную стратегию параллелизма, например «параллельный» для работы с привязкой к ЦП с ограниченным количеством потоков или «эластичный» для работы с привязкой к вводу-выводу с большим количеством потоков. Если вы видите такие потоки, это означает, что какой-то код использует определенную стратегию планировщика пула потоков.
  • Библиотеки доступа к данным и другие сторонние зависимости также могут создавать и использовать собственные потоки.

Частично вы можете настроить детали потоковой модели через конфигурацию

Чтобы настроить модель потоковой передачи для сервера, вам необходимо использовать специфичные для сервера API-интерфейсы конфигурации или, если вы используете Spring Boot, проверить параметры конфигурации Spring Boot для каждого сервера. WebClient можно настроить напрямую. Для всех остальных библиотек обратитесь к соответствующей документации.

Более того, как, например, обсуждение Количество потоков по умолчанию в Spring реактивная конфигурация webflux при загрузке 2.0 основные моменты,

Количество потоков по умолчанию для обработки запросов определяется базовым веб-сервером; по умолчанию Spring Boot 2.0 использует Reactor Netty, который использует настройки Netty по умолчанию.

это вопрос компонентов по умолчанию и их значений по умолчанию (и общей конфигурации, в том числе прозрачно вводимых через аннотации), которые также могут меняться в зависимости от версий Spring / Boot и соответствующих зависимостей. Сказал, что ваши предположения верны.

person metaphori    schedule 02.06.2018
comment
Если моя реактивная конечная точка должна вызвать внешнюю, нереактивную конечную точку, которая выполняет блокировку, будет ли моя реактивная конечная точка по-прежнему реактивной? Я использую реактивный WebClient для вызова этой внешней нереактивной конечной точки - person user1955934; 15.09.2019