В 2016 году в основной презентации платформы Spring One Юрген Хоеллер объявил Spring WebFlux , один из самых ожидаемых проектов, над которым работает Spring Team, благодаря повышению производительности, которое обещают реактивные потоки для веб-контроллеров. Впоследствии, с Spring Framework 5.0, Spring Reactive MVC пошла в гору вместе с выпуском WebFlux API, сделав основной поток основанным на реактивном потоке веб-контроллером.
В преддверии 2020 года Spring WebFlux MVC получил широкое распространение в облачных приложениях, где разработчики стремятся использовать микросервисы с высокой пропускной способностью и малой задержкой. Ясно, что произошел сдвиг в сторону модели реактивного программирования, теперь, когда многие поставщики баз данных поддерживают реактивные драйверы, в которых традиционные блокирующие вызовы базы данных заменяются асинхронным и неблокирующим доступом к данным с обратным давлением.
В этой статье мы познакомим вас с основами начала работы с полностью реактивным технологическим стеком, от веб-контроллеров до вызовов баз данных. Мы создадим микросервис Spring с использованием Spring WebFlux, Spring Data Reactive Repositories и YugabyteDB , которые поддерживают реактивные драйверы для операций CRUD.
Что такое YugabyteDB? Это высокопроизводительная распределенная база данных SQL с открытым исходным кодом, построенная на масштабируемой и отказоустойчивой конструкции, созданной по мотивам Google Spanner.
Технологический стек для создания приложения Spring Microservices
Следуя этому руководству, мы создадим приложение для микросервисов Spring, предоставляющее реактивный REST API для выполнения операций CRUD с YugabyteDB. В этом примере приложения используется следующий технический стек:
- Spring WebFlux — поддержка реактивных контроллеров MVC и контроллеров REST.
- Spring Data реагирует на Apache Cassandra — поддержка реактивных репозиториев для YugabyteDB.
- Yugabyte Cloud Query Language (YCQL) — основанный на SQL API-интерфейс с гибкой схемой, который поддерживает распределенные транзакции, строго согласованные вторичные индексы и собственный тип столбца JSON. YCQL совместим с диалектом запросов Apache Cassandra и изначально работает с реактивными драйверами Apache Cassandra.
Репозиторий Git для примера приложения находится здесь .
Начиная YugabyteDB
Запустите кластер YugabyteDB с помощью следующей команды из установочного каталога YugabyteDB:
Оболочка
xxxxxxxxxx
1
$ ./bin/yb-ctl destroy && ./bin/yb-ctl --rf 3 create --tserver_flags="cql_nodelist_refresh_interval_secs=10" --master_flags="tserver_unresponsive_timeout_ms=10000"
Это запустит локальный кластер с 3 узлами с коэффициентом репликации (RF) 3. Этот флажок cql_nodelist_refresh_interval_secs
определяет, как часто драйверы будут получать уведомления об изменениях топологии кластера, и следующий флаг позволяет tserver_unresponsive_timeout_ms
мастеру пометить узел как мертвый после того, как он перестает отвечать. (сердцебиение) в течение 10 секунд.
Примечание. Вот полные инструкции по установке YugabyteDB на локальный ноутбук Mac.
Инициализация проекта и настройка зависимостей
Создайте новый проект Spring Boot с помощью Spring Initializr и добавьте следующие зависимости, необходимые для примера приложения:
- Spring Reactive Web
- Реактивные данные Spring для Apache Cassandra
При рассмотрении pom.xml
проекта вы увидите следующие реактивные зависимости:
Джава
xxxxxxxxxx
1
<dependency>
2
<groupId>org.springframework.boot</groupId>
3
<artifactId>spring-boot-starter-data-cassandra-reactive</artifactId>
4
</dependency>
5
<dependency>
6
<groupId>org.springframework.boot</groupId>
7
<artifactId>spring-boot-starter-webflux</artifactId>
8
</dependency>
Реактивная конфигурация репозитория
Автоматическая реконфигурация Spring Boot инициализирует источник данных Cassandra при запуске, все, что нам нужно сделать, это указать информацию о соединении YugabyteDB, application.properties
как показано ниже:
Джава
xxxxxxxxxx
1
spring.data.cassandra.keyspace-name=sample
2
spring.data.cassandra.contact-points=127.0.0.1
3
spring.data.cassandra.port=9042
После того, как мы применили конфигурацию источника данных, давайте продолжим и рассмотрим реактивные репозитории, необходимые для примера приложения.
Пример приложения содержит product
объект домена, для которого мы будем создавать реактивные репозитории для выполнения операций CRUD. Доменный объект должен иметь аннотации @Table
и @Id
Spring Spring Cassandra:
Джава
xxxxxxxxxx
1
"products") (
2
public class Product {
3
5
private String productId;
6
...
8
}
Теперь давайте реализуем реактивный репозиторий для product
объекта домена:
Джава
xxxxxxxxxx
1
public interface ProductReactiveRepository extends ReactiveCassandraRepository<Product, String> {
2
}
ReactiveCassandraRepository
Интерфейс позволяет реакционноспособные API - интерфейсов для всех общих операций поддерживает Спринг данные , такие как save( )
, findById( )
, findAll()
, и deleteByID()
. Как и следовало ожидать, эти API вызовы будут возвращать реакционно типы, либо Mono<>
или flux<>
на основе результата вызова API.
Реактивный контроллер REST и доступ к данным
Как мы видели из предыдущего раздела, весь стандартный код для создания источника данных и реализации кода доступа к данным предоставляется Spring Framework. Давайте теперь используем репозиторий продукта в нашем реактивном контроллере REST.
Джава
xxxxxxxxxx
1
2
public class ProductController {
3
5
private ProductReactiveRepository productReactiveRepository;
6
("/products")
8
public Flux getProducts() {
9
return productReactiveRepository.findAll();
10
}
11
("/products/save")
13
public Mono createProductUsingSaveAPI( Product product) {
14
return productReactiveRepository.save(product);
15
}
16
}
Это оно! Методы контроллера, использующие API хранилища, также возвращают реактивные типы, что делает общее взаимодействие асинхронным, от обслуживания HTTP-запроса до вызовов базы данных, что дает приложениям преимущества в производительности благодаря наличию полностью реактивной модели программирования.
Резюме
Поскольку нативные облачные приложения смещаются в сторону неблокирующей модели программирования, разработчики приложений могут быстро начать создание прототипов, используя абстракции Spring для реактивного программирования. В сочетании с распределенными облачными базами данных, такими как YugabyteDB, которая поддерживает реактивные драйверы для доступа к данным, получаются приложения с высокой степенью масштабируемости и производительности.