Blog ENI : Toute la veille numérique !
-25€ dès 75€ sur les livres en ligne, vidéos... avec le code FUSEE25. J'en profite !
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici
  1. Livres et vidéos
  2. Java Spring
  3. Les différents reactors étendus
Extrait - Java Spring Construisez vos applications réactives avec une architecture micro-services en environnement Jakarta EE (2e édition)
Extraits du livre
Java Spring Construisez vos applications réactives avec une architecture micro-services en environnement Jakarta EE (2e édition) Revenir à la page d'achat du livre

Les différents reactors étendus

Introduction

Reactor est une bibliothèque de programmation réactive qui offre une approche fondée sur les flux pour la programmation asynchrone. Elle est utilisée pour créer des applications réactives en Java. Voici des précisions sur les différents projets Reactor.

  • Reactor seul (reactor-core) : comme son nom l’indique, c’est le cœur de la bibliothèque Reactor. Il fournit les principaux types de données réactives tels que Flux et Mono, ainsi que les opérations pour les transformer, les filtrer et les combiner. Il s’agit de la base sur laquelle les autres projets Reactor sont construits.

  • Reactor Netty (reactor-netty) : intégration de Reactor avec Netty, qui est un framework réseau évolutif pour Java. Reactor Netty offre une implémentation réactive pour les opérations de communication réseau, telles que les appels HTTP, les serveurs TCP et les clients WebSocket. Il permet une communication réseau hautement performante et asynchrone.

  • Reactor RabbitMQ (reactor-rabbitmq) : bibliothèque qui fournit une intégration réactive avec RabbitMQ, ce dernier étant un système de messagerie orienté messages. Reactor RabbitMQ permet de publier et de consommer des messages RabbitMQ en utilisant des objets Flux et Mono, rendant ainsi les interactions avec RabbitMQ réactives....

Reactor Netty

Nous avons vu qu’il est possible de faire de la programmation avec Netty, mais que cela est fastidieux et qu’il y a beaucoup de code boilerplate.

Le terme code boilerplate (« code répétitif » ou « code gâteau » en français) désigne les parties de code qui doivent être écrites à plusieurs endroits dans un programme, souvent de manière identique ou très similaire. Ces parties de code ne contribuent pas directement à la logique métier de l’application, mais sont nécessaires pour le bon fonctionnement de celle-ci, comme l’initialisation de variables, la gestion des exceptions, la configuration, etc. Le code boilerplate peut rendre le code plus long, moins lisible et plus sujet aux erreurs, car les développeurs doivent copier-coller ou réécrire le même code plusieurs fois. Il peut également être fastidieux à maintenir, car tout changement doit être appliqué à plusieurs endroits. Pour remédier à ce problème, certains frameworks et bibliothèques fournissent des outils pour générer automatiquement le code boilerplate, ce qui permet de gagner du temps et de réduire les risques d’erreur. Par exemple, en utilisant des annotations ou des générateurs de code, nous pouvons éviter d’écrire...

Programmation Netty avec Spring

Reactor Netty est un framework qui permet de développer des applications réseau asynchrones fondées sur des événements. Il offre des fonctionnalités de client et de serveur pour les protocoles TCP, HTTP et UDP, qui sont non bloquants et prennent en charge la contre-pression. Ce framework est construit sur la base solide du framework Netty.

Reactor Netty est le serveur par défaut utilisé par Spring WebFlux. Lorsque vous créez une application WebFlux avec Spring, le serveur Reactor Netty est automatiquement configuré pour gérer les requêtes et les réponses asynchrones grâce à la programmation réactive. Vous pouvez également configurer d’autres serveurs si vous le souhaitez. Néanmoins, Reactor Netty étant l’option par défaut, elle est recommandée pour profiter pleinement des avantages de la réactivité dans Spring WebFlux.

Nous pouvons utiliser la librairie Spring Reactor Netty pour faire de la programmation réseau dans un style fonctionnel, comme ce que nous faisions précédemment avec un moteur tel que Vert.x, avant la mise à disposition de Spring Reactor Netty.

La contre-pression nous permet soit de prévenir l’appelant qu’il nous appelle trop souvent, soit de piloter un cluster élastique pour ajouter dynamiquement...

Protocole TCP

Reactor peut être utilisé pour concevoir une application TCP pour :

  • Créer des applications de communication en temps réel, telles que des serveurs de chat, des systèmes de messagerie instantanée ou des applications de streaming de données en continu.

  • Mettre en place des microservices avec une communication fondée sur le protocole TCP. Cela permet aux différents microservices de communiquer entre eux de manière efficace et réactive.

  • Exposer des données via un protocole TCP. Cela peut être utile lorsque vous avez besoin de fournir un accès direct aux données à des clients ou à d’autres systèmes.

  • Intégrer des systèmes hétérogènes en utilisant des protocoles de communication standard tels que TCP/IP. Cela permet de connecter des systèmes disparates et de faciliter l’échange de données entre eux.

  • Créer des jeux en ligne multijoueurs où une communication en temps réel est essentielle. Cela permet aux joueurs de se connecter et d’interagir avec le serveur de jeu de manière réactive.

Reactor Netty fournit un outil facile à utiliser et à configurer. Il s’agit de la classe TcpServer qui masque la plupart des fonctionnalités Netty nécessaires à la création d’un serveur TCP tout en ajoutant une contre-pression Reactive Streams.

Nous allons commencer par un couple client/serveur qui nous servira à expliquer le comportement et les variantes possibles plus en détail par la suite. Nous allons utiliser reactor-netty dans le cadre d’une application Spring-boot.

Le lanceur :

@SpringBootApplication 
public class ReactorNettyServerApplication implements CommandLineRunner { 
 
  public static void main(String[] args) { 
    SpringApplication.run(ReactorNettyServerApplication.class, args); 
  } 
 
  @Override 
  public void run(String... args) throws Exception { 
  } 
} 

Le serveur :

@Slf4j 
@Component 
public class ServerSimple { 
 
  // Injection de la valeur pour le port du serveur depuis application.properties 
  @Value("${server.port}") ...

Serveur HTTP

En général, l’utilisation du serveur HTTP de Spring Reactor Netty est limitée car nous avons déjà WebFlux pour cela. Le serveur HTTP de Spring Reactor Netty est généralement réservé à des cas spécifiques, tels que ceux proches de Vert.x ou dans des scénarios avec des ports multiples pour des besoins de simulation (comme des mocks).

L’un des avantages de l’utilisation de Spring Reactor Netty pour un serveur HTTP est la possibilité de gérer la contre-pression. Cela permet de mieux contrôler le flux de données entre le serveur et les clients, évitant ainsi des problèmes de surcharge ou de congestion.

Cependant, il est important de noter que Spring a créé un projet spécialement dédié pour répondre à ce besoin : Spring WebFlux. Spring WebFlux est la version réactive du Spring MVC traditionnel et offre une solution complète pour gérer les applications réactives et les serveurs HTTP.

Dans la plupart des cas, il est recommandé d’utiliser Spring WebFlux plutôt que le serveur HTTP de Spring Reactor Netty, car cela permet de bénéficier de toutes les fonctionnalités et des avantages d’une approche réactive complète.

L’utilisation du serveur HTTP de Spring Reactor Netty sera...

Serveur UDP

Reactor Netty offre également la possibilité de créer des serveurs UDP. Le serveur UDP est très similaire au serveur TCP en termes d’implémentation et de configuration. Cependant, il existe des différences fondamentales entre les protocoles UDP (User Datagram Protocol) et TCP (Transmission Control Protocol).

UDP est un protocole de communication réseau qui permet d’envoyer des datagrammes de manière non fiable et sans connexion. Contrairement à TCP, qui garantit la livraison des paquets dans l’ordre et gère les retransmissions en cas de perte, UDP ne fournit pas de mécanismes de garantie de livraison ou de retransmission.

La légèreté et la rapidité d’UDP en font un choix attractif pour certaines applications où la perte de quelques paquets n’est pas critique, comme les applications multimédias en streaming ou les jeux en ligne. Cependant, cette rapidité et cette légèreté peuvent entraîner une perte de données en cas de congestion ou de perturbations sur le réseau.

Bien que le serveur UDP de Reactor Netty offre une alternative légère et rapide pour certaines applications spécifiques, il est important de prendre en compte les limitations d’UDP en termes de fiabilité de la livraison des paquets et d’ordre des messages.

Voici cinq cas d’utilisation courants d’un serveur UDP avec Spring Reactor Netty :

  • Serveur de jeu en temps réel :...

Conclusion sur Reactor Netty

En conclusion, Reactor Netty est une puissante bibliothèque qui offre une approche réactive pour construire des serveurs et des clients réseau hautement performants. Grâce à son architecture fondée sur le modèle de programmation réactive, Reactor Netty permet de gérer efficacement de nombreux clients simultanés tout en maintenant une utilisation optimale des ressources.

Les fonctionnalités offertes par Reactor Netty, telles que la gestion des connexions asynchrones, la prise en charge de protocoles réseau variés (TCP, UDP), la personnalisation fine des paramètres réseau et la compatibilité avec les outils de monitoring tels que Micrometer, en font un choix idéal pour les applications exigeantes en termes de performance et de scalabilité.

L’utilisation de Reactor Netty est particulièrement pertinente dans le contexte de la programmation réactive, où la gestion des flux de données est primordiale. Son intégration transparente avec le framework Spring permet également de tirer pleinement parti des capacités réactives de l’écosystème Spring.

Cependant, il est important de noter que Reactor Netty peut être plus complexe à utiliser que certaines alternatives pour des cas d’utilisation plus simples. Par conséquent...

Reactor Rabbit MQ

RabbitMQ est un système de messagerie open source, fondé sur le protocole AMQP (Advanced Message Queuing Protocol), qui facilite l’échange de messages asynchrones et fiables entre différentes applications ou composants d’un système distribué. Il utilise des files d’attente pour permettre aux producteurs d’envoyer des messages et aux consommateurs de les récupérer et de les traiter. RabbitMQ garantit la livraison sécurisée des messages et offre des fonctionnalités telles que la persistance des messages, un routage flexible, des modèles de messagerie avancés, une extensibilité via des plugins, une haute performance, et des mécanismes de gestion des files d’attente. Il est largement utilisé dans les architectures distribuées pour la communication entre les services, la gestion des files d’attente de tâches, la mise en œuvre de workflows, etc., offrant ainsi une solution fiable et scalable pour les systèmes nécessitant une communication asynchrone et la garantie de livraison des messages.

1. Utilisation de la partie serveur de RabbitMQ

a. Mise en place du serveur

En ligne de commande : https://www.rabbitmq.com/management-cli.html

Nous avons une partie serveur et une partie client. Le serveur peut être installé en autonome ou fonctionner dans un conteneur comme Docker.

Nous pouvons utiliser Docker :

Pour lancer RabbitMQ dans un conteneur Docker, vous pouvez utiliser l’image officielle RabbitMQ disponible sur Docker Hub.

docker run -it --rm --name mon_rabbitmq -p 5672:5672 -p  
15672:15672 rabbitmq:3.12-management 
  • L’option -d lance le conteneur en mode détaché (en arrière-plan).

  • --name mon_rabbitmq définit le nom du conteneur comme "mon_rabbitmq" (vous pouvez choisir un nom différent si vous le souhaitez). 

  • -p 5672:5672 expose le port 5672 du conteneur (port par défaut de RabbitMQ) sur le port 5672 de votre machine hôte, permettant ainsi aux applications externes de se connecter à RabbitMQ.

  • -p 15672:15672 expose le port 15672 du conteneur, qui est utilisé pour l’interface de gestion web de RabbitMQ.

  • rabbitmq:3-management spécifie l’image Docker à utiliser, dans ce cas, l’image officielle RabbitMQ avec le plugin...

Reactor Kafka

1. Introduction

Kafka est une solution de messagerie distribuée hautement évolutive et performante. Grâce à sa faible latence et à sa capacité à gérer des flux de messages à haut débit, Kafka est devenu un service de messagerie très apprécié, ainsi qu’une plateforme puissante pour le traitement en continu des flux d’événements en temps réel.

Apache Kafka propose trois principales API pour faciliter son utilisation.

  • Producer API/Consumer API (API Producteur/Consommateur) : cette API permet aux applications de publier des messages sur des sujets (topics) Kafka et de consommer des messages depuis ces sujets. Les producteurs envoient des données aux sujets, tandis que les consommateurs lisent ces données à partir des sujets pour les traiter ou les stocker.

  • Connect API (API de connecteurs) : cette API permet d’extraire des données à partir de systèmes de stockage de données existants et de les charger dans Kafka, ou inversement, de pousser des données des sujets Kafka vers d’autres systèmes de données. Elle facilite l’intégration de Kafka avec différents écosystèmes de données.

  • Streams API (API Streams) : cette API permet de transformer et d’analyser en temps réel les flux d’événements publiés sur Kafka. Elle permet aux développeurs de construire des pipelines de traitement de données en continu, effectuant des opérations de transformation, de filtrage, d’agrégation et d’analyse sur les flux de données.

Apache Kafka offre donc un ensemble d’API flexibles et puissantes qui permettent aux développeurs de créer des systèmes de messagerie, d’intégration de données et de traitement en temps réel, répondant ainsi aux besoins de divers scénarios d’application.

2. API réactive pour Kafka

Reactor Kafka est une API réactive spécialement conçue pour Kafka, fondée sur les principes de Reactor et ceux des API Kafka Producer/Consumer. Grâce à l’utilisation d’API fonctionnelles et à la contre-pression non bloquante, l’API Reactor Kafka permet aux applications...