1.1 Architecture applicative

Ce cours est conçu pour les débutants, car vous ne concevrez pas l'architecture d'une application sérieuse avant longtemps. Mais ne vous inquiétez pas, une bonne architecture est l'exception plutôt que la règle. Il est très difficile de choisir la bonne architecture d'application avant de construire l'application.

Exemples d'architectures populaires pour les grandes applications de serveur :

  • Architecture en couches (architecture en couches).
  • Architecture à plusieurs niveaux.
  • Architecture orientée services (SOA).
  • Architecture de microservices (Architecture de microservices).

Chacun d'eux a ses avantages et ses inconvénients. Mais les étudier ne vous apportera rien. L'architecture est la réponse à la question "comment organiser l'interaction de milliers d'objets au sein du système" . Et tant que vous n'aurez pas expérimenté toute la complexité du problème, vous ne pourrez pas comprendre toute la polyvalence de la solution.

Toutes les applications utilisent une sorte d'architecture, ou du moins font semblant. Par conséquent, la connaissance des approches courantes de la conception d'applications vous permettra de comprendre rapidement et mieux le fonctionnement de l'application. Et cela signifie apporter des modifications exactement là où vous en avez besoin.

Que signifie « faire des changements si nécessaire » ? Y a-t-il des endroits où vous n'avez pas besoin d'apporter des modifications ? Exactement.

Pour être précis, disons que vous travaillez sur un projet backend moyen . Il est écrit depuis 5 ans par une équipe de 20 personnes. Le projet a pris 100 années-hommes et contient environ 100 000 lignes de code. Au total, il se compose de deux mille classes, qui sont divisées en 10 modules de tailles différentes.

Et ajouter une dure réalité. La logique de certaines tâches est répartie sur plusieurs modules. De plus, la logique métier peut être dans le frontend (écrite en JavaScript) et/ou écrite sous forme de procédure stockée directement dans la base de données. Êtes-vous toujours sûr de pouvoir déterminer immédiatement l'endroit exact où effectuer les modifications ?

Ce n'est pas un cauchemar que j'ai inventé pour te faire peur. C'est un projet typique. Cela arrive encore pire. Pourquoi cela arrive-t-il? Il peut y avoir un certain nombre de raisons, mais il y en a presque toujours :

  • Beaucoup de gens travaillent sur le projet - chacun d'eux le voit un peu différemment.
  • Depuis 5 ans, 10 personnes ont changé dans le projet, les nouveaux venus n'y comprenaient pas grand chose.
  • Créer un logiciel, c'est faire constamment des changements qui changent constamment tout.
  • Il y a cinq ans, lorsque nous avons décidé de l'architecture, l'idée du projet était quelque peu différente.

Mais l'essentiel est que quelle que soit l'architecture du projet, tous les programmeurs qui y travaillaient ont adhéré à la même compréhension du fonctionnement de ce projet. Commençons par le concept le plus simple - l'architecture client-serveur.

1.2 Le concept d'interaction client-serveur

Nous allons maintenant comprendre le concept qui sous-tend l' architecture client-serveur et vous permettra de mieux comprendre comment s'organise l'interaction de millions de programmes sur Internet.

Comme son nom l'indique, ce concept implique deux parties : le client et le serveur . Tout est comme dans la vie ici : le client est le client de tel ou tel service, et le serveur est le prestataire de service. Le client et le serveur sont physiquement des programmes , par exemple un client typique est un navigateur .

Les exemples suivants peuvent être donnés en tant que serveur :

  • Serveurs Web tels que Tomcat.
  • Serveurs de base de données tels que MySQL.
  • Des passerelles de paiement comme Stripe.

