Meilleures pratiques de développement web (création d’applications cloud Real-World avec Azure)
par Rick Anderson, Tom Dykstra
Télécharger corriger le projet ou télécharger le livre électronique
Le livre électronique Building Real World Cloud Apps with Azure est basé sur une présentation développée par Scott Guthrie. Il explique 13 modèles et pratiques qui peuvent vous aider à développer des applications web pour le cloud. Pour plus d’informations sur le livre électronique, consultez le premier chapitre.
Les trois premiers modèles portaient sur la mise en place d’un processus de développement agile ; le reste concerne l’architecture et le code. Celui-ci est une collection de bonnes pratiques de développement web :
- Serveurs web sans état derrière un équilibreur de charge intelligent.
- Évitez l’état de session (ou si vous ne pouvez pas l’éviter, utilisez le cache distribué plutôt qu’une base de données).
- Utilisez un CDN pour mettre en cache des ressources de fichiers statiques (images, scripts).
- Utilisez la prise en charge asynchrone de .NET 4.5 pour éviter de bloquer les appels.
Ces pratiques sont valables pour tous les développements web, pas seulement pour les applications cloud, mais elles sont particulièrement importantes pour les applications cloud. Ils travaillent ensemble pour vous aider à tirer le meilleur profit de la mise à l’échelle hautement flexible offerte par l’environnement cloud. Si vous ne suivez pas ces pratiques, vous rencontrez des limitations lorsque vous essayez de mettre à l’échelle votre application.
Niveau Web sans état derrière un équilibreur de charge intelligent
Le niveau Web sans état signifie que vous ne stockez pas de données d’application dans la mémoire du serveur web ou le système de fichiers. Le fait de conserver votre niveau Web sans état vous permet à la fois d’offrir une meilleure expérience client et d’économiser de l’argent :
- Si la couche web est sans état et qu’elle se trouve derrière un équilibreur de charge, vous pouvez répondre rapidement aux modifications du trafic d’application en ajoutant ou en supprimant dynamiquement des serveurs. Dans l’environnement cloud où vous ne payez que pour les ressources du serveur tant que vous les utilisez réellement, cette capacité à répondre aux changements de la demande peut se traduire par d’énormes économies.
- Une couche Web sans état est architecturalement beaucoup plus simple pour effectuer un scale-out de l’application. Cela vous permet également de répondre plus rapidement aux besoins de mise à l’échelle et de dépenser moins d’argent en développement et en test dans le processus.
- Les serveurs cloud, comme les serveurs locaux, doivent être corrigés et redémarrés à l’occasion ; et si la couche Web est sans état, le réacheminement du trafic lorsqu’un serveur tombe temporairement en panne ne provoquera pas d’erreurs ou de comportement inattendu.
La plupart des applications réelles doivent stocker l’état d’une session web ; le main point ici est de ne pas le stocker sur le serveur web. Vous pouvez stocker l’état d’autres manières, par exemple sur le client dans des cookies ou côté serveur hors processus dans ASP.NET état de session à l’aide d’un fournisseur de cache. Vous pouvez stocker des fichiers dans le stockage d’objets blob Azure Windows au lieu du système de fichiers local.
Pour vous donner un exemple de la facilité avec laquelle il est possible de mettre à l’échelle une application dans Windows Azure Web Sites si votre niveau web est sans état, consultez l’onglet Mettre à l’échelle pour un site web Windows Azure dans le portail de gestion :
Si vous souhaitez ajouter des serveurs web, vous pouvez simplement faire glisser le curseur instance nombre vers la droite. Définissez-le sur 5 et cliquez sur Enregistrer. En quelques secondes, vous avez 5 serveurs web dans Windows Azure qui gèrent le trafic de votre site web.
Vous pouvez tout aussi facilement définir le nombre de instance sur 3 ou 1. Lorsque vous effectuez un scale-back, vous commencez à économiser de l’argent immédiatement, car Windows Azure facture à la minute, pas à l’heure.
Vous pouvez également indiquer à Windows Azure d’augmenter ou de diminuer automatiquement le nombre de serveurs web en fonction de l’utilisation du processeur. Dans l’exemple suivant, lorsque l’utilisation du processeur est inférieure à 60 %, le nombre de serveurs web diminue à un minimum de 2, et si l’utilisation du processeur dépasse 80 %, le nombre de serveurs web est augmenté jusqu’à un maximum de 4.
Ou que se passe-t-il si vous savez que votre site ne sera occupé que pendant les heures de travail ? Vous pouvez indiquer à Windows Azure d’exécuter plusieurs serveurs pendant la journée et de réduire à un seul serveur les soirs, les nuits et les week-ends. La série suivante de captures d’écran montre comment configurer le site web pour exécuter un serveur en dehors des heures creuses et 4 serveurs pendant les heures de travail de 8 h à 17 h.
Et bien sûr, tout cela peut être effectué dans des scripts ainsi que dans le portail.
La capacité de votre application à effectuer un scale-out est presque illimitée dans Windows Azure, tant que vous évitez les obstacles à l’ajout ou à la suppression dynamique de machines virtuelles serveur, en conservant la couche Web sans état.
Éviter l’état de session
Dans une application cloud réelle, il n’est souvent pas pratique d’éviter de stocker une forme d’état de session utilisateur, mais certaines approches ont davantage d’incidence que d’autres sur les performances et l'extensibilité. Si vous devez stocker un état, la meilleure solution consiste à veiller à ce qu’il reste de petite taille et à le stocker dans des cookies. Si ce n’est pas possible, la meilleure solution consiste à utiliser ASP.NET’état de session avec un fournisseur pour le cache distribué en mémoire. La pire solution du point de vue des performances et de l’extensibilité consiste à utiliser un fournisseur d’état de session s'appuyant sur une base de données.
Utiliser un CDN pour mettre en cache des ressources de fichiers statiques
CDN est un acronyme pour Content Delivery Network. Vous fournissez des ressources de fichiers statiques telles que des images et des fichiers de script à un fournisseur CDN, et le fournisseur met ces fichiers en cache dans les centres de données du monde entier afin que, partout où les utilisateurs accèdent à votre application, ils obtiennent une réponse relativement rapide et une faible latence pour les ressources mises en cache. Cela accélère le temps de chargement global du site et réduit la charge sur vos serveurs web. Les CDN sont particulièrement importants si vous atteignez un public largement distribué géographiquement.
Windows Azure a un CDN et vous pouvez utiliser d’autres CDN dans une application qui s’exécute dans Windows Azure ou dans n’importe quel environnement d’hébergement web.
Utiliser la prise en charge asynchrone de .NET 4.5 pour éviter de bloquer les appels
.NET 4.5 a amélioré les langages de programmation C# et VB afin de simplifier la gestion asynchrone des tâches. L’avantage de la programmation asynchrone n’est pas seulement pour les situations de traitement parallèle telles que lorsque vous souhaitez lancer plusieurs appels de service web simultanément. Il permet également à votre serveur web de fonctionner plus efficacement et plus fiable dans des conditions de charge élevée. Un serveur web ne dispose que d’un nombre limité de threads et, dans des conditions de charge élevée, lorsque tous les threads sont en cours d’utilisation, les demandes entrantes doivent attendre que les threads soient libérés. Si le code de votre application ne gère pas les tâches telles que les requêtes de base de données et les appels de service web de manière asynchrone, de nombreux threads sont inutilement liés pendant que le serveur attend une réponse d’E/S. Cela limite la quantité de trafic que le serveur peut gérer dans des conditions de charge élevée. Avec la programmation asynchrone, les threads qui attendent qu’un service web ou une base de données retournent des données sont libérés pour traiter de nouvelles demandes jusqu’à ce que les données soient reçues. Dans un serveur web occupé, des centaines ou des milliers de demandes peuvent alors être traitées rapidement, ce qui, sinon, attendrait que les threads soient libérés.
Comme vous l’avez vu précédemment, il est aussi facile de réduire le nombre de serveurs web qui gèrent votre site web que de les augmenter. Par conséquent, si un serveur peut obtenir un débit plus élevé, vous n’en avez pas besoin autant et vous pouvez réduire vos coûts, car vous avez besoin de moins de serveurs pour un volume de trafic donné que vous ne le feriez autrement.
La prise en charge du modèle de programmation asynchrone .NET 4.5 est incluse dans ASP.NET 4.5 pour Web Forms, MVC et l’API web ; dans Entity Framework 6 et dans l’API Stockage Azure Windows.
Prise en charge asynchrone dans ASP.NET 4.5
Dans ASP.NET 4.5, la prise en charge de la programmation asynchrone a été ajoutée non seulement au langage, mais également aux infrastructures MVC, Web Forms et API web. Par exemple, une méthode d’action de contrôleur MVC ASP.NET reçoit des données d’une requête web et transmet les données à une vue qui crée ensuite le code HTML à envoyer au navigateur. Souvent, la méthode d’action doit obtenir des données à partir d’une base de données ou d’un service web afin de les afficher dans une page web ou d’enregistrer les données entrées dans une page web. Dans ces scénarios, il est facile de rendre la méthode d’action asynchrone : au lieu de retourner un objet ActionResult, vous retournez Task<ActionResult> et marquez la méthode avec le mot clé asynchrone. À l’intérieur de la méthode, lorsqu’une ligne de code démarre une opération qui implique un temps d’attente, vous la marquez avec le mot clé d’attente.
Voici une méthode d’action simple qui appelle une méthode de dépôt pour une requête de base de données :
public ActionResult Index()
{
string currentUser = User.Identity.Name;
var result = fixItRepository.FindOpenTasksByOwner(currentUser);
return View(result);
}
Voici la même méthode qui gère l’appel de base de données de manière asynchrone :
public async Task<ActionResult> Index()
{
string currentUser = User.Identity.Name;
var result = await fixItRepository.FindOpenTasksByOwnerAsync(currentUser);
return View(result);
}
Sous le couvre, le compilateur génère le code asynchrone approprié. Lorsque l’application effectue l’appel à FindTaskByIdAsync
, ASP.NET effectue la FindTask
demande, puis déroule le thread de travail et le rend disponible pour traiter une autre requête. Une fois la FindTask
demande terminée, un thread est redémarré pour continuer à traiter le code qui arrive après cet appel. Pendant l’intervalle entre le moment où la FindTask
demande est lancée et le moment où les données sont retournées, vous disposez d’un thread disponible pour effectuer un travail utile qui, sinon, serait lié en attendant la réponse.
Il y a une certaine surcharge pour le code asynchrone, mais dans des conditions de faible charge, cette surcharge est négligeable, tandis que dans des conditions de charge élevée, vous pouvez traiter les demandes qui seraient autrement tenues en attente de threads disponibles.
Il a été possible d’effectuer ce type de programmation asynchrone depuis ASP.NET 1.1, mais il était difficile d’écrire, sujet aux erreurs et difficile à déboguer. Maintenant que nous avons simplifié le codage pour cela dans ASP.NET 4.5, il n’y a aucune raison de ne plus le faire.
Prise en charge asynchrone dans Entity Framework 6
Dans le cadre de la prise en charge asynchrone dans la version 4.5, nous avons fourni une prise en charge asynchrone des appels de service web, des sockets et des E/S de système de fichiers, mais le modèle le plus courant pour les applications web est d’atteindre une base de données, et nos bibliothèques de données ne prenaient pas en charge async. À présent, Entity Framework 6 ajoute la prise en charge asynchrone de l’accès à la base de données.
Dans Entity Framework 6, toutes les méthodes qui provoquent l’envoi d’une requête ou d’une commande à la base de données ont des versions asynchrones. L’exemple ci-dessous montre la version asynchrone de la méthode Find .
public async Task<FixItTask> FindTaskByIdAsync(int id)
{
FixItTask fixItTask = null;
Stopwatch timespan = Stopwatch.StartNew();
try
{
fixItTask = await db.FixItTasks.FindAsync(id);
timespan.Stop();
log.TraceApi("SQL Database", "FixItTaskRepository.FindTaskByIdAsync", timespan.Elapsed, "id={0}", id);
}
catch(Exception e)
{
log.Error(e, "Error in FixItTaskRepository.FindTaskByIdAsynx(id={0})", id);
}
return fixItTask;
}
Et cette prise en charge asynchrone fonctionne non seulement pour les insertions, les suppressions, les mises à jour et les recherches simples, elle fonctionne également avec les requêtes LINQ :
public async Task<List<FixItTask>> FindOpenTasksByOwnerAsync(string userName)
{
Stopwatch timespan = Stopwatch.StartNew();
try
{
var result = await db.FixItTasks
.Where(t => t.Owner == userName)
.Where(t=>t.IsDone == false)
.OrderByDescending(t => t.FixItTaskId).ToListAsync();
timespan.Stop();
log.TraceApi("SQL Database", "FixItTaskRepository.FindTasksByOwnerAsync", timespan.Elapsed, "username={0}", userName);
return result;
}
catch (Exception e)
{
log.Error(e, "Error in FixItTaskRepository.FindTasksByOwnerAsync(userName={0})", userName);
return null;
}
}
Il existe une Async
version de la ToList
méthode, car dans ce code, il s’agit de la méthode qui provoque l’envoi d’une requête à la base de données. Les Where
méthodes et OrderByDescending
configurent uniquement la requête, tandis que la ToListAsync
méthode exécute la requête et stocke la réponse dans la result
variable.
Résumé
Vous pouvez implémenter les meilleures pratiques de développement web décrites ici dans n’importe quel framework de programmation web et tout environnement cloud, mais nous disposons d’outils dans ASP.NET et Windows Azure pour faciliter la tâche. Si vous suivez ces modèles, vous pouvez facilement effectuer un scale-out de votre niveau web, et vous réduirez vos dépenses, car chaque serveur sera en mesure de gérer plus de trafic.
Le chapitre suivant examine comment le cloud active les scénarios d’authentification unique.
Ressources
Pour plus d’informations, consultez les ressources suivantes.
Serveurs web sans état :
- Modèles et pratiques Microsoft - Conseils sur la mise à l’échelle automatique.
- Désactivation de l’affinité d’instance d’ARR dans les sites web Windows Azure. Le billet de blog d’Erez Benari explique l’affinité de session dans Windows Azure Web Sites.
CDN:
- FailSafe : création de Services cloud évolutifs et résilients. Série vidéo en neuf parties par Ulrich Homann, Marc Mercuri et Mark Simms. Consultez la discussion CDN dans l’épisode 3 à partir de 1:34:00.
- Modèle d’hébergement de contenu statique Microsoft Patterns and Practices
- Révisions CDN. Vue d’ensemble de nombreux CDN.
Programmation asynchrone :
- Utilisation de méthodes asynchrones dans ASP.NET MVC 4. Tutoriel de Rick Anderson.
- Programmation asynchrone avec Async et Await (C# et Visual Basic). Livre blanc MSDN qui explique la raison d’être de la programmation asynchrone, son fonctionnement dans ASP.NET 4.5 et comment écrire du code pour l’implémenter.
- Requête asynchrone et enregistrement d’Entity Framework
- FailSafe : création de Services cloud évolutifs et résilients. Série vidéo en neuf parties par Ulrich Homann, Marc Mercuri et Mark Simms. Pour des discussions sur l’impact de la programmation asynchrone sur la scalabilité, consultez les épisodes 4 et 8.
- La magie de l’utilisation de méthodes asynchrones dans ASP.NET 4.5 plus un gotcha important. Billet de blog de Scott Hanselman, principalement sur l’utilisation d’async dans ASP.NET Web Forms applications.
Pour obtenir d’autres meilleures pratiques en matière de développement web, consultez les ressources suivantes :
- Exemple d’application Correctif - Meilleures pratiques. L’annexe de ce livre électronique répertorie un certain nombre de bonnes pratiques qui ont été implémentées dans l’application Corriger le problème.
- Liste de contrôle du développeur web
Commentaires
https://aka.ms/ContentUserFeedback.
Bientôt disponible : Tout au long de 2024, nous allons supprimer progressivement GitHub Issues comme mécanisme de commentaires pour le contenu et le remplacer par un nouveau système de commentaires. Pour plus d’informations, consultezEnvoyer et afficher des commentaires pour