Understand the network infrastructure of a modern and efficient information system
What does the network infrastructure of a real application used by large companies look like? This article aims to clarify a bit about the subject through a possible example of web architecture.
👋🏻 For a English version of this article 🇺🇸 : let’s check out at Medium

À quoi ressemble l'infrastructure réseau d'une vraie application utilisée par de grosses sociétés ? Quels sont les besoins auxquels il faut répondre ? Cet article a pour but de vous éclaircir un peu sur le sujet à travers un exemple possible d'architecture web.

Une architecture moderne pour une application stable et performante

Lors du précédent article, nous avons vu les bases du fonctionnement de l'architecture client-serveur, nous y avons détaillé ce qu'était un client (front end), un serveur (back end) ainsi qu'un protocole. Étant donné que vous devez avoir assimilé ces concepts de base nous pouvons pousser la réflexion un peu plus loin et décortiquer une architecture digne d'une grosse application. L'exemple que nous allons étudier pourrait très bien s'appliquer à l'architecture de Google, Facebook ou encore Amazon. Certes dans la réalité c'est bien plus complexe et beaucoup plus gros mais sur le principe cela fonctionne de la même manière.

L'histoire d'un message qui se balade dans le système

Prenons ensemble le rôle de notre petit courrier qui, émis par un client, se balade au travers de notre architecture de serveurs (donc la fameuse « requête »).

Ce dernier a pour origine le terminal de l'utilisateur. Ce terminal se trouve dans ce que l'on nomme l'extranet[^1] représenté par la zone grise sur le schéma ci-dessous. Ce qui est détaillé plus bas dans cet article se nomme l'intranet, c'est la zone bleue du schéma. En gros, il faut imaginer que c'est une zone du réseau fermée au grand public, tout comme le centre de tri de La Poste, là où les messages arrivent et sont dirigés à l'intérieur du système pour traitement.

C'est une « boite noire » pour les personnes externes à l'intranet (donc pour les utilisateurs) car l'on ne sait pas ce qui s'y passe. D'une part car l'on s'en fiche, seul le résultat (la réponse) comptant, mais surtout car cela poserait des soucis de sécurité. L'implémentation dans ce réseau fermé est donc seulement connue par les développeurs de celui-ci.

Sans plus attendre, voici la représentation graphique de l'architecture sur laquelle cet article s'appuie :

L'architecture applicative web que nous allons étudier

Le routage

Tout commence ici, par le routage !

Plusieurs utilisateurs procèdent à des requêtes auprès d'un serveur DNS par le biais de l'URL de leur navigateur par exemple. Ce serveur DNS est une sorte de grand annuaire stockant un fichier de correspondance entre des noms de domaines (ex. : facebook.com, instagram.fr, google.com) et des adresses IP (ex. : 192.168.2.4, 86.250.54.66, …). En fin de compte, les terminaux des utilisateurs demandent simplement au serveur de leur indiquer l'adresse IP (l'équivalent de l'adresse postale) d'une machine du réseau intranet du destinataire (à l'écoute du réseau externe) capable d'adresser la requête qu'ils sont entrain d'effectuer.

Le serveur DNS transforme des noms de domaines en adresse IP.

Le traitement de la requête

Parfait, le terminal de notre utilisateur récupère donc l'adresse IP cible et peut désormais envoyer sa requête vers le bon destinataire ! Ce message parti, il atterri dans notre cas sur une machine nommée le pare-feu.

Le pare-feu est une machine exécutant un programme agissant comme une sorte de bouclier permettant de contrôler et réglementer les accès à l'infrastructure d'un réseau intranet (réseau privé). Vous pouvez par exemple comparer cela à la douane. Nous ne rentrerons pas dans les détails de fonctionnement d'un pare-feu, mais sachez que ce dernier peut filtrer le trafic passant sur plusieurs règles telles que des plages (ensemble d'adresses) IP, des ports réseau, … Si vous souhaitez en savoir plus veuillez vous référer à des liens comme celui-ci ou celui-là

Le pare-feu est un bouclier réglementant l'accès à un réseau ou une machine.

Une fois la requête et l'émetteur contrôlés, cette dernière transite jusqu'au maillon suivant de la chaîne : le répartiteur de charge (Load Balancer en anglais).
Pour de petites applications : une seule machine, un nœud, pourrait suffire à desservir l'ensemble des requêtes du système et l'on pourrait donc se passer de répartiteur de charge. Cependant dans le cas d'applications à fort trafic et ne pouvant pas se permettre d'interruptions de service, on trouvera un répartiteur de charge afin d'assurer un service stable et continue.

Un répartiteur de charge est une machine exécutant un programme dont le rôle est de rediriger le trafic réseau selon un algorithme donné, cela vers d'autres machines.

Les règles de répartitions peuvent être diverses et seront développées plus tard dans un autre article, mais sachez qu'on peut choisir de répartir les requêtes équitablement entre plusieurs machines (nœuds) pouvant les traiter, en vérifiant au préalable que ces dernières sont en bonne santé (comprendre opérationnelles) ou par exemple en fonction de leur provenance (zone géographique, réseau privé, …).

La récupération des données

Une fois qu'une machine a été élue pour traiter notre requête par le répartiteur, cette dernière la reçoit et procède à son traitement. Dans notre cas, l'application responsable est un serveur tournant sous NodeJS (un serveur d'application programmé en Javascript), cependant cela pourrait être n'importe quel autre type de serveur, comme un serveur écrit en PHP.

L'application serveur procède dans notre cas à la récupération ou à l'écriture de données grâce au contenu de notre message, pour cela elle intérroge un système de gestion de base de données (SGBD).

L'application serveur décortique une requête cliente pour utiliser son contenu afin de construire une réponse à celle-ci, qu'elle lui transmet en retour.

Des système de gestion de base de données

Les SGBD les plus populaires du marché de nos jours se divisent en deux grandes familles :

  • Les bases de données relationnelles — On y retrouvera les fameuses BDD SQL forte de leurs solides principes en termes de sécurisation de l'intégrité du stockage des données, cela par le biais d'une structure bien précise imposée et de nombreuses vérifications effectuées lors de l'enregistrement de ces dernières. Ce qui peut poser des problèmes sur des applications traitant de très large volumes de données (plusieurs millions) et nécessitant de grandes performances.
  • Les bases de données non-relationnelles — Telles que les bases de données NoSQL avec un modèle de donnée libre elles permettent de meilleures performances en sacrifiant une partie de la sécurité de l'intégrité des données. Cette tâche étant déléguée à l'implémentation du développeur qui devra faire en sorte que la cohérence des données demeurent, en évitant les enregistrements orphelins ayant des références à d'autres enregistrements n'existant pas ou plus.

Les bases de données stockent, répliquent et permettent une sauvegarde durable et certaines des données dans le temps. On les interrogent par le biais d'un langage de requêtes.

En informatique et plus particulièrement dans la programmation web vous pouvez constater que le mot « requête » revient tout le temps, c'est un principe fondamental.

Dans notre schéma le trait vert indique que les bases de données communiquent également entre-elles, on parle de grappes (ou Cluster en anglais). Ces dernières peuvent donc échanger des données en les copiants de l'une à l'autre, on parle de réplication ou bien elles peuvent partager certaines parties de ces données, on parle alors de segmentation (sharding en anglais). Ces termes seront abordés plus en détails dans d'autres articles.

Une couche de cache

Lorsque des traitements (des calculs) sont coûteux, longs et que l'on sait d'avance que le résultat produit sera le même (on parle d'idempotence[^2]), il devient alors intéressant de garder en mémoire ce résultat, on dit « mettre en cache » la réponse produite par un traitement d'une requête. Ce qui signifie que la première fois que la tâche sera effectuée, la seconde fois on interrogera d'abord le cache pour voir si le traitement a déjà été fait et si tel est le cas on servira directement le résultat sans effectuer le traitement.

Ce procédé bien que sur notre schéma est décrit entre le SGBD et le serveur applicatif, il peut en réalité se positionner à d'autres endroits. Par exemple entre le répartiteur de charge et le serveur applicatif.

Nous y reviendrons certainement dans de futurs articles.

Les systèmes de mise en cache ont vocations à l'amélioration des performances et la réduction de la charge des machines en limitant la répétition de tâches provoquant les même résultats dans une fenêtre de temps plus ou moins longue.

Le retour du boomerang, la réponse

Une fois les données récupérées, le serveur applicatif les renvoient au répartiteur, qui les renvoient au pare-feu, qui les renvoient à l'utilisateur. C'est un effet boomerang, et ça se passe comme ça pour chaque requête.

Lors d'une session, un utilisateur effectue généralement plusieurs centaines de requêtes.

Pour résumer

Une application moderne et performante ayant une forte fréquentation aura besoin d'une infrastructure répondant à différents critères parmis lesquels :

  • L'échelonnage (scalability en anglais) — Soit sa capacité à supporter la charge au fûr-et-à-mesure de l'accroissement du trafic. On distinguera la scalabilité horizontale et verticale, qui seront abordées dans d'autres articles.
  • La consistence (consistency en anglais) — Soit la capacité à garder les données dans un état de cohérence et avec une hiérarchie correcte.
  • La résillience — La capacité à conserver les données dans le temps et faire face à diverses pannes matérielles imprévues (durabilité), notamment grâce à des techniques comme la réplication et la segmentation (sharding en anglais), abordées également dans d'autres articles.
  • La performance — Afin que l'utilisateur ait accès le plus rapidement possible au contenu dont il a besoin.
  • La haute disponibilité (High-availability en anglais) — C'est à dire le « Zero Down-time », soit un accès au service en continue en assurant les autres facteurs cités plus haut.

Aller plus loin

D'autres architectures existent telles que les architectures dites « Server Less », soit sans serveur, c'est le cas par exemple de Azure chez Microsoft, Google cloud chez Google ou Amazon web services chez Amazon. Ce sont les architectures de cloud-computing. Cela sera également dévéloppé dans les prochains mois :) En attendant vous pouvez toujours aller vous renseigner sur le web, par contre je vous met en garde si vous êtes novices, c'est un niveau assez avancé et requiert certaines connaissances plutôt appronfondies pour en comprendre l'intérêt, à vos risques et périls.

J'espère que cet article vous aura permis de comprendre un peu mieux le fonctionnement d'une architecture moderne et performante utilisée par de grosses sociétés. N'oubliez pas que tout cela est un exemple à but éducatif et bien plus simple que de vraie architectures, mais dans l'idée, c'est cela !

Merci de m'avoir lu, n'hésitez pas à partager vos avis dans l'espace commentaire ci-dessous.

  1. L'extranet représente une zone réseau externe (réseau public) à la zone de notre infrastructure de serveurs. En opposition à l'intranet (réseau privé) qui lui est la zone de ce réseau interne, c'est là où se trouvent tous nos téléphones et ordinateurs connecté au web.

  2. L'idempotence En mathématiques et en informatique, l'idempotence signifie qu'une opération a le même effet qu'on l'applique une ou plusieurs fois, sans changer les paramètres ou la façon de l'effectuer.