"Si un ouvrier veut bien faire son travail, il doit d'abord affûter ses outils." - Confucius, "Les Entretiens de Confucius. Lu Linggong"
Page de garde > La programmation > Pourquoi avons-nous écarté l'architecture des systèmes réactifs de notre code ?

Pourquoi avons-nous écarté l'architecture des systèmes réactifs de notre code ?

Publié le 2024-09-02
Parcourir:754

Cet article explore notre décision de nous éloigner de l'architecture réactive dans notre projet logiciel. Nous aborderons les principes fondamentaux des systèmes réactifs, les avantages des E/S non bloquantes et les défis auxquels nous sommes confrontés avec une approche réactive.

Comprendre le style d'architecture réactive

Reactive englobe un ensemble de principes et de lignes directrices visant à construire des systèmes et des applications distribués réactifs, caractérisés par :

  1. Réactivité : Capable de traiter rapidement les demandes, même sous de lourdes charges.
  2. Résilience : Capable de se remettre des pannes avec un temps d'arrêt minimal.
  3. Élasticité : Peut s'adapter à l'évolution des charges de travail en faisant évoluer les ressources en conséquence.
  4. Basé sur les messages : Utilise la messagerie asynchrone pour améliorer la tolérance aux pannes et découpler les composants.

L'un des principaux avantages des systèmes réactifs est leur utilisation d'E/S non bloquantes. Cette approche évite de bloquer les threads lors des opérations d'E/S, permettant à un seul thread de gérer plusieurs requêtes simultanément. Cela peut améliorer considérablement l'efficacité du système par rapport au blocage traditionnel des E/S.
Dans le multithreading traditionnel, les opérations de blocage posent des défis importants en matière d'optimisation des systèmes (Figure 1). Les applications gourmandes qui consomment trop de mémoire sont inefficaces et pénalisent les autres applications, nécessitant souvent des demandes de ressources supplémentaires comme de la mémoire, du processeur ou des machines virtuelles plus volumineuses.

Why we discarded Reactive systems architecture from our code?

Figure 1 – Multithreading traditionnel


Les opérations d'E/S font partie intégrante des systèmes modernes, et leur gestion efficace est primordiale pour éviter les comportements gourmands. Les systèmes réactifs utilisent des E/S non bloquantes, permettant à un faible nombre de threads du système d'exploitation de gérer de nombreuses opérations d'E/S simultanées.

Modèle d'exécution réactif

Bien que les E/S non bloquantes offrent des avantages substantiels, elles introduisent un nouveau modèle d'exécution distinct des frameworks traditionnels. Une programmation réactive a émergé pour résoudre ce problème, car elle atténue l'inefficacité des threads de plate-forme inactifs pendant les opérations de blocage (Figure 2).

Why we discarded Reactive systems architecture from our code?

Figure 2 – Boucle d'événement réactif


Quarkus et réactif

Quarkus exploite un moteur réactif alimenté par Eclipse Vert.x et Netty, facilitant les interactions d'E/S non bloquantes. Mutiny, l'approche privilégiée pour écrire du code réactif avec Quarkus, adopte un paradigme événementiel, dans lequel les réactions sont déclenchées par les événements reçus.

Mutiny propose deux types événementiels et paresseux :

  1. Uni : Émet un seul événement (un élément ou un échec), adapté pour représenter des actions asynchrones avec zéro ou un résultat.
  2. Multi : Émet plusieurs événements (n éléments, un échec ou un achèvement), représentant des flux d'éléments, potentiellement illimités.

Les défis de Reactive

Bien que les systèmes réactifs offrent des avantages, nous avons rencontré plusieurs défis lors du développement :

  • Changement de paradigme : La programmation réactive nécessite un changement fondamental dans la mentalité des développeurs, ce qui peut s'avérer difficile, en particulier pour les développeurs habitués à la programmation impérative. Contrairement aux outils auxiliaires comme l'API Streams, l'approche réactive nécessite une refonte complète de l'état d'esprit.
  • Lisibilité et compréhension du code : Le code réactif pose des difficultés à comprendre pour les nouveaux développeurs, ce qui entraîne une augmentation du temps passé à le déchiffrer et à le comprendre. La complexité introduite par les paradigmes réactifs aggrave ce problème.

