{"id":80035,"date":"2020-05-02T13:42:54","date_gmt":"2020-05-02T11:42:54","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/udobnye-arhitekturnye-patterny"},"modified":"2020-05-02T13:42:54","modified_gmt":"2020-05-02T11:42:54","slug":"udobnye-arhitekturnye-patterny","status":"publish","type":"post","link":"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/udobnye-arhitekturnye-patterny","title":{"rendered":"Mod\u00e8les architecturaux pratiques","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Salut, Habr !<\/p>\n<p><\/p>\n<p>\u00c0 la lumi\u00e8re des \u00e9v\u00e9nements actuels li\u00e9s au coronavirus, plusieurs services en ligne font face \u00e0 une charge accrue. Par exemple, <noindex><a rel=\"nofollow\" href=\"https:\/\/www.independent.co.uk\/life-style\/gadgets-and-tech\/news\/coronavirus-ocado-down-app-website-stockpiling-food-online-delivery-a9402216.html\">une des cha\u00eenes de magasins au Royaume-Uni a simplement arr\u00eat\u00e9 son site de commandes en ligne,<\/a><\/noindex>car les ressources n'\u00e9taient pas suffisantes. De plus, il n'est pas toujours possible d'acc\u00e9l\u00e9rer un serveur simplement en ajoutant du mat\u00e9riel plus puissant, mais il est n\u00e9cessaire de traiter les demandes des clients (sinon, ils iront chez les concurrents).<\/p>\n<p><\/p>\n<p>Dans cet article, je vais bri\u00e8vement parler des pratiques populaires qui permettront de cr\u00e9er un service rapide et r\u00e9silient. Cependant, parmi les sch\u00e9mas de d\u00e9veloppement possibles, j'ai s\u00e9lectionn\u00e9 uniquement ceux que vous pouvez actuellement <strong>facilement utiliser.<\/strong>Pour chaque point, vous avez soit d\u00e9j\u00e0 des biblioth\u00e8ques pr\u00eates \u00e0 l'emploi, soit la possibilit\u00e9 de r\u00e9soudre le probl\u00e8me en utilisant une plateforme cloud.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h1 id=\"gorizontalnoe-masshtabirovanie\">Scalabilit\u00e9 horizontale<\/h1>\n<p><\/p>\n<p>Le point le plus simple et le plus connu. On distingue g\u00e9n\u00e9ralement deux m\u00e9thodes de r\u00e9partition de la charge : la scalabilit\u00e9 horizontale et verticale. <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%9C%D0%B0%D1%81%D1%88%D1%82%D0%B0%D0%B1%D0%B8%D1%80%D1%83%D0%B5%D0%BC%D0%BE%D1%81%D1%82%D1%8C#%D0%93%D0%BE%D1%80%D0%B8%D0%B7%D0%BE%D0%BD%D1%82%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B5_%D0%BC%D0%B0%D1%81%D1%88%D1%82%D0%B0%D0%B1%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5\">Dans le premier cas,<\/a><\/noindex> vous permettez aux services de fonctionner en parall\u00e8le, r\u00e9partissant ainsi la charge entre eux. <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%9C%D0%B0%D1%81%D1%88%D1%82%D0%B0%D0%B1%D0%B8%D1%80%D1%83%D0%B5%D0%BC%D0%BE%D1%81%D1%82%D1%8C#%D0%92%D0%B5%D1%80%D1%82%D0%B8%D0%BA%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B5_%D0%BC%D0%B0%D1%81%D1%88%D1%82%D0%B0%D0%B1%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5\">Dans le second,<\/a><\/noindex> vous commandez des serveurs plus puissants ou optimisez le code.<\/p>\n<p><\/p>\n<p>\u00c0 titre d'exemple, je vais prendre un stockage cloud abstrait de fichiers, c'est-\u00e0-dire un certain \u00e9quivalent d'OwnCloud, OneDrive, etc.<\/p>\n<p><\/p>\n<p>L'image standard de ce type de sch\u00e9ma est ci-dessous, mais elle ne fait qu'illustrer la complexit\u00e9 du syst\u00e8me. En effet, nous devons synchroniser les services. Que se passe-t-il si un utilisateur sauvegarde un fichier depuis sa tablette et souhaite ensuite le consulter sur son t\u00e9l\u00e9phone ?<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Mod\u00e8les architecturaux pratiques\" src=\"\/wp-content\/uploads\/2020\/05\/7512c6d8783f5e0a38cc0861b01e54c8.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nLa diff\u00e9rence entre les approches : dans la scalabilit\u00e9 verticale, nous sommes pr\u00eats \u00e0 accro\u00eetre la puissance des n\u0153uds, tandis que dans la scalabilit\u00e9 horizontale, nous ajoutons de nouveaux n\u0153uds pour r\u00e9partir la charge.<\/p>\n<p><\/p>\n<h1 id=\"cqrs\">CQRS<\/h1>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/martinfowler.com\/bliki\/CQRS.html\">Command Query Responsibility Segregation<\/a><\/noindex> est un mod\u00e8le assez important, car il permet \u00e0 diff\u00e9rents clients non seulement de se connecter \u00e0 diff\u00e9rents services, mais \u00e9galement de recevoir des flux d'\u00e9v\u00e9nements identiques. Ses avantages ne sont pas si \u00e9vidents pour une application simple, mais ils sont extr\u00eamement importants (et simples) pour un service charg\u00e9. Son principe : les flux de donn\u00e9es entrants et sortants ne doivent pas se croiser. En d'autres termes, vous ne pouvez pas envoyer une requ\u00eate et attendre une r\u00e9ponse, au lieu de cela, vous envoyez une requ\u00eate au service A, mais vous obtenez une r\u00e9ponse dans le service B.<\/p>\n<p><\/p>\n<p>Le premier avantage de cette approche est la possibilit\u00e9 d'interrompre la connexion (au sens large du terme) pendant l'ex\u00e9cution d'une longue requ\u00eate. Prenons par exemple une s\u00e9quence standard :<\/p>\n<p><\/p>\n<ol>\n<li>Le client a envoy\u00e9 une requ\u00eate au serveur.<\/li>\n<li>Le serveur a lanc\u00e9 un traitement long.<\/li>\n<li>Le serveur a r\u00e9pondu au client avec un r\u00e9sultat.<\/li>\n<\/ol>\n<p><\/p>\n<p>Imaginons que, dans le point 2, une interruption de connexion se soit produite (soit en raison d'une d\u00e9connexion r\u00e9seau, soit parce que l'utilisateur est pass\u00e9 \u00e0 une autre page, rompant ainsi la connexion). Dans ce cas, il sera difficile pour le serveur d'envoyer une r\u00e9ponse \u00e0 l'utilisateur concernant ce qui a \u00e9t\u00e9 trait\u00e9. En appliquant CQRS, la s\u00e9quence sera l\u00e9g\u00e8rement diff\u00e9rente :<\/p>\n<p><\/p>\n<ol>\n<li>Le client s'est abonn\u00e9 aux mises \u00e0 jour.<\/li>\n<li>Le client a envoy\u00e9 une requ\u00eate au serveur.<\/li>\n<li>Le serveur a r\u00e9pondu \u00ab requ\u00eate re\u00e7ue \u00bb.<\/li>\n<li>Le serveur a r\u00e9pondu avec le r\u00e9sultat via le canal du point \u00ab 1 \u00bb.<\/li>\n<\/ol>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Mod\u00e8les architecturaux pratiques\" src=\"\/wp-content\/uploads\/2020\/05\/8a00ea93eecc7cc0754122857c5f90d0.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Comme on le voit, le sch\u00e9ma est l\u00e9g\u00e8rement plus complexe. De plus, l'approche intuitive request-response est absente ici. Cependant, comme on peut le voir, une interruption de connexion pendant le traitement de la requ\u00eate ne conduira pas \u00e0 une erreur. De plus, si l'utilisateur est effectivement connect\u00e9 au service depuis plusieurs appareils (par exemple, un t\u00e9l\u00e9phone mobile et une tablette), il est possible de faire en sorte que la r\u00e9ponse parvienne aux deux appareils.<\/p>\n<p><\/p>\n<p>Il est int\u00e9ressant de noter que le code de traitement des messages entrants devient identique (\u00e0 100 %) tant pour les \u00e9v\u00e9nements affect\u00e9s par le client lui-m\u00eame que pour les autres \u00e9v\u00e9nements, y compris ceux d'autres clients.<\/p>\n<p><\/p>\n<p>Cependant, dans la r\u00e9alit\u00e9, nous obtenons des avantages suppl\u00e9mentaires gr\u00e2ce au fait qu'un flux unidirectionnel peut \u00eatre trait\u00e9 de mani\u00e8re fonctionnelle (en utilisant RX et des analogues). Et c'est d\u00e9j\u00e0 un vrai plus, car en substance, l'application peut devenir compl\u00e8tement r\u00e9active, tout en utilisant \u00e9galement une approche fonctionnelle. Pour les applications lourdes, cela peut consid\u00e9rablement \u00e9conomiser des ressources en d\u00e9veloppement et en maintenance.<\/p>\n<p><\/p>\n<p>Si nous combinons cette approche avec une mise \u00e0 l'\u00e9chelle horizontale, alors nous obtenons en prime la possibilit\u00e9 d'envoyer des requ\u00eates \u00e0 un serveur tout en recevant des r\u00e9ponses d'un autre. Ainsi, le client peut choisir le service qui lui convient le mieux, et le syst\u00e8me \u00e0 l'int\u00e9rieur pourra tout de m\u00eame traiter les \u00e9v\u00e9nements de mani\u00e8re appropri\u00e9e.<\/p>\n<p><\/p>\n<h1 id=\"event-sourcing\">Event Sourcing<\/h1>\n<p><\/p>\n<p>Comme vous le savez, l'une des caract\u00e9ristiques principales d'un syst\u00e8me distribu\u00e9 est l'absence de temps commun et de section critique partag\u00e9e. Pour un seul processus, vous pouvez effectuer une synchronisation (sur les m\u00eames mutex), o\u00f9 vous \u00eates s\u00fbr que personne d'autre n'ex\u00e9cute ce code. Cependant, pour un syst\u00e8me distribu\u00e9, cela peut \u00eatre dangereux, car cela entra\u00eenera des frais g\u00e9n\u00e9raux et ruinera tout l'int\u00e9r\u00eat de l'\u00e9volutivit\u00e9 : tous les composants devront attendre les uns les autres.<\/p>\n<p><\/p>\n<p>D'ici, nous obtenons un fait important : un syst\u00e8me distribu\u00e9 rapide ne peut pas \u00eatre synchronis\u00e9, car cela diminuerait les performances. D'un autre c\u00f4t\u00e9, nous avons souvent besoin d'une certaine coh\u00e9rence des composants. Et pour cela, nous pouvons utiliser l'approche de <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Eventual_consistency\">la coh\u00e9rence \u00e9ventuelle<\/a><\/noindex>, qui garantit qu'en l'absence de modifications des donn\u00e9es, apr\u00e8s un certain laps de temps apr\u00e8s la derni\u00e8re mise \u00e0 jour (\u00ab en fin de compte \u00bb), toutes les requ\u00eates renverront la derni\u00e8re valeur mise \u00e0 jour.<\/p>\n<p><\/p>\n<p>Il est important de comprendre qu'une <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Consistency_model#Strict_consistency\">coh\u00e9rence stricte<\/a><\/noindex>est souvent appliqu\u00e9e aux bases de donn\u00e9es classiques, o\u00f9 chaque n\u0153ud poss\u00e8de les m\u00eames informations (ce qui est souvent r\u00e9alis\u00e9 lorsqu'une transaction est consid\u00e9r\u00e9e comme \u00e9tablie uniquement apr\u00e8s la r\u00e9ponse d'un deuxi\u00e8me serveur). Il existe certaines concessions dues aux niveaux d'isolation, mais l'id\u00e9e principale reste la m\u00eame : vous pouvez vivre dans un monde compl\u00e8tement coh\u00e9rent.<\/p>\n<p><\/p>\n<p>Cependant, revenons \u00e0 la t\u00e2che initiale. Si une partie du syst\u00e8me peut \u00eatre construite avec <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Eventual_consistency\">la coh\u00e9rence \u00e9ventuelle<\/a><\/noindex>, alors on peut construire le sch\u00e9ma suivant.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Mod\u00e8les architecturaux pratiques\" src=\"\/wp-content\/uploads\/2020\/05\/33c80be6bc33bd897ca9b9e5525f9ae8.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Caract\u00e9ristiques importantes de cette approche :<\/p>\n<p><\/p>\n<ul>\n<li>Chaque requ\u00eate entrante est plac\u00e9e dans une seule file d'attente.<\/li>\n<li>Au cours du traitement de la requ\u00eate, le service peut \u00e9galement placer des t\u00e2ches dans d'autres files d'attente.<\/li>\n<li>Chaque \u00e9v\u00e9nement entrant a un identifiant (n\u00e9cessaire pour la d\u00e9duplication).<\/li>\n<li>La file fonctionne id\u00e9ologiquement selon le sch\u00e9ma &quot;append only&quot;. On ne peut pas en supprimer des \u00e9l\u00e9ments ni les r\u00e9organiser.<\/li>\n<li>La file d'attente fonctionne selon le sch\u00e9ma FIFO (d\u00e9sol\u00e9 pour la tautologie). Si une ex\u00e9cution parall\u00e8le est n\u00e9cessaire, il conviendrait \u00e0 un des niveaux de redistribuer les objets dans diff\u00e9rentes files d'attente.<\/li>\n<\/ul>\n<p><\/p>\n<p>Je rappelle que nous examinons le cas d'un stockage de fichiers en ligne. Dans ce cas, le syst\u00e8me ressemblera, environ, \u00e0 ceci :<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Mod\u00e8les architecturaux pratiques\" src=\"\/wp-content\/uploads\/2020\/05\/b95efb29545dcde1db9432d12d00a1b1.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Il est important de noter que les services sur le diagramme ne signifient pas n\u00e9cessairement un serveur s\u00e9par\u00e9. Le processus peut \u00eatre identique. Ce qui est crucial, c'est que ces \u00e9l\u00e9ments sont id\u00e9ologiquement s\u00e9par\u00e9s de mani\u00e8re \u00e0 faciliter l'application de l'\u00e9volutivit\u00e9 horizontale.<\/p>\n<p><\/p>\n<p>Pour deux utilisateurs, le sch\u00e9ma appara\u00eetra comme suit (les services destin\u00e9s \u00e0 diff\u00e9rents utilisateurs sont indiqu\u00e9s en diff\u00e9rentes couleurs) :<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Mod\u00e8les architecturaux pratiques\" src=\"\/wp-content\/uploads\/2020\/05\/4c4aadc8b9dd505c3ad743e69fee4fae.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Les avantages d'une telle combinaison :<\/p>\n<p><\/p>\n<ul>\n<li>Les services de traitement de donn\u00e9es sont s\u00e9par\u00e9s. Les files d'attente sont \u00e9galement distinctes. Si nous devons augmenter la capacit\u00e9 de la syst\u00e8me, il suffit de lancer davantage de services sur un plus grand nombre de serveurs.<\/li>\n<li>Lorsque nous recevons des informations de l'utilisateur, nous ne devons pas n\u00e9cessairement attendre la sauvegarde compl\u00e8te des donn\u00e9es. Au contraire, il est suffisant de r\u00e9pondre \u00ab ok \u00bb, puis de commencer progressivement \u00e0 travailler. De plus, la file d'attente att\u00e9nue les pics, car l'ajout d'un nouvel objet se fait rapidement, et l'utilisateur n'a pas \u00e0 attendre un passage complet par tout le cycle.<\/li>\n<li>\u00c0 titre d'exemple, j'ai ajout\u00e9 un service de d\u00e9duplication qui tente de regrouper les fichiers identiques. S'il fonctionne longuement dans 1% des cas, le client ne le remarquera pratiquement pas (voir ci-dessus), ce qui est un grand avantage, car nous ne demandons plus une vitesse et une fiabilit\u00e9 \u00e0 100%.<\/li>\n<\/ul>\n<p><\/p>\n<p>Cependant, les inconv\u00e9nients sont \u00e9galement \u00e9vidents :<\/p>\n<p><\/p>\n<ul>\n<li>Notre syst\u00e8me a perdu une coh\u00e9rence stricte. Cela signifie que si, par exemple, on s'abonne \u00e0 diff\u00e9rents services, il est th\u00e9oriquement possible d'obtenir des \u00e9tats diff\u00e9rents (puisqu'un des services peut ne pas r\u00e9ussir \u00e0 recevoir la notification de la file d'attente interne). Comme autre cons\u00e9quence, le syst\u00e8me n'a plus de temps commun. Autrement dit, il n'est pas possible, par exemple, de trier tous les \u00e9v\u00e9nements simplement par ordre d'arriv\u00e9e, car les horloges entre les serveurs peuvent ne pas \u00eatre synchronis\u00e9es (de plus, deux serveurs ayant la m\u00eame heure est une utopie).<\/li>\n<li>Aucun \u00e9v\u00e9nement ne peut maintenant \u00eatre simplement annul\u00e9 (comme cela aurait pu \u00eatre fait avec une base de donn\u00e9es). Au lieu de cela, il est n\u00e9cessaire d'ajouter un nouvel \u00e9v\u00e9nement \u2014 <noindex><a rel=\"nofollow\" href=\"https:\/\/stackoverflow.com\/questions\/49451237\/compensating-events-on-cqrs-es-architecture\">compensation event<\/a><\/noindex>, qui va changer le dernier \u00e9tat en celui requis. Un exemple d'un domaine similaire : sans r\u00e9\u00e9criture de l'historique (ce qui est mauvais dans certains cas), il n'est pas possible de revenir \u00e0 un commit dans git, mais on peut faire un sp\u00e9cial <noindex><a rel=\"nofollow\" href=\"https:\/\/git-scm.com\/docs\/git-revert\">rollback commit<\/a><\/noindex>, qui en fait ne renverra qu'\u00e0 l'\u00e9tat pr\u00e9c\u00e9dent. Cependant, l'historique conservera \u00e0 la fois le commit erron\u00e9 et le rollback.<\/li>\n<li>Le sch\u00e9ma des donn\u00e9es peut changer d'une version \u00e0 l'autre, cependant, il ne sera plus possible de mettre \u00e0 jour les anciens \u00e9v\u00e9nements vers le nouveau standard (car les \u00e9v\u00e9nements ne peuvent en principe pas \u00eatre modifi\u00e9s).<\/li>\n<\/ul>\n<p><\/p>\n<p>Comme on peut le voir, l'Event Sourcing s'int\u00e8gre parfaitement avec le CQRS. De plus, mettre en place un syst\u00e8me avec des files d'attente efficaces et pratiques, mais sans s\u00e9paration des flux de donn\u00e9es, est d\u00e9j\u00e0 en soi compliqu\u00e9, car il faudra ajouter des points de synchronisation qui annuleront tout l'effet positif des files d'attente. En appliquant les deux approches simultan\u00e9ment, il est n\u00e9cessaire d'ajuster l\u00e9g\u00e8rement le code de l'application. Dans notre cas, lors de l'envoi d'un fichier au serveur, la r\u00e9ponse ne contient que \u00ab ok \u00bb, ce qui signifie simplement que \u00ab l'op\u00e9ration d'ajout de fichier a \u00e9t\u00e9 enregistr\u00e9e \u00bb. Formellement, cela n'indique pas que les donn\u00e9es sont d\u00e9j\u00e0 accessibles sur d'autres appareils (par exemple, un service de d\u00e9-duplication peut \u00eatre en train de reconstruire l'index). Cependant, apr\u00e8s un certain temps, le client recevra une notification du type \u00ab fichier X enregistr\u00e9 \u00bb.<\/p>\n<p><\/p>\n<p>En cons\u00e9quence :<\/p>\n<p><\/p>\n<ul>\n<li>Le nombre de statuts d'envoi de fichiers augmente : au lieu du classique \u00ab fichier envoy\u00e9 \u00bb, nous obtenons deux : \u00ab fichier ajout\u00e9 \u00e0 la file d'attente sur le serveur \u00bb et \u00ab fichier enregistr\u00e9 dans le stockage \u00bb. Ce dernier signifie que d'autres appareils peuvent d\u00e9j\u00e0 commencer \u00e0 recevoir le fichier (avec la nuance que les files d'attente fonctionnent \u00e0 des vitesses diff\u00e9rentes).<\/li>\n<li>En raison du fait que l'information sur l'envoi arrive maintenant par diff\u00e9rents canaux, nous devons trouver des solutions pour obtenir le statut de traitement du fichier. En cons\u00e9quence, contrairement \u00e0 la m\u00e9thode classique de requ\u00eate-r\u00e9ponse, le client peut \u00eatre red\u00e9marr\u00e9 pendant le traitement du fichier, mais le statut de ce traitement sera correct. De plus, ce point fonctionne en fait de mani\u00e8re native. En cons\u00e9quence : nous sommes maintenant plus tol\u00e9rants aux pannes.<\/li>\n<\/ul>\n<p><\/p>\n<h1 id=\"sharding\">Sharding<\/h1>\n<p><\/p>\n<p>Comme d\u00e9j\u00e0 mentionn\u00e9, dans les syst\u00e8mes avec event sourcing, il n'y a pas de coh\u00e9rence stricte. Cela signifie que nous pouvons utiliser plusieurs stockages sans aucune synchronisation entre eux. En nous rapprochant de notre t\u00e2che, nous pouvons :<\/p>\n<p><\/p>\n<ul>\n<li>S\u00e9parer les fichiers par types. Par exemple, les images\/vid\u00e9os peuvent \u00eatre d\u00e9cod\u00e9es et choisies dans un format plus efficace.<\/li>\n<li>S\u00e9parer les comptes par pays. En raison de nombreuses lois, cela peut \u00eatre n\u00e9cessaire, cependant, cette architecture offre une telle possibilit\u00e9 automatiquement.<\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Mod\u00e8les architecturaux pratiques\" src=\"\/wp-content\/uploads\/2020\/05\/dd310df700bc39c014d0105a3425fece.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Si vous souhaitez transf\u00e9rer des donn\u00e9es d'un stockage \u00e0 un autre, les moyens standards ne suffisent pas ici. Malheureusement, dans ce cas, il est n\u00e9cessaire d'arr\u00eater la file d'attente, de faire la migration, puis de la relancer. En g\u00e9n\u00e9ral, les donn\u00e9es ne peuvent pas \u00eatre transf\u00e9r\u00e9es '\u00e0 la vol\u00e9e', cependant, si la file d'\u00e9v\u00e9nements est enti\u00e8rement conserv\u00e9e, et que vous avez des instantan\u00e9s des \u00e9tats pr\u00e9c\u00e9dents du stockage, nous pouvons rejouer les \u00e9v\u00e9nements comme suit :<\/p>\n<p><\/p>\n<ul>\n<li>Dans Event Source, chaque \u00e9v\u00e9nement a son identifiant (id\u00e9alement \u2014 non d\u00e9croissant). Cela signifie que nous pouvons ajouter un champ dans le stockage \u2014 id du dernier \u00e9l\u00e9ment trait\u00e9.<\/li>\n<li>Nous dupliquons la file d'attente, afin que tous les \u00e9v\u00e9nements puissent \u00eatre trait\u00e9s pour plusieurs stockages ind\u00e9pendants (le premier \u00e9tant celui o\u00f9 les donn\u00e9es sont d\u00e9j\u00e0 stock\u00e9es, et le second \u00e9tant nouveau, mais encore vide). La seconde file d'attente n'est bien s\u00fbr pas encore trait\u00e9e.<\/li>\n<li>Nous lan\u00e7ons la seconde file d'attente (c'est-\u00e0-dire que nous commen\u00e7ons \u00e0 rejouer les \u00e9v\u00e9nements).<\/li>\n<li>Lorsque la nouvelle file d'attente sera relativement vide (c'est-\u00e0-dire que l'\u00e9cart moyen de temps entre l'ajout d'un \u00e9l\u00e9ment et sa r\u00e9cup\u00e9ration sera acceptable), nous pourrons commencer \u00e0 rediriger les lecteurs vers le nouveau stockage.<\/li>\n<\/ul>\n<p><\/p>\n<p>Comme on peut le voir, notre syst\u00e8me n'a jamais eu de coh\u00e9rence stricte. Il y a seulement une constance \u00e9ventuelle, c'est-\u00e0-dire la garantie que les \u00e9v\u00e9nements sont trait\u00e9s dans le m\u00eame ordre (mais, peut-\u00eatre, avec un d\u00e9calage diff\u00e9rent). En profitant de cela, nous pouvons relativement facilement transf\u00e9rer des donn\u00e9es sans arr\u00eater le syst\u00e8me \u00e0 l'autre bout du monde.<\/p>\n<p><\/p>\n<p>Ainsi, en continuant notre exemple d'un stockage en ligne pour fichiers, une telle architecture nous offre d\u00e9j\u00e0 plusieurs avantages :<\/p>\n<p><\/p>\n<ul>\n<li>Nous pouvons d\u00e9placer des objets plus pr\u00e8s des utilisateurs, de mani\u00e8re dynamique. Cela peut ainsi am\u00e9liorer la qualit\u00e9 du service. <\/li>\n<li>Nous pouvons stocker une partie des donn\u00e9es \u00e0 l'int\u00e9rieur des entreprises. Par exemple, les utilisateurs d'entreprise exigent souvent que leurs donn\u00e9es soient stock\u00e9es dans des centres de donn\u00e9es sous contr\u00f4le (pour \u00e9viter les fuites de donn\u00e9es). Gr\u00e2ce au sharding, nous pouvons facilement soutenir cela. Et la t\u00e2che est encore simplifi\u00e9e si le client a un cloud compatible (par exemple, <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.microsoft.com\/en-gb\/azure-stack\/asdk\/asdk-what-is?view=azs-1910\">Azure self hosted<\/a><\/noindex>).<\/li>\n<li>Le plus important est que nous n'avons pas \u00e0 le faire. En fait, au d\u00e9part, un seul stockage pour tous les comptes nous suffirait (pour commencer \u00e0 travailler plus rapidement). La caract\u00e9ristique cl\u00e9 de ce syst\u00e8me est qu'il est simple au d\u00e9part, bien qu'il soit extensible. Il suffit de ne pas \u00e9crire imm\u00e9diatement le code qui traite un million de files d'attente ind\u00e9pendantes, etc. Si n\u00e9cessaire, cela peut \u00eatre fait \u00e0 l'avenir.<\/li>\n<\/ul>\n<p><\/p>\n<h1 id=\"static-content-hosting\">H\u00e9bergement de Contenu Statique<\/h1>\n<p><\/p>\n<p>Ce point peut sembler \u00e9vident, mais il est n\u00e9anmoins n\u00e9cessaire pour une application charg\u00e9e relativement standard. Son essence est simple : tout le contenu statique est distribu\u00e9 non pas depuis le m\u00eame serveur que l'application, mais depuis des serveurs d\u00e9di\u00e9s \u00e0 cet effet. En cons\u00e9quence, ces op\u00e9rations sont effectu\u00e9es plus rapidement (un nginx par exemple, distribue les fichiers de mani\u00e8re plus efficace et moins co\u00fbteuse qu'un serveur Java). De plus, l'architecture CDN (<noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Content_delivery_network\">R\u00e9seau de Distribution de Contenu<\/a><\/noindex>) permet de placer nos fichiers plus pr\u00e8s des utilisateurs finaux, ce qui am\u00e9liore l'ergonomie de l'utilisation du service.<\/p>\n<p><\/p>\n<p>Le meilleur exemple de contenu statique est un ensemble de scripts et d'images pour un site web. C'est assez simple - ils sont connus \u00e0 l'avance, puis l'archive est t\u00e9l\u00e9charg\u00e9e sur les serveurs CDN, d'o\u00f9 elle est distribu\u00e9e aux utilisateurs finaux.<\/p>\n<p><\/p>\n<p>Cependant, en r\u00e9alit\u00e9, pour le contenu statique, nous pouvons appliquer une approche similaire \u00e0 l'architecture lambda. Revenons \u00e0 notre t\u00e2che (un stockage de fichiers en ligne), o\u00f9 nous devons distribuer des fichiers aux utilisateurs. La solution la plus simple serait de cr\u00e9er un service qui effectue toutes les v\u00e9rifications n\u00e9cessaires (authentification, etc.) pour chaque demande utilisateur, puis t\u00e9l\u00e9charge le fichier directement depuis notre stockage. Le principal inconv\u00e9nient de cette approche est que le contenu statique (et un fichier avec un certain r\u00e9vision est essentiellement du contenu statique) est distribu\u00e9 par le m\u00eame serveur qui contient la logique m\u00e9tier. Au lieu de cela, nous pouvons proposer le sch\u00e9ma suivant :<\/p>\n<p><\/p>\n<ul>\n<li>Le serveur fournit une URL de t\u00e9l\u00e9chargement. Elle peut \u00eatre sous la forme file_id + key, o\u00f9 la key est une signature num\u00e9rique courte, donnant acc\u00e8s \u00e0 la ressource pour les prochaines 24 heures.<\/li>\n<li>La distribution du fichier est g\u00e9r\u00e9e par un simple nginx avec les options suivantes :\n<ul>\n<li>Mise en cache du contenu. \u00c9tant donn\u00e9 que ce service peut \u00eatre sur un serveur s\u00e9par\u00e9, nous nous sommes laiss\u00e9s une marge pour l'avenir avec la possibilit\u00e9 de stocker tous les fichiers t\u00e9l\u00e9charg\u00e9s r\u00e9cemment sur le disque.<\/li>\n<li>V\u00e9rification de la cl\u00e9 au moment de la cr\u00e9ation de la connexion<\/li>\n<\/ul>\n<\/li>\n<li>En option : traitement en continu du contenu. Par exemple, si nous compressons tous les fichiers dans le service, il est possible de d\u00e9compresser directement dans ce module. Par cons\u00e9quent, les op\u00e9rations IO sont effectu\u00e9es l\u00e0 o\u00f9 elles ont le plus de sens. Un archiveur en Java pourrait facilement consommer beaucoup de m\u00e9moire, mais r\u00e9\u00e9crire le service avec la logique m\u00e9tier en Rust\/C++ pourrait \u00e9galement s'av\u00e9rer inefficace. Dans notre cas, diff\u00e9rents processus (ou m\u00eame services) sont utilis\u00e9s, ce qui permet de s\u00e9parer efficacement la logique m\u00e9tier des op\u00e9rations IO.<\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Mod\u00e8les architecturaux pratiques\" src=\"\/wp-content\/uploads\/2020\/05\/4dead07d5824938e09b986192ccc8f5e.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Un tel sch\u00e9ma ressemble peu \u00e0 la distribution de contenu statique (car nous ne t\u00e9l\u00e9chargeons pas l'ensemble du paquet statique quelque part), mais dans la r\u00e9alit\u00e9, cette approche s'occupe bien de la distribution de donn\u00e9es immuables. De plus, ce sch\u00e9ma peut \u00eatre g\u00e9n\u00e9ralis\u00e9 \u00e0 d'autres cas, o\u00f9 le contenu n'est pas simplement statique, mais peut \u00eatre repr\u00e9sent\u00e9 par un ensemble de blocs immuables et non supprimables (bien qu'ils puissent \u00eatre ajout\u00e9s).<\/p>\n<p><\/p>\n<p>Un autre exemple (pour bien comprendre) : si vous avez travaill\u00e9 avec Jenkins\/TeamCity, vous savez que les deux solutions sont \u00e9crites en Java. Elles repr\u00e9sentent toutes deux un processus Java qui s'occupe \u00e0 la fois de l'orchestration des builds et de la gestion du contenu. En particulier, elles ont toutes deux des t\u00e2ches de type &quot;transf\u00e9rer un fichier\/dossier depuis le serveur&quot;. Par exemple : la d\u00e9livrance des artefacts, le transfert de code source (lorsque l'agent ne t\u00e9l\u00e9charge pas le code directement depuis le d\u00e9p\u00f4t, mais que le serveur le fait pour lui), l'acc\u00e8s aux logs. Toutes ces t\u00e2ches diff\u00e8rent par leur charge IO. Cela signifie que le serveur, charg\u00e9 de la logique m\u00e9tier complexe, doit \u00e9galement \u00eatre capable de g\u00e9rer efficacement de grands volumes de donn\u00e9es. Ce qui est int\u00e9ressant, c'est que cette op\u00e9ration peut \u00eatre d\u00e9l\u00e9gu\u00e9e au m\u00eame nginx selon exactement le m\u00eame sch\u00e9ma (si ce n'est qu'il faut ajouter une cl\u00e9 de donn\u00e9es \u00e0 la demande).<\/p>\n<p><\/p>\n<p>Cependant, si nous revenons \u00e0 notre syst\u00e8me, nous obtenons un sch\u00e9ma similaire :<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Mod\u00e8les architecturaux pratiques\" src=\"\/wp-content\/uploads\/2020\/05\/97cfbf5daaa6678a9eecc3169692f0fc.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Comme vous pouvez le constater, le syst\u00e8me est devenu radicalement plus complexe. Ce n\u2019est plus simplement un mini-processus qui stocke des fichiers localement. Il n\u00e9cessite maintenant un support non trivial, un contr\u00f4le de version de l\u2019API, etc. Il est donc pr\u00e9f\u00e9rable, apr\u00e8s avoir dessin\u00e9 tous les diagrammes, d\u2019\u00e9valuer en d\u00e9tail si l\u2019\u00e9volutivit\u00e9 de telles d\u00e9penses en vaut la peine. Cependant, si vous souhaitez \u00eatre en mesure d\u2019\u00e9voluer (y compris pour g\u00e9rer un nombre encore plus important d\u2019utilisateurs), vous devrez envisager des solutions de ce type. En revanche, cela rend le syst\u00e8me architectur\u00e9 pr\u00eat \u00e0 une augmentation de la charge (pratiquement chaque composant peut \u00eatre clon\u00e9 pour un scaling horizontal). Le syst\u00e8me peut \u00eatre mis \u00e0 jour sans \u00eatre arr\u00eat\u00e9 (simplement, certaines op\u00e9rations vont l\u00e9g\u00e8rement ralentir).<\/p>\n<p><\/p>\n<p>Comme je l\u2019ai d\u00e9j\u00e0 mentionn\u00e9 au d\u00e9but, un certain nombre de services Internet supportent d\u00e9sormais une charge accrue. Et certains d\u2019entre eux ont simplement cess\u00e9 de fonctionner correctement. En effet, les syst\u00e8mes ont \u00e9chou\u00e9 au moment m\u00eame o\u00f9 les entreprises devraient g\u00e9n\u00e9rer des revenus. Au lieu de livraisons diff\u00e9r\u00e9es, au lieu de proposer aux clients de 'planifier la livraison pour les mois \u00e0 venir', le syst\u00e8me a simplement dit 'allez voir nos concurrents'. C'est cela le co\u00fbt d'une faible performance : les pertes se produisent exactement quand les b\u00e9n\u00e9fices seraient les plus \u00e9lev\u00e9s.<\/p>\n<p><\/p>\n<h1 id=\"zaklyuchenie\">Conclusion<\/h1>\n<p><\/p>\n<p>Tous ces approches \u00e9taient d\u00e9j\u00e0 connues auparavant. VK utilise depuis longtemps l'id\u00e9e de Static Content Hosting pour d\u00e9livrer des images. De nombreux jeux en ligne utilisent le sch\u00e9ma de Sharding pour diviser les joueurs par r\u00e9gions ou pour s\u00e9parer les zones de jeu (si le monde est unique). L\u2019approche d\u2019Event Sourcing est activement utilis\u00e9e dans l\u2019e-mail. La plupart des applications des traders, o\u00f9 les donn\u00e9es arrivent en continu, sont en r\u00e9alit\u00e9 construites sur l\u2019approche CQRS pour pouvoir filtrer les donn\u00e9es re\u00e7ues. De plus, le scaling horizontal est appliqu\u00e9 depuis longtemps dans de nombreux services.<\/p>\n<p><\/p>\n<p>Cependant, ce qui est le plus important, c'est que tous ces patrons sont devenus tr\u00e8s faciles \u00e0 appliquer dans les applications modernes (s'ils sont pertinents, bien s\u00fbr). Les clouds proposent le sharding et la mise \u00e0 l'\u00e9chelle horizontale imm\u00e9diatement, ce qui est beaucoup plus facile que de commander diff\u00e9rentes serveurs d\u00e9di\u00e9s dans diff\u00e9rents centres de donn\u00e9es par soi-m\u00eame. Le CQRS est devenu beaucoup plus simple, rien que gr\u00e2ce au d\u00e9veloppement de biblioth\u00e8ques telles que RX. Il y a 10 ans, un site Web rare aurait pu le supporter. L'event sourcing est \u00e9galement configur\u00e9 incroyablement facilement gr\u00e2ce \u00e0 des conteneurs pr\u00eats \u00e0 l'emploi avec Apache Kafka. Il y a 10 ans, cela aurait \u00e9t\u00e9 une innovation, maintenant c'est une banalit\u00e9. Il en va de m\u00eame pour l'h\u00e9bergement de contenu statique : gr\u00e2ce \u00e0 des technologies plus pratiques (notamment parce qu'il existe une documentation d\u00e9taill\u00e9e et une vaste base de r\u00e9ponses), cette approche est devenue encore plus simple.<\/p>\n<p><\/p>\n<p>En fin de compte, la mise en \u0153uvre d'un certain nombre de mod\u00e8les architecturaux assez complexes est maintenant beaucoup plus facile, ce qui signifie qu'il vaut mieux y pr\u00eater attention \u00e0 l'avance. Si, dans une application vieille de dix ans, on a abandonn\u00e9 l'une des solutions ci-dessus en raison de son co\u00fbt \u00e9lev\u00e9 d'impl\u00e9mentation et d'exploitation, alors maintenant, dans la nouvelle application, ou apr\u00e8s une refactorisation, on peut cr\u00e9er un service qui sera d\u00e9j\u00e0 extensible sur le plan architectural (en termes de performance) et pr\u00eat pour les nouvelles demandes des clients (par exemple, pour la localisation des donn\u00e9es personnelles).<\/p>\n<p><\/p>\n<p>Et le plus important : ne utilisez pas ces approches, s'il vous pla\u00eet, si vous avez une application simple. Oui, elles sont belles et int\u00e9ressantes, mais pour un site avec un pic de 100 visiteurs, on peut souvent se contenter d'un monolithe classique (du moins \u00e0 l'ext\u00e9rieur, \u00e0 l'int\u00e9rieur tout peut \u00eatre divis\u00e9 en modules, etc.).<\/p>\n<p>Source : <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/dbtc\/blog\/499758\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041f\u0440\u0438\u0432\u0435\u0442, \u0425\u0430\u0431\u0440! \u0412 \u0441\u0432\u0435\u0442\u0435 \u0442\u0435\u043a\u0443\u0449\u0438\u0445 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0438\u0437-\u0437\u0430 \u043a\u043e\u0440\u043e\u043d\u0430\u0432\u0438\u0440\u0443\u0441\u0430 \u0440\u044f\u0434 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442-\u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u0441\u0442\u0430\u043b \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u043d\u0443\u044e \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0443. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043e\u0434\u043d\u0430 \u0438\u0437 \u0442\u043e\u0440\u0433\u043e\u0432\u044b\u0445 \u0441\u0435\u0442\u0435\u0439 \u0432 \u0412\u0435\u043b\u0438\u043a\u043e\u0431\u0440\u0438\u0442\u0430\u043d\u0438\u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u0430 \u0441\u0430\u0439\u0442 \u0441 \u043e\u043d\u043b\u0430\u0439\u043d-\u0437\u0430\u043a\u0430\u0437\u0430\u043c\u0438, \u0442\u0430\u043a \u043a\u0430\u043a \u043d\u0435 \u0445\u0432\u0430\u0442\u0438\u043b\u043e \u043c\u043e\u0449\u043d\u043e\u0441\u0442\u0435\u0439. \u0418 \u0434\u0430\u043b\u0435\u043a\u043e \u043d\u0435 \u0432\u0441\u0435\u0433\u0434\u0430 \u043c\u043e\u0436\u043d\u043e \u0443\u0441\u043a\u043e\u0440\u0438\u0442\u044c \u0441\u0435\u0440\u0432\u0435\u0440, \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0432 \u0431\u043e\u043b\u0435\u0435 \u043c\u043e\u0449\u043d\u043e\u0435 \u043e\u0431\u043e\u0440\u0443\u0434\u043e\u0432\u0430\u043d\u0438\u0435, \u043e\u0434\u043d\u0430\u043a\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u043d\u0430\u0434\u043e (\u0438\u043b\u0438 \u043e\u043d\u0438 \u0443\u0439\u0434\u0443\u0442 \u043a \u043a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0442\u0430\u043c). \u0412 \u044d\u0442\u043e\u0439 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":80036,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-80035","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.2 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041f\u0440\u0438\u0432\u0435\u0442, \u0425\u0430\u0431\u0440! \u0412 \u0441\u0432\u0435\u0442\u0435 \u0442\u0435\u043a\u0443\u0449\u0438\u0445 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0438\u0437-\u0437\u0430 \u043a\u043e\u0440\u043e\u043d\u0430\u0432\u0438\u0440\u0443\u0441\u0430 \u0440\u044f\u0434 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442-\u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u0441\u0442\u0430\u043b \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u043d\u0443\u044e \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0443.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/udobnye-arhitekturnye-patterny\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2\" \/>\n\t\t<meta property=\"og:locale\" content=\"fr_FR\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u0423\u0434\u043e\u0431\u043d\u044b\u0435 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u043d\u044b\u0435 \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u044b | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041f\u0440\u0438\u0432\u0435\u0442, \u0425\u0430\u0431\u0440! \u0412 \u0441\u0432\u0435\u0442\u0435 \u0442\u0435\u043a\u0443\u0449\u0438\u0445 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0438\u0437-\u0437\u0430 \u043a\u043e\u0440\u043e\u043d\u0430\u0432\u0438\u0440\u0443\u0441\u0430 \u0440\u044f\u0434 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442-\u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u0441\u0442\u0430\u043b \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u043d\u0443\u044e \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0443.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/udobnye-arhitekturnye-patterny\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-05-02T11:42:54+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-05-02T11:42:54+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Mod\u00e8les architecturaux pratiques | ProHoster","description":"Salut, Habr ! \u00c0 la lumi\u00e8re des \u00e9v\u00e9nements actuels dus au coronavirus, plusieurs services Internet ont commenc\u00e9 \u00e0 subir une charge accrue.","canonical_url":"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/udobnye-arhitekturnye-patterny","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"fr_FR","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u0423\u0434\u043e\u0431\u043d\u044b\u0435 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u043d\u044b\u0435 \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u044b | ProHoster","og:description":"\u041f\u0440\u0438\u0432\u0435\u0442, \u0425\u0430\u0431\u0440! \u0412 \u0441\u0432\u0435\u0442\u0435 \u0442\u0435\u043a\u0443\u0449\u0438\u0445 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0438\u0437-\u0437\u0430 \u043a\u043e\u0440\u043e\u043d\u0430\u0432\u0438\u0440\u0443\u0441\u0430 \u0440\u044f\u0434 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442-\u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u0441\u0442\u0430\u043b \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u043d\u0443\u044e \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0443.","og:url":"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/udobnye-arhitekturnye-patterny","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-05-02T11:42:54+00:00","article:modified_time":"2020-05-02T11:42:54+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"80035","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 16:26:40","updated":"2022-09-28 01:38:29","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/posts\/80035","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/comments?post=80035"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/posts\/80035\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/media\/80036"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/media?parent=80035"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/categories?post=80035"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/tags?post=80035"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}