Spring WebFlux. Основы использования реактивного модуля Spring WebFlux

1.

Spring WebFlux
Основы использования реактивного модуля Spring WebFlux
Свиридов Юрий, Java developer

2.

Agenda:
Узнаем что такое реактивное программирование
Познакомимся с основами модуля Spring WebFlux
Узнаем о плюсах и минусах использования
Узнаем структуру использования внутри программы

3.

Реактивное программирование
Реактивное программирование - это асинхронное (неблокирующееся) взаимодействие,
совмещенное с потоковой обработкой данных
Asynchrony
Reactive

4.

Паттерн Observer
В основе реактивного программирования лежит паттерн Observer

5.

Хронология введений технологий распараллеливания

6.

Spring 5 нововведения
Поддержка Java 9
Реактивность (Spring Reactive Web Framework или WebFlux)
Поддержка Kotlin
Прочие изменения

7.

Особенности WebFlux
Spring WebFlux:
● Альтернатива MVC
● В основе лежит Project Reactor
● Non-Blocking I/O
● Вместо Tomcat по умолчанию используется Netty

8.

Reactive Stack vs Servlet Stack

9.

Event Loop
Механизм обработки событий и управления потоком выполнения в асинхронном программировании

10.

Tomcat vs Netty
Сравнение производительности Tomcat и Netty

11.

Плюсы и минусы WebFlux
Производительность: WebFlux является
реактивным фреймворком, который работает на
основе неблокирующих операций ввода-вывода. Это
обеспечивает эффективное использование ресурсов
сервера и позволяет обрабатывать большое
количество одновременных запросов с
минимальной нагрузкой на систему.
Масштабируемость: Веб-приложения на основе
WebFlux могут обрабатывать большое количество
запросов без замедления производительности. Это
особенно важно при работе с большими нагрузками
на сервер.
Гибкость: WebFlux поддерживает несколько
языков программирования, включая Java, Kotlin и
Groovy. Это позволяет разработчикам выбрать
наиболее подходящий для них язык и использовать
его для создания веб-приложений.
Сложность: Реактивное программирование может
быть сложным для понимания, особенно для
новичков. Это связано с необходимостью работы с
асинхронностью, обработкой ошибок и
механизмами подобными backpressure.
Отладка и тестирование: Отладка и тестирование
реактивных систем сложная задача, так как
асинхронная природа реактивного кода делает
отслеживание исполнения программы менее
прямолинейным и понятным.
Требования к проектированию: Реактивные
системы требуют продуманного проектирования,
чтобы обеспечить их эффективность.
Ограниченная поддержка сторонних библиотек:
Некоторые сторонние библиотеки и инструменты
могут быть не полностью совместимы с WebFlux изза своей ориентации на блокирующую модель
работы.

12.

Mono & Flux
Flux - это Publisher, который может испускать от 0 до N элементов
Mono - это Publisher, который может испускать от 0 до 1 элемента

13.

Зависимости
Вместо обычного spring-boot-starter-web в Spring MVC
maven:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
gradle:
implementation 'org.springframework.boot:spring-boot-starter-webflux'

14.

Вместо RestTemplate используем Web Client
было:
RestTemplateBuilder -> RestTemplate
RestTemplate - передаем статический текст в body
стало:
WebClientBuilder -> WebClient
WebClient - можем передать последовательность Flux в качестве body

15.

POJO
Начнем с POJO Greeting, который будет сериализован в JSON нашим RESTful-сервисом:
public class Greeting { //POJO
private String message;
//Constructors, getters, setters & toString();
}

16.

Handler
В подходе Spring Reactive мы используем обработчик для обработки запроса и создания ответа, как
показано в следующем примере:
@Component
public class GreetingHandler {
public Mono<ServerResponse> hello(ServerRequest request) {
return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue(new Greeting("Hello, Spring!")));
}
}
Этот простой реактивный класс всегда возвращает JSON-тело с приветствием "Hello, Spring!". Он
может возвращать и многое другое, в том числе поток элементов из базы данных, поток элементов,
сгенерированных в результате вычислений, и т.д. Обратите внимание на реактивный код: объект
Mono, содержащий тело ServerResponse.

17.

Router
В данном приложении мы используем маршрутизатор для обработки единственного маршрута,
который мы выставляем (/hello), как показано в следующем примере:
@Configuration(proxyBeanMethods = false)
public class GreetingRouter {
@Bean
public RouterFunction<ServerResponse> route(GreetingHandler greetingHandler) {
return RouterFunctions
.route(GET("/hello").and(accept(MediaType.APPLICATION_JSON)),
greetingHandler::hello);
}
}

18.

WebClient
Мы используем реализацию на базе WebClient для потребления нашего RESTful-сервиса:
@Component
public class GreetingClient {
private final WebClient client;
public GreetingClient(WebClient.Builder builder) {
this.client = builder.baseUrl("http://localhost:8080").build();
}
public Mono<String> getMessage() {
return this.client.get().uri("/hello").accept(MediaType.APPLICATION_JSON)
.retrieve()
.bodyToMono(Greeting.class)
.map(Greeting::getMessage);
}
}

19.

SpringBootApplication
Мы будем использовать метод main() для управления нашим приложением и получения сообщения
Greeting от нашего эндпоинта:
@SpringBootApplication
public class ReactiveWebServiceApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context =
SpringApplication.run(ReactiveWebServiceApplication.class, args);
GreetingClient greetingClient = context.getBean(GreetingClient.class);
// Здесь нам необходимо блокировать содержимое, иначе JVM может завершиться
до того, как сообщение будет зарегистрировано.
System.out.println(">> message = " + greetingClient.getMessage().block());
}
}

20.

Отправляем запрос
GET request: URL: http://localhost:8080/hello
response:
{
"message": "Hello, Spring!"
}

21.

PostgreSQL
Зависимости для подключения PostgreSQL в WebFlux:
maven:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-r2dbc</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>r2dbc-postgresql</artifactId>
<scope>runtime</scope>
</dependency>
gradle:
implementation 'org.springframework.boot:spring-boot-starter-data-r2dbc'
runtimeOnly 'org.postgresql:postgresql'
runtimeOnly 'org.postgresql:r2dbc-postgresql'

22.

Материал для изучения
https://habr.com/ru/companies/oleg-bunin/articles/543386/
https://habr.com/ru/companies/oleg-bunin/articles/545702/
https://struchkov.dev/blog/ru/overview-of-reactive-programming/
https://habr.com/ru/articles/339016/
https://habr.com/ru/articles/565752/
https://youtu.be/pmzeobajr4o
https://youtu.be/8S_GSQngB-c
https://youtu.be/mX19FWX2_Hs

23.

Благодарю за уделенное
время и внимание!
Свиридов Юрий | skype: crip_shooter
astondevs.ru
English     Русский Правила