Internet Information Services

Montée en charge des applications ASP.NET : Principaux enseignements

Richard Campbell

 

En un coup d'œil :

  • Importance de la collaboration entre le service de développement et le service informatique
  • Les principales stratégies de montée en charge
  • Partage des connaissances entre les équipes
  • Définition d'un ensemble de connaissances de base

Sommaire

Principes de base de la montée en charge
La rencontre des grands esprits
Informations que l'équipe réseau doit obtenir de l'équipe de développement
Informations que l'équipe de développement doit obtenir de l'équipe réseau
Retour à la montée en charge
Branle-bas de combat

Dans ma vie de consultant, toutes les montées en charge d'application ASP.NET fructueuses sur lesquelles j'ai travaillé ont été l'aboutissement d'un effort de collaboration entre les développeurs (qui ont créé l'application) et les administrateurs réseau (qui l'utilisent). Malheureusement, il n'est pas toujours évident, au début du

cycle de vie d'une application, que cette collaboration est essentielle. Par conséquent, je n'ai presque jamais l'occasion d'être impliqué au début du cycle de vie d'une application mais seulement lorsque les problèmes commencent à se manifester.

La vérité est qu'aucune application n'évolue efficacement à la première tentative car il est impossible de faire correctement du premier coup. Pour bien faire monter en charge une application, vous devez comprendre comment elle a été construite et comment fonctionne l'environnement d'exploitation dans lequel elle s'exécute. En d'autres termes, vous avez besoin d'obtenir des informations tant auprès de l'équipe de développement que de l'équipe réseau. Sans partage de connaissances, vous ne réussirez pas.

Principes de base de la montée en charge

Avant de plonger dans le vif du sujet, voyons tout d'abord ce qui est nécessaire pour faire monter en charge une application ASP.NET. Deux stratégies fondamentales sont généralement utilisées : la spécialisation et la distribution. La plupart des montées en charge d'applications ASP.NET de grande ampleur appliquent les deux stratégies. De plus, toutes les astuces qui vous aideront à faire monter en charge votre application ASP.NET se classent dans l'une ou l'autre stratégie.

La spécialisation implique la séparation d'éléments de l'application de sorte qu'ils puissent monter en charge de façon indépendante. Par exemple, vous pouvez créer des serveurs d'images dédiés au lieu d'utiliser les serveurs qui affichent les pages ASP.NET. La configuration optimale d'un serveur d'images est entièrement différente de celle d'un serveur ASP.NET. En outre, en séparant vos requêtes d'images du reste des applications, vous pouvez utiliser des ressources de tiers pour servir les images. La même approche peut s'appliquer à d'autres fichiers de ressources.

La distribution, en revanche, implique l'extension symétrique de l'application sur plusieurs serveurs qui forment généralement une batterie de serveurs Web. Les applications ASP.NET conviennent particulièrement à la distribution parce que chaque requête de page individuelle est relativement petite, et les interactions d'un utilisateur donné dépendent largement des autres utilisateurs. La distribution est véritablement la manifestation de la stratégie de « montée en charge horizontale », où plusieurs serveurs de performances moyennes fonctionnent ensemble pour servir les utilisateurs, plutôt que de la stratégie de « montée en charge verticale » au sein de laquelle un seul gros serveur effectue tout le travail.

La combinaison de la spécialisation et de la distribution accroît l'efficacité car elle permet de distribuer uniquement les éléments de l'application qui ont besoin de performances supplémentaires. Par exemple, si vous avez créé des serveurs d'images spécialisés mais que le service d'images n'est toujours pas adéquat, vous pouvez ajouter des serveurs d'images au lieu d'ajouter des serveurs pour l'ensemble de l'application. Il est important de garder ces stratégies à l'esprit lorsque vous vous efforcez d'améliorer les performances et l'évolutivité de votre application ASP.NET.

La rencontre des grands esprits

À un moment du cycle de vie de chaque application ASP.NET, les développeurs et le personnel réseau/personnel informatique doivent se rencontrer. Avec un peu de chance, cette rencontre interviendra avant le déploiement de l'application, mais parfois, elle a lieu en pleine crise, par exemple lorsque l'application s'exécute parfaitement dans l'environnement de test mais fonctionne au ralenti une fois expédiée aux utilisateurs. (C'est à ce moment qu'on fait appel à des consultants tels que moi).

Lorsque les développeurs et les responsables réseau se rencontrent, leur principal objectif est d'échanger des informations. Les développeurs ont une connaissance approfondie de l'application, tandis que le personnel réseau connaît parfaitement l'environnement d'exploitation. Chaque groupe doit comprendre les données que possède l'autre, et plus leur rencontre intervient à un stade précoce du cycle de vie de l'application, mieux cela vaut.