Le client et le serveur communiquent généralement via Internet (bien qu'ils puissent travailler dans le même réseau local et en général dans tout autre type de réseau). La communication s'effectue via des protocoles standard tels que HTTP, FTP ou des protocoles de niveau inférieur tels que TCP ou UDP.

Le protocole est généralement choisi en fonction du type de service fourni par les serveurs. Par exemple, s'il s'agit d'un appel vidéo, alors UDP est généralement utilisé.

Vous souvenez-vous du fonctionnement de Tomcat et de ses servlets ? Le serveur reçoit un message HTTP, le décompresse, en extrait toutes les informations nécessaires et le transmet à la servlet pour traitement. Ensuite, le résultat du traitement est reconditionné dans une réponse HTTP et envoyé au client.

Il s'agit de l'interaction client-serveur typique. Le navigateur est le client Web et Tomcat est le serveur Web. Tomcat est même appelé un serveur Web.

Mais si vous y réfléchissez, ce n'est pas le nom qui est important, mais l'essence - la répartition des rôles entre les programmes. Votre script JS s'exécutant dans une page HTML pourrait bien être appelé un client et votre servlet un serveur . Après tout, ils travaillent en binôme dans le cadre du concept client-serveur .

1.3 Une nuance importante

Il convient également de noter que l'interaction client-serveur repose sur le principe qu'une telle interaction est initiée par le client : le serveur répond uniquement au client et signale s'il peut fournir le service au client et, si oui, à quelles conditions .

Peu importe où se trouve physiquement le client et où se trouve le serveur. Le logiciel client et le logiciel serveur sont généralement installés sur des machines différentes, mais ils peuvent également s'exécuter sur le même ordinateur.

Ce concept a été développé comme une première étape vers la simplification d'un système complexe. Elle a ces atouts :

  • Simplification logique : le serveur ne sait rien du client et comment il utilisera ses données dans le futur.
  • Il peut y avoir des clients faibles : toutes les tâches gourmandes en ressources peuvent être transférées vers le serveur.
  • Développement indépendant du code client et du code serveur.
  • Beaucoup de clients différents, par exemple Tomcat et différents navigateurs.

La version la plus basique de l'interaction entre le client et le serveur est montrée dans l'image :

serveur client

Il est important de noter ici deux détails. Tout d'abord, l'image montre que de nombreux clients peuvent accéder à un serveur. Deuxièmement, ils peuvent y accéder en même temps. C'est aussi une partie importante du serveur.

Un client interagit généralement avec un utilisateur, donc souvent même une autorisation n'est pas nécessaire là-bas. Cependant, le serveur traite les demandes de milliers de clients, et lors du développement du code pour celui-ci, vous devez être en mesure de faire la distinction entre l'autorisation et l'authentification.

Il est également important que le serveur traite des milliers de requêtes en parallèle. Et cela signifie que lors du développement du code backend, vous devrez constamment penser à la tâche d'accès simultané aux ressources. De plus, le code du serveur a une probabilité très élevée de condition de concurrence (course de threads), de blocage (blocage mutuel des threads).

Le cycle de vie des objets importants doit être surveillé :

Vous ne pouvez pas simplement démarrer un nouveau fil sur le serveur via new Thread().start(). Au lieu de cela, vous devez disposer d'un ThreadPool qui sera partagé entre tous les threads de service.

De plus, vous ne pouvez pas simplement démarrer une tâche asynchrone, car elles sont également exécutées dans des threads séparés. Lors de la création d'une telle tâche, vous devez toujours savoir quel pool de threads l'exécute et ce qui se passera si un tel pool déborde.

Tout travail avec des fichiers et des répertoires doit être effectué via try-with-resources. Si dans une application normale vous avez oublié de fermer un flux ou un fichier, est-ce un problème ? Il se fermera lorsque vous quitterez le programme. Mais si vous avez oublié de fermer un fichier sur le serveur quelque part dans le code et que votre serveur fonctionne depuis des mois ... Bientôt, des milliers de ces fichiers non fermés s'accumuleront et le système d'exploitation cessera d'ouvrir de nouveaux fichiers en lecture (travaillez avec des fichiers est contrôlé par le système d'exploitation). Teamlead ne vous tapotera pas sur la tête...

1.4 Architecture client-serveur

un autre point important. L'architecture client-serveur ne définit que les principes généraux d'interaction entre les ordinateurs , les détails de l'interaction sont déterminés par divers protocoles.

Ce concept (client-serveur) nous dit qu'il faut diviser les machines du réseau en machines clientes, qui ont toujours besoin de quelque chose, et en machines serveurs, qui donnent ce dont elles ont besoin. Dans ce cas, le client démarre toujours l'interaction et les règles selon lesquelles l'interaction se produit sont décrites par le protocole.

Il existe deux types d'architecture d'interaction client-serveur : la première est appelée architecture client-serveur à deux niveaux, la seconde est l'architecture client-serveur multi-niveaux (parfois appelée architecture à trois niveaux ou architecture à trois niveaux, mais c'est un cas particulier).

Le principe de fonctionnement de l'architecture à deux niveaux de l'interaction client-serveur est que le traitement d'une requête se produit sur un serveur sans faire référence à d'autres serveurs dans le processus de ce traitement.

Le modèle d'interaction client-serveur à deux niveaux peut être dessiné sous la forme d'un schéma simple.

architecture à deux niveaux de l'interaction client-serveur

Ici, vous pouvez voir que le premier niveau est tout ce qui concerne le client, et le second niveau est tout ce qui concerne le serveur.