Site icon Blog ARC Optimizer

Le pouvoir des applications asynchrones

Le pouvoir des applications asynchrones


Si, dans votre application basée sur le cloud, vous pouvez vivre avec une cohérence éventuelle, Azure vous donne trois outils hors de la boîte qui vous offrira des applications asynchrones fiables, extensibles et évolutives.

Jusqu’à présent, dans ce Codage des séries AzureJe me suis concentré sur la création d’un cloud natif sécurisé, à trois niveaux synchrone Application composée d’un frontend côté client ou côté serveur et d’un backend de service Web RESTful.

Mais il y a des problèmes avec cette architecture traditionnelle, et ils sont généralement liés au service Web backend: l’échelle du service Web peut-elle augmenter? À quel point le service Web est fiable / robuste (et ce qui se passe lorsque le service Web non disponible)? Et comment étendre l’application pour ajouter proprement de nouvelles fonctionnalités.

Les problèmes avec les applications asynchrones

Par exemple, imaginez que (à ses périodes de pointe) cette application à trois niveaux obtient une demande par seconde via son frontend, mais le service Web backend prend deux secondes pour traiter chaque demande.

Vous abordez probablement cela en élargissant le service d’application du backend à plusieurs instances et en distribuant ces demandes entrantes sur toutes ces instances. Vous devriez faire face à la latence pour démarrer ces nouvelles instances (même les conteneurs prennent un certain temps pour se réchauffer) et, bien sûr, payer le coût supplémentaire de ces instances supplémentaires, mais ce n’est pas une mauvaise solution.

Mais la mise à l’échelle crée des problèmes architecturaux. Bien que nous préférons toutes les demandes à notre backend pour être sans état, la réalité est que de nombreuses transactions commerciales dépendent de savoir ce qui s’est passé dans les activités précédentes de l’utilisateur. Cela signifie que votre backend doit faire face au maintien de l’état à travers les demandes.

Gérer ces demandes «semi-sans état», ce qui permettra d’activer une sorte de cache côté serveur orienté session ou de renvoyer des informations d’état au client et d’obliger le client à le retourner à chaque demande. Alternativement, vous pouvez activer l’affinité des serveurs (également connue sous le nom de «sessions collantes») qui, malheureusement, a pour effet secondaire d’empêcher les demandes d’être réparties uniformément dans toutes vos instances backend, ce qui retire une partie du plaisir de l’échelle. Parfois, vous devez faire les deux.

Et puis il y a la fiabilité: la mise à l’échelle est également un moyen courant de traiter la fiabilité. Si une instance échoue, les demandes suivantes sont acheminées vers une autre instance en cours d’exécution afin que l’application puisse continuer à fonctionner (bien sûr, cette nouvelle instance sera désormais, au moins temporairement, surchargée). Cependant, le pire des cas, s’il n’y a qu’une seule instance du backend en cours d’exécution et qu’il échoue, certaines demandes peuvent être perdues à mesure qu’une nouvelle instance est transformée.

Un autre problème est que la communication entre le frontend et le service Web backend n’est pas transactionnelle. Il est possible que le frontend envoie une demande au service Web, puis échouer avant de recevoir la réponse du backend, par exemple. Dans ce scénario, le service Web backend terminera ses mises à jour, mais toutes les activités de suivi que le frontend était censées effectuer ne se produira pas.

L’extension d’une application synchrone existante peut également être difficile. Vous devez soit ajouter des fonctionnalités au frontend (pour appeler un service Web supplémentaire, par exemple) ou ajouter des fonctionnalités au backend (pour effectuer un traitement supplémentaire). L’une de ces options, en s’accumulant sur des travaux supplémentaires sur le frontend ou le backend, a également un impact sur leur capacité à évoluer pour gérer une demande accrue. Et même en ignorant tout cela, ces deux solutions vous obligent à modifier les applications existantes qui étaient, jusqu’à vos nouvelles «améliorations», fonctionnant très bien. Considérez les cotes que continuera après vos modifications.

Les avantages des applications asynchrones