Cette rencontre ne doit pas avoir lieu pour la première fois pendant une crise. Si les deux équipes ne communiquent pas, il sera très difficile de savoir pourquoi l'application ne fonctionne pas correctement. En outre, il est trop simple d'adopter une position défensive et de décréter que le problème concerne uniquement l'autre équipe. Ce n'est jamais vrai. Les deux parties doivent invariablement collaborer pour résoudre un problème un tant soit peu complexe.

Toutefois, même lorsque les conditions sont bonnes, la réunion peut donner lieu à des difficultés. Celles que j'organise commencent généralement avec le personnel réseau d'un côté et les développeurs de l'autre. Ils se dévisagent. Pour lancer la conversation, je définis l'objectif de la réunion, à savoir un échange de connaissances. Peu importe qui est le premier à prendre la parole. Je commencerai par définir les informations que l'équipe réseau doit obtenir de l'équipe de développement.

Informations que l'équipe réseau doit obtenir de l'équipe de développement

Chaque application ASP.NET a ses propres particularités, mais certains éléments clés s'appliquent à tous les cas. Le fichier web.config est l'un de ceux-là (voir la figure 1). Web.config est un point d'intersection entre l'équipe de développement et l'équipe réseau. Il est configuré parfois par les développeurs et parfois par le personnel réseau. Le contenu de web.config impose des limites au matériel et à la configuration réseau et affecte directement le fonctionnement de l'application. L'examen en détail de chaque aspect du fichier web.config pourrait aisément faire l'objet d'un livre entier ; ce qu'il faut comprendre, c'est que les deux groupes doivent étudier le fichier web.config et se mettre d'accord sur ce que signifie la configuration qu'il représente, ainsi que sur l'impact qu'auront les divers paramètres sur l'application et sur l'environnement.

fig01.gif

Figure 1 Fichier web.config de base présentant des paramètres d'application et la configuration de messages d'erreur personnalisés (Cliquez sur l'image pour l'agrandir)

Par exemple, la section <authorization> de web.config spécifie comment les utilisateurs seront authentifiés dans l'application et définit ainsi une dépendance. Si l'application utilise l'authentification Windows®, elle peut dépendre d'Active Directory®. Si elle utilise l'authentification basée sur les formulaires, la dépendance se trouve sur une banque de données de comptes utilisateur. Cette question mérite certainement une petite conversation.

La section <customErrors> est importante parce qu'elle a un effet sur la façon dont l'échec est vu par les utilisateurs. Ce paramètre n'est pas complexe, mais il est préférable d'en discuter afin de comprendre la nature des pages d'erreur. Au début du cycle de collaboration, il n'y a probablement pas de page d'erreur personnalisée, ce qui mérite également d'être discuté.

La section <appSettings> de web.config peut être particulièrement significative. C'est généralement là que les développeurs placent les valeurs globales telles que les chaînes de connexion pour les bases de données. Il s'agit d'une grande source de dépendances et d'un élément clé de la planification pour le basculement, la migration, etc. Mais comme la section <appSettings> est entièrement personnalisée, elle peut contenir pratiquement n'importe quoi et la compréhension de son contenu peut nécessiter beaucoup d'explications. Les orphelins (des valeurs qui ne sont utilisées nulle part dans l'application) sont souvent laissés dans cette section.

Même si vos développeurs n'utilisent pas <appSettings>, l'équipe réseau ou d'exploitation peuvent souhaiter l'utiliser ; en effet, le regroupement de toutes les chaînes de connexion de base de données dans cette section constitue une façon efficace de créer une stratégie de basculement simple. Si le serveur de base de données meurt, une chaîne de remplacement pointant vers un serveur de base de données différent peut être insérée. Si vous exploitez cette opportunité au début du cycle de développement, vous renforcez la fiabilité et la facilité de gestion de l'application.

Enfin, vous devez noter une valeur de web.config absolument essentielle pour la montée en charge : il s'agit de la balise <sessionState>, qui détermine l'emplacement où les données de session seront stockées pour l'application. Par défaut, ces données sont stockées « InProc », c'est-à-dire dans l'espace de processus de l'application ASP.NET. Si les données de session sont configurées in-process, cela signifie que tout équilibrage de la charge doit être « permanent » ; un utilisateur donné doit toujours être redirigé vers le même serveur, là où résident les données de session. Ce sujet doit faire l'objet d'une importante conversation entre les développeurs et l'équipe réseau parce qu'il influe directement sur la montée en charge et le basculement. En abordant ce point dès le début, vous éviterez de nombreux problèmes lorsque vous essayerez de déboguer l'application.

Lorsque la conversation en vient à l'état de session, il est facile d'enchaîner sur les exigences en matière d'équilibrage de la charge de l'application en général. Certains environnements possèdent un matériel d'équilibrage de la charge dédié avec des fonctionnalités spécifiques, mais si l'application ne peut pas contrôler ces fonctionnalités, ces dernières ne serviront pas à grand-chose. J'ai rencontré des cas où l'équilibrage de la charge matériel était utilisé avec une application ASP.NET qui avait des données de session in-process, ce qui a donné lieu à des pertes de sessions occasionnelles sans aucune explication. Cela avait l'air d'un bogue dans l'application, mais il s'agissait en fait d'une erreur de configuration.

L'équipe réseau doit absolument obtenir des développeurs des informations détaillées sur les schémas d’équilibrage de la charge qui fonctionneront pour l'application. Cette conversation doit être véritablement bilatérale et doit déterminer quels schémas d’équilibrage de la charge sont disponibles et lesquels l'application peut tolérer. L'un des principaux avantages d'organiser cette conversation dès le début du cycle de vie de l'application réside dans le fait qu'il est possible de prévoir à l'avance de passer à un schéma d’équilibrage de la charge sans affinité et out-of-process.

Lorsqu'une application ASP.NET sera prête à être déployée (ou en sera au déploiement initial), l'équipe de développement aura une bonne idée des parties de l'application qui sont rapides et de celles qui sont lentes. Chose plus importante, elle pourra prévoir les goulots d'étranglement ou les points de crise potentiels dans le système. Si l'équipe réseau/exploitation est avertie de ces goulots d'étranglement, elle peut se préparer à les affronter et peut-être même les éviter.

Par exemple, j'ai une fois travaillé avec une application qui avait un énorme processus de chargement de données tous les soirs, moment où cette application était inactive. Les développeurs avaient créé le mécanisme de chargement de données, l'avaient testé et avaient compris comment il fonctionnait. Ils savaient qu'il soumettait la base de données à beaucoup de contraintes, mais il était efficace et constituait une bonne façon de résoudre le problème.

Toutefois, ils n'ont jamais informé l'équipe réseau de la création de ce processus ni du fait qu'il devait s'exécuter à 01h00, c'est-à-dire exactement au moment où les sauvegardes de la base de données étaient exécutées. La base de données restait en ligne, mais elle s'exécutait beaucoup plus lentement pendant la sauvegarde car toutes les transactions envoyées à la base de données étaient retenues dans le journal des transactions.

Ce n'est que lorsque le chargement et la sauvegarde simultanés des données a provoqué un manque d'espace disque au niveau du journal des transactions de la base de données que le conflit a été identifié. Le problème a été résolu en reportant le lancement du chargement des données à 03h00, mais seulement après plusieurs jours de crise.

En discutant de ces problèmes de charge de travail de votre application au moment opportun, vous pouvez peut éviter des tas de problèmes en cours de route.

Informations que l'équipe de développement doit obtenir de l'équipe réseau

Mon point de départ préféré pour la partie de la réunion où l'équipe réseau explique son environnement à l'équipe de développement est le diagramme du réseau. Bien trop souvent, les développeurs voient le réseau comme il est illustré par la figure 2, c'est-à-dire sans aucun réseau, juste des serveurs Web, des navigateurs et Internet.

fig02.gif

Figure 2 La vision simple du réseau du développeur (Cliquez sur l'image pour l'agrandir)

La réalité est, bien sûr, beaucoup plus complexe. Un diagramme comme celui de la figure 3 est plus proche de la vérité, bien qu'il soit lui aussi simplifié. Lorsque vous regardez la figure 3, des questions vous viennent immédiatement à l'esprit, telles que « Comment les utilisateurs VPN (Réseau privé virtuel) utilisent-ils l'application » ou « Quelle est la différence en termes d'authentification entre un utilisateur interne et un utilisateur public », et ainsi de suite.

fig03.gif

Figure 3 Le vrai réseau que les développeurs doivent comprendre (Cliquez sur l'image pour l'agrandir)

Bien sûr, un diagramme du réseau à lui seul ne suffit pas. Il est également important d'expliquer le réseau en détail parce qu'il est impossible de savoir, juste en regardant un diagramme, quels éléments auront un effet sur l'application. Vous devez expliquer le processus de connexion réel d'un utilisateur public, d'un utilisateur VPN et d'un utilisateur interne. En abordant les diverses règles de pare-feu qui existent, surtout dans les architectures réseau de type DMZ plus complexes, vous soulèverez par là-même les problèmes qui peuvent se poser à l'application.

Bien sûr, il serait avantageux de tenir toutes ces discussions avant le déploiement de l'application ou même avant le début de son développement. Mais quoi qu'il en soit, cette discussion doit avoir lieu, et il est essentiel que tous ceux qui sont réunis autour de la table comprennent le diagramme du réseau tout entier.

La mise en réseau est également l'arène des modèles de basculement et de redondance, mais sans une certaine prise en charge logicielle ou au moins une certaine connaissance du comportement, ces modèles fonctionnent rarement comme prévu. Une discussion détaillée des divers scénarios de défaillance doit avoir lieu. Si le clustering est en place sur la base de données, cela affectera le code lié à l'accès à la base de données. Par exemple, les requêtes peuvent-elles effectuer une nouvelle tentative après un changement de serveur ? Si un site redondant est disponible, comment les données seront-elles répliquées sur le site ? Comment s'effectue le passage d'un site à l'autre en cas de basculement ?

Là aussi, il est préférable d'en discuter à un stade précoce du cycle de vie, mais mieux vaut tard que jamais : toutes les personnes concernées par l'application doivent savoir comment fonctionnent ces choses. Il n'y a rien de plus frustrant qu'une solution de basculement qui ne fonctionne pas lorsqu'on en a besoin.

Enfin, il existe une autre ressource réseau clé qui doit être partagée : les journaux de production. Il est recommandé de toujours mettre les journaux de production à la disposition de l'équipe de développement. L'équipe réseau ne le fait pas en général, préférant qu'on les lui demande le cas échéant. Je ne pense pas que cette attitude soit adéquate. Il est beaucoup plus efficace de donner aux développeurs la possibilité de récupérer les journaux eux-mêmes, par exemple à partir d'un site de sauvegarde.

Les journaux de production sont essentiels durant une crise. Ils sont souvent la meilleure (et la seule) source d'informations empiriques réelles sur ce qui s'est passé. Ils sont également précieux dans des circonstances plus ordinaires. Lorsque les développeurs ont un accès régulier aux journaux de production, ils peuvent les utiliser pour voir comment une nouvelle fonctionnalité se comporte. Il s'agit d'un bon moyen de découvrir si votre fonctionnalité ne fait pas ce qu'elle doit faire et de résoudre le problème avant qu'il ne cause une crise. Si tout le monde a accès aux journaux, il est possible de réagir aux problèmes plus rapidement et de les résoudre plus tôt.

Retour à la montée en charge

La réunion entre l'équipe réseau et les développeurs vise avant tout à comprendre l'étendue des problèmes liés à la montée en charge d'une application ASP.NET. L'environnement réel dans lequel l'application fonctionne affecte directement le fonctionnement du code exécuté par l'application. Toutes les stratégies liées à la montée en charge auront un impact sur le comportement du code dans l'environnement. L'application d'une stratégie de spécialisation telle que la séparation des parties SSL de l'application peut nécessiter des modifications de l'environnement de mise en réseau et probablement des modifications des serveurs eux-mêmes.

Même une modification apparemment centrée sur le code telle que l'utilisation de la mise en cache peut influer sur l'environnement. Cela est dû au fait que lorsque vous ajoutez la mise en cache des données à votre application ASP.NET, vous diminuez le nombre d'appels de base de données en échange d'une utilisation accrue de la mémoire. Vous risquez donc de devoir augmenter le nombre de serveurs ASP.NET dont vous avez besoin ou augmenter le nombre de recyclages de thread de travail sur les serveurs, ce qui déclencherait des événements du côté de la surveillance réseau.

La montée en charge de votre application ASP.NET a un impact à la fois sur l'équipe réseau et sur les développeurs ; il est donc sage de faire participer ces deux groupes au processus de prise de décision. Souvent, cette collaboration produira des solutions originales qui ne pourraient pas être découvertes si les deux équipes travaillaient indépendamment l'une de l'autre. Par exemple, l'équipe réseau pourrait être au courant de l'existence dans l'entreprise de solutions matérielles pouvant aider les développeurs à atteindre les objectifs de performances et de montée en charge. C'est à travers une discussion détaillée de l'application et de l'environnement que ces opportunités seront dévoilées.

Branle-bas de combat

Ressources pour la montée en charge d'applications ASP.NET

Une crise en pleine montée en charge n'est pas nécessairement une mauvaise chose ; en fait, elle entraîne souvent des conséquences positives puisqu'elle est provoquée par un nombre excessif d'utilisateurs qui veulent exécuter votre application, ce qui, à son tour, prouve la qualité de votre application ! Vous devez, toutefois, veiller à ce qu'elle fonctionne parfaitement.

Parfois les crises de montée en charge sont provoquées par un autre événement, par exemple le fait que votre entreprise organise une promotion ou le fait que vous fassiez l'objet d'un billet de blog ou qu'un site de réseau social ait dirigé énormément de personnes vers votre site Web d'un seul coup. Tout d'un coup, vous devez vous mobiliser pour maintenir l'exécution de l'application. Comme vous le savez probablement, il est préférable de vous entraîner à faire face à ce type de scénario avant qu'il ne se produise. Et une démonstration de la façon dont la collaboration peut aider une organisation à surmonter cette crise est la meilleure façon de conclure votre réunion entre l'équipe de développeurs et l'équipe réseau.

La première question à poser dans cette situation est : « Comment détectons-nous que le site est en train de succomber à la charge » ? Bien trop souvent, la réponse est : « Nous recevons un appel du Directeur technique ». Si le premier signe d'un problème au niveau de votre site Web est un appel provenant de l'extérieur, vous avez un gros problème ! Un bon système de vérification devrait pouvoir vous avertir de tels problèmes avant que le téléphone ne sonne. Il n'empêchera pas le téléphone de sonner, mais il vous donnera au moins le temps de préparer votre répondre. Ce n'est pas en répondant « Ah bon ? » au directeur technique que vous serez promu au sein de l'entreprise !

Question suivante : Qui est appelé en premier ? Qui réagit à l'événement ? Souvent, c'est un membre de l'équipe réseau qui est averti en premier, et cette personne risque de manquer d'expérience ; vous devez donc mettre en place un bon plan de promotion des problèmes. Qui est appelé ensuite ? La difficulté consiste à effectuer un diagnostic rapide et précis pour identifier le problème auquel vous êtes confronté. Une panne du réseau est une chose, mais un problème de montée en charge est quelque chose de complètement différent. En cas de problème de montée en charge, il est recommandé de faire appel à un membre de l'équipe de développement dès le départ.

Toutes les personnes mobilisées doivent disposer de bonnes informations, et il est donc essentiel qu'elles bénéficient de droits d'accès adéquats. L'objectif est de disséminer autant d'informations que possible afin qu'un diagnostic efficace puisse être établi, lequel devrait au bout du compte déterminer l'étendue de la solution.

Souvent, si la seule réponse est d'écrire du code, l'événement sera terminé avant même que le code ne soit écrit. Bien sûr, l'événement doit être noté afin d'aider à déterminer les priorités de développement à l'avenir, mais il n'est pas raisonnable (ou recommandé) d'essayer d'écrire un tas de code et de le mettre en production sans avoir procédé à des tests minutieux. Règle numéro un de n'importe quel combat : ne pas envenimer les choses.

Dans le cas d'un problème de montée en charge, la solution consiste parfois à attendre qu'il disparaisse de lui-même. Il s'agit quand même d'une décision qui doit être prise.

En même temps, la mise en place de plans de secours implique la possibilité d'appliquer différentes techniques rapidement. La participation des équipes réseau et de développement à un problème de montée en charge contribue souvent à le résoudre rapidement, peut-être même suffisamment rapidement pour encore accroître le succès de cet événement promotionnel !

En conclusion, la leçon retenue par l'équipe réseau est qu'une application ASP.NET performante et hautement évolutive est le résultat d'une collaboration réussie entre les personnes qui créent l'application et celles qui la déploient et l'exécutent.

La collaboration étant inévitable, il est donc préférable d'organiser les réunions d'équipes au début du cycle de vie pour partager les informations. L'objectif des réunions est de comprendre et de s'accorder sur tous les éléments de l'application, sur ce qu'elle fait, sur la façon dont elle fonctionne, les éléments dont elle dépend, son comportement sous la charge et la façon dont elle gère les problèmes qui se présentent au fil du temps.

Lorsque cette collaboration est vraiment efficace, elle se traduit par une entreprise plus agile, capable de réagir rapidement en cas de problèmes et de définir clairement les objectifs nécessaires au succès de l'application à l'avenir.

Richard Campbell est directeur régional de Microsoft, MVP ASP.NET et coanimateur de .NET Rocks, le débat audio sur Internet destiné aux développeurs .NET (dotnetrocks.com). Il a travaillé pendant de nombreuses années en tant que consultant spécialisé dans les performances et l'évolutivité d'ASP.NET, et est également l'un des cofondateurs de Strangeloop Networks.

© 2008 Microsoft Corporation et CMP Media, LLC. Tous droits réservés. La reproduction partielle ou totale sans autorisation est interdite.