"En effet, le rapport entre le temps passé à lire et à écrire est bien supérieur à 10 pour 1. Nous lisons constamment de l'ancien code dans le cadre de l'effort d'écrire du nouveau code. ...[Par conséquent,] le rendre facile à lire rend c'est plus facile à écrire."
- Robert C. Martin, Clean Code : un manuel d'artisanat logiciel agile

  • Défis de débogage : Le débogage du code réactif s'avère presque impossible avec les débogueurs IDE standard en raison des lambdas encapsulant la plupart du code. De plus, la perte de traces de pile significatives lors d'exceptions entrave encore davantage les efforts de débogage. Efforts accrus de développement et de test : La complexité inhérente du code réactif peut conduire à des cycles de développement plus longs en raison du temps requis pour l'écriture, la modification et les tests.

Voici un exemple de code réactif utilisant Mutiny pour illustrer la complexité :

Multi.createFrom().ticks().every(Duration.ofSeconds(15))
    .onItem().invoke(() - > Multi.createFrom().iterable(configs())
    .onItem().transform(configuration - > {
  try {
    return Tuple2.of(openAPIConfiguration,
        RestClientBuilder.newBuilder()
            .baseUrl(new URL(configuration.url()))
            .build(MyReactiveRestClient.class)
            .getAPIResponse());

  } catch (MalformedURLException e) {
    log.error("Unable to create url");

  }
  return null;
}).collect().asList().toMulti().onItem().transformToMultiAndConcatenate(tuples - > {

  AtomicInteger callbackCount = new AtomicInteger();
  return Multi.createFrom().emitter(emitter - > Multi.createFrom().iterable(tuples)
      .subscribe().with(tuple - >
          tuple.getItem2().subscribe().with(response - > {
              emitter.emit(callbackCount.incrementAndGet());

  if (callbackCount.get() == tuples.size()) {
    emitter.complete();
  }
                    })
                ));

}).subscribe().with(s - > {},
Throwable::printStackTrace, () - > doSomethingUponComplete()))
    .subscribe().with(aLong - > log.info("Tic Tac with iteration: "   aLong));

Perspectives futures – Projet Loom et au-delà

Project Loom, un développement récent de l'écosystème Java, promet d'atténuer les problèmes associés au blocage des opérations. En permettant la création de milliers de threads virtuels sans modifications matérielles, Project Loom pourrait potentiellement éliminer le besoin d'une approche réactive dans de nombreux cas.

"Le projet Loom va tuer la programmation réactive"
Brian Goetz

Conclusion

En conclusion, notre décision de s'éloigner du style d'architecture réactive pour adopter une approche pragmatique de la maintenabilité à long terme de notre projet. Bien que les systèmes réactifs offrent des avantages potentiels, les défis qu'ils ont présentés à notre équipe l'emportaient sur ces avantages dans notre contexte spécifique.

Il est important de noter que ce changement n'a pas compromis les performances. Il s'agit d'un résultat positif, car il démontre qu'une architecture non réactive (impérative) bien conçue peut fournir les performances nécessaires sans la complexité associée à une architecture réactive dans notre cas.

Alors que nous regardons vers l'avenir, l'accent reste mis sur la création d'une base de code non seulement fonctionnelle, mais également facile à comprendre et à maintenir pour les développeurs de tous niveaux d'expérience. Cela réduit non seulement le temps de développement, mais favorise également une meilleure collaboration et un meilleur partage des connaissances au sein de l'équipe.

Dans le graphique ci-dessous, l'axe X représente la complexité croissante de notre base de code à mesure qu'elle évolue, tandis que l'axe Y représente le temps requis pour ces changements de développement.

Why we discarded Reactive systems architecture from our code?

Déclaration de sortie Cet article est reproduit sur : https://dev.to/yanev/why-we-discarded-reactive-systems-architecture-from-our-code-19ni?1 En cas de violation, veuillez contacter [email protected] pour le supprimer
Dernier tutoriel Plus>

Clause de non-responsabilité: Toutes les ressources fournies proviennent en partie d'Internet. En cas de violation de vos droits d'auteur ou d'autres droits et intérêts, veuillez expliquer les raisons détaillées et fournir une preuve du droit d'auteur ou des droits et intérêts, puis l'envoyer à l'adresse e-mail : [email protected]. Nous nous en occuperons pour vous dans les plus brefs délais.

Copyright© 2022 湘ICP备2022001581号-3