Tous ces problèmes peuvent souvent être résolus en passant à asynchrone SYSTÈMES: Au lieu d’avoir votre frontend accès à un service Web, votre frontend ajoute un message à une file d’attente ou soulève un événement qu’un processeur backend répond (éventuellement).

Le déménagement dans une application asynchrone nécessite de diviser une transaction dans la partie de la transaction qui doit être traitée immédiatement par le frontend et la pièce qui peut être différée jusqu’à ce que le processeur backend y arrive.

Un bon modèle pour ce type de division est votre expérience de passer une commande avec Amazon.com. Sur Amazon, lorsque vous cliquez sur le bouton Soumettre sur votre commande, vous obtenez une réponse immédiate qui dit essentiellement: «Merci pour votre commande», cependant, le traitement réel de la commande est effectué par un processeur backend… éventuellement. Lorsque ce traitement backend se termine, vous êtes informé par e-mail.

L’avantage ici est que la partie «traitement immédiat» de la transaction (y compris l’écriture dans une file d’attente ou la hausse d’un événement) est généralement beaucoup plus rapide et moins à forte intensité de ressources que le «traitement différé». Cela réduit la demande sur le frontend afin qu’il n’ait pas besoin de s’étendre du tout. Le «traitement différé» est généralement plus à forte intensité de ressources et qui prend du temps… mais cela n’a pas d’importance.

Cela n’a pas d’importance car, dans un système asynchrone, si le frontend ajoute / envoie des messages plus rapidement que le processeur backend ne peut les gérer, les demandes de «traitement différé» attendront simplement que le backend les arrive. Lorsque la demande tombe, le processus backend rattrapera son retard. Si la demande ne tombe jamais (et que le traitement différé est différé «trop long»), vous pouvez démarrer un deuxième processeur backend pour réduire la durée de la file d’attente.

Cela s’améliore: parce que, dans une file d’attente, les processeurs backend peuvent consulter tous les messages dans la file d’attente, un processeur backend peut traiter des «lots de messages» qui partagent l’état. Ils peuvent même, potentiellement, mettre en œuvre un traitement par lots plus efficace pour ces demandes qu’un service Web qui répond toujours aux demandes individuelles.

Les systèmes asynchrones améliorent également la fiabilité: si le processeur backend dans un système basé sur la file d’attente ou basé sur des événements est en baisse pour quelque raison que ce soit (défaillance réelle, mises à niveau, maintenance planifiée), les messages sont simplement assis sur la file d’attente jusqu’à ce que le processeur backend redémarre. Les événements fonctionnent d’une manière similaire lorsqu’un événement ne peut pas être livré à un consommateur.

Et, en plus de tout cela, l’un des services – le bus de service Azure – est transactionnel. Cela signifie que, si une transaction échoue, les messages créés dans la transaction ne sont pas ajoutés à la file d’attente et que les messages traités dans le cadre de la transaction sont automatiquement renvoyés à la file d’attente. Essentiellement, le bus de service nettoie après lui-même en cas de défaillance.

Même l’extensibilité est plus facile dans les systèmes asynchrones. Avec des systèmes basés sur des événements ou basés sur des files d’attente, de nouveaux processeurs backend peuvent être ajoutés pour effectuer de nouvelles opérations sur les messages existants sans avoir un impact sur les processeurs existants.

Choisir votre service

Alors, quel service convient le mieux à votre application?

À un niveau très élevé, la sélection entre les files d’attente et les événements est assez facile. Si votre application asynchrone aura plusieurs processeurs backend (ou, potentiellement, un nombre inconnu de processeurs backend), vous souhaitez probablement utiliser la grille d’événements Azure. Si vous avez un processeur backend unique, vous souhaitez probablement utiliser un système basé sur la file d’attente. Si vous avez besoin de nombreuses fonctionnalités «basées sur la file d’attente», vous pouvez utiliser un bus de service; Sinon, une file d’attente de stockage répondra probablement à vos besoins.

Bien que ce soit une bonne règle générale, ce n’est pas vrai pour chaque cas. Si vous souhaitez tirer parti des transactions, par exemple, vous voudrez utiliser le bus de service. Et, comme les événements, le bus de service prend également en charge d’avoir plusieurs processeurs backend (mais pas aussi flexiblement que les événements).

Si vous essayez de décider entre l’utilisation d’une file d’attente de stockage ou d’un bus de service, il y a beaucoup de bonnes comparaisons disponibles. Fondamentalement, si vous considérez la file d’attente de stockage comme une camionnette (grande capacité, fonctionnalités de base, prix inférieur) et le bus de service en tant que voiture de sport trompée (moins de capacité, beaucoup de fonctionnalités, prix plus élevé), vous avez un bon modèle mental des différences.

Mais, pour rendre les choses plus difficiles, vous pouvez probablement écrire suffisamment de code pour donner à votre application basée sur la file d’attente de stockage à peu près toutes les fonctionnalités d’une application basée sur un bus de service.

Par exemple, un bus de service fonctionne comme un «courtier de messages» et ne se soucie pas du format de votre message. Une file d’attente de stockage, en revanche, s’attend à ce que tous vos messages soient des chaînes. En conséquence, lorsque vous travaillez avec une file d’attente de stockage, vous devrez convertir tous les objets que vous souhaitez ajouter à la file d’attente en documents JSON (en particulier, votre message doit être compatible avec l’insertion dans un document XML codé de base64). Heureusement, c’est assez facile à faire, comme vous le verrez dans mon article sur l’ajout de messages à une file d’attente de stockage.

Modèles de conception asynchrones

Sans surprise, il existe des modèles de conception qui surgissent lorsque vous travaillez avec des applications asynchrones.

Cependant, tous ces modèles ne sont pas pris en charge par les services Azure. Idéalement, par exemple, vous voulez une livraison «exactement une fois» – la garantie qu’aucun message n’est perdu, dupliqué ou orphelin, et le processeur backend reçoit chaque message une fois. Malheureusement, aucun des trois services Azure ne garantit cela, donc votre processeur backend devra traiter des messages en double potentiels.

Les autres modèles sont cependant bien pris en charge, et ce sont que je couvrirai mes prochains articles: les files d’attente de lettres mortes (pour permettre l’examen et le traitement des messages supprimés d’une file d’attente) et le modèle de clé de voiturier, ce qui est suffisamment important pour être utile de discuter.

Modèle de clé de voiturier

Le modèle de clé de voiturier se sépare Autoriser l’accès à une ressource de lecture et écriture la ressource. Ce modèle peut être précieux lorsque le traitement d’un message peut être long et intensif des ressources (lire un grand message à partir d’une file d’attente, par exemple).

Avec le modèle de clé de voiturier, l’application peut initier le processus de traitement des messages en acquérant les autorisations pour accéder à la file d’attente, puis en passant une clé qui accorde ces autorisations à un client (la clé est généralement limitée dans le temps et limitée par autorisation).

Alternativement, une application côté client peut demander une clé à partir d’une ressource côté serveur en appelant un service Web. Le client (qui n’a aucune autorisation d’accéder à la ressource sans la clé) utilise la clé pour effectuer le traitement requis, en évitant d’incorporer des secrets dans le code côté client.

Voici mon plan

Dans mes prochains articles, je vais examiner les services qu’Azure fournit pour créer des applications asynchrones: files d’attente de stockage, bus de service et grille d’événements (je vais ignorer le centre d’événements car il est plus ciblé dans des flux de télémétrie continus plutôt que des transactions commerciales discrètes).

Je vais briser chacun de ces sujets sur plusieurs articles qui couvriront la configuration et la sécurisation du service, la création de fronts (à la fois côté client et côté serveur) pour envoyer des messages au service et créer un processeur backend pour lire les messages (côté serveur uniquement).

Je vais commencer cette série avec des files d’attente de stockage dans mon prochain post. Après cela, je passerai dans le bus de service et terminerai avec la grille de l’événement.




Source link
Quitter la version mobile