Éviter les « cold queries » sur son site IIS

Avez-vous déjà remarqué qu’après une longue période d’inactivité votre site internet mettait du temps à répondre ? C’est ce qu’on appelle une « cold query« , c’est à dire une requête qui se verra ajouter un temps d’initialisation de l’application en plus de son temps de traitement habituel.

Avant d’entrer plus en détails sur les différents solutions pour pallier à ce problème, revoyons nos basiques !

AppDomain

Un domaine d’application fournit une couche d’isolement dans un processus. Tout ce que vous pensez habituellement comme «par programme» (variables statiques, etc.) est en fait par AppDomain.
Par exemple Entity Framework utilise l’AppDomain pour mettre en cache :
  • Les métadonnées : contient les infos pour faire le lien entre les value types C# et les types de base de donnée
  • Les vues générées : la transformation nécessaire entre les objets C# et les tables de la base de données
  • Les traductions des requêtes LINQ en SQL

Plus d’infos à ce sujet http://msdn.microsoft.com/en-us/data/hh949853.aspx#2

 Application pool

Un pool d’applications est un mécanisme utilisé par IIS pour isoler les applications Web, cela permet d’avoir différentes configurations (sécurité, utilisation des ressources, etc.) et empêche les applications instables d’interférer avec d’autres applications.

Généralement, chaque pool d’applications correspond à un processus de travail. Un processus de travail est un processus windows (w3wp.exe) qui exécute des applications Web et est responsable du traitement des demandes envoyées à un serveur Web pour un pool d’applications spécifique.

Le pool d’applications peut contenir plusieurs AppDomain, d’où le compteur « Applications » visible dans la liste des pools d’application dans IIS.

Cycle de vie de l’application pool

Un recyclage signifie que le processus de travail qui gère les requêtes pour ce pool d’applications est terminé, et qu’un nouveau a pris le relais. Ceci afin d’éviter des états instables qui peuvent mener à des plantages, blocages ou des fuites mémoire. Les recyclages peuvent notamment se produire si on modifie le web.config ou le dossier bin du site web, et sont affectés par certains paramètres.

Les paramètres avancés du pool d’applications possède une section « Recyclage » où sont répertoriés les différents paramètres influant sur le cycle de vie dont voici la liste :

  • Intervalle de temps régulier (par défaut 29h)
  • Nombre limite de demandes (par défaut pas de limite)
  • Heures spécifiques (par défaut vide)
  • Limite de mémoire virtuelle  (par défaut pas de limite)
  • Limite de mémoire privée (par défaut pas de limite)

Un autre paramètre à ne pas négliger se trouve dans la section « Modèle de processus » :

  • Délai d’inactivité (20 minutes par défaut)

 

Résolution du problème

 

La méthode simple

Afin de régler le problème de « cold query » sur votre site IIS, vous pouvez simplement modifier tous les paramètres ci-dessus pour faire en sorte que le pool d’applications ne se recycle qu’en cas de modification du site web.

Sur une configuration par défaut il suffit de mettre 0 pour « Intervalle de temps régulier » et pour « Délai d’inactivité« . Cependant cette méthode est fortement déconseillée. Le pool d’application DOIT être recyclé à intervalles régulier, sinon la moindre et infime fuite mémoire dans n’importe quelle librairie (ASP.Net inclus) va être source de plantages aléatoires, inexpliqués, et inexplicables.

 

La méthode Preload

Une requête est envoyée une fois que le pool d’applications a été recyclé, cela permet de conserver sa logique au niveau du global.asax, mais si l’initialisation est longue cela peut figer le site. De plus la requête n’est pas déclenchée lorsque l’application est redéployée.

1) Installation du module « Application Initialization »

– Sur un Windows classique : Programmes et fonctionnalités -> Activer ou désactiver des fonctionnalités Windows -> Internet et Information Services -> Services World Wide Web -> Initialisation d’application

– Sur un Windows Server : Server Manager -> Ajouter des rôles ou fonctionnalités -> Rôle serveur -> Internet et Information Services -> Services World Wide Web -> Initialisation d’application

2) Configuration du pool d’applications

– Sur la liste des pools d’applications -> sélectionner le pool d’application

  • Paramètres de base -> cocher « Démarrer automatiquement le pool d’applications »
  • Paramètres avancés -> section Général : mettre « Mode de démarrage » à « Always Running« 

3) Configuration du site Web

Dans la page d’accueil du serveur ouvrir l’éditeur de configuration:

1 EditeurConfigurationServeur

Sélectionner la section « sites» sous « applicationHost » via le menu déroulant « section » :

2 choisirApplicationHost

Ouvrir la collection :

3 OuvrirCollectionApplication

Sélectionner votre site web :

  • Mettre serverAutoStart à true

4 OuvrirCollectionAppPool

Dans les paramètres de la nouvelle fenêtre mettre :

  • preloadEnabled à true

5.1 OptionAppPool

Fermer les fenêtres. De retour sur l’éditeur de configuration, vous pouvez faire « Générer le script » afin de rendre la tâche répétable 😉 Sinon, faites appliquer.

6 AppliquerChangement

Dans le web.config de l’application, ajouter :

<system.webServer>
     <applicationInitialization doAppInitAfterRestart="true"/>
</system.webServer>

A noter qu’il y a deux attributs optionnels :

  • remapManagedRequestsTo : Permet de spécrediriger les requêtes vers une page statique pendant l’initialisation du site web.
  • skipManagedModules : Spécifie si les modules managés de IIS sont chargés durant l’initialisation.

Checklist :

  • Pool d’Application
    • Démarrage automatique
    • Mode de démarrage à AlwaysRunning
  • Site web
    • serverAutoStart à true
    • Application du site web
      • preloadEnabled à true
  • Web.config :
    • Avoir ajouté la clé applicationInitalization
  • Global asax ou dans Startup.cs
    • Mettre votre logique d’initialisation : par exemple si vous utilisez Entity Framework, faire une query qui charge un objet complexe afin de mettre en cache un maximum de choses au niveau de l’AppDomain.

 

La méthode serviceAutoStart

La méthode Preload d’une classe implémentant « System.Web.Hosting.IProcessHostPreloadClient » est appelée (ne déclenche ni l’Application_Start du Global.asax ni la classe « Startup » de Owin). C’est la méthode recommandée pour garder son application up tout le temps mais la plus contraignante.

1) Créer votre classe implémentant « System.Web.Hosting.IProcessHostPreloadClient »

Exemple :

public class MvcMusicStoreApplicationPreloadClient : IProcessHostPreloadClient
{
    public void Preload(string[] parameters)
    {
        var service = new TopSellingAlbumsService();
        HttpRuntime.Cache["TopSellingAlbums"] = service.GetTopFiveSellingAlbums();
    }
}

2) Installation du module « Application Initialization »

– Sur un Windows classique : Programmes et fonctionnalités -> Activer ou désactiver des fonctionnalités Windows -> Internet et Information Services -> Services World Wide Web -> Initialisation d’application

– Sur un Windows Server : Server Manager ->Ajouter des rôles ou fonctionnalités -> Rôle serveur -> Internet et Information Services -> Services World Wide Web -> Initialisation d’application

3) Configuration du pool d’applications

– Sur la liste des pools d’applications -> sélectionner le pool d’application

  • Paramètres de base -> cocher « Démarrer automatiquement le pool d’applications »
  • Paramètres avancés -> section Général : mettre « Mode de démarrage » à « Always Running« 

4) Ouvrir l’éditeur de configuration

Dans la page d’accueil du serveur ouvrir l’éditeur de configuration:

1 EditeurConfigurationServeur

5) Ajouter le service à IIS

Sélectionner la section « serviceAutoStartProviders» sous « applicationHost » via le menu déroulant « section » :

2 choisirSercice

Ouvrir la collection :

3 OuvrirCollection servicesAutoStart

Ajouter votre service :

4 Ajouter serviceProvider

Pour le champ type, mettre le nom complet du type implémentant IProcessHostPreloadClient par exemple : « MvcMusicStore.MvcMusicStoreApplicationPreloadClient, MvcMusicStore » (MvcMusicStore est la DLL). Fermer la fenêtre.

6) Configurer le site web

Sélectionner la section « sites» sous « applicationHost » via le menu déroulant « section » :

2 choisirApplicationHost

Ouvrir la collection :

3 OuvrirCollectionApplication

Sélectionner votre site web :

  • Mettre serverAutoStart à true

4 OuvrirCollectionAppPool

Dans les paramètres de la nouvelle fenêtre mettre :

  • serviceAutoStartEnabled à true
  • serviceAutoStartProvider : mettre le nom de votre service

5.1 OptionAppPool

Fermer les fenêtres. De retour sur l’éditeur de configuration, vous pouvez faire « Générer le script » afin de rendre la tâche répétable 😉 Sinon, faites appliquer.

6 AppliquerChangement

Checklist

  • Pool d’Application
    • Démarrage automatique
    • Mode de démarrage à AlwaysRunning
  • Service Provider
    • Ajouter votre service en utilisant le nom complet pour le type
  • Site web
    • serverAutoStart à true
    • Application du site web
      • serviceAutoStartEnabled à true
      • serviceAutoStartProvider attribué au service précédemment ajouté
  • Web.config :
    • Avoir ajouté la clé applicationInitalization

 

 

Conclusion

Vous avez maintenant toutes les clés en main pour résoudre votre problème avec la solution la plus adaptée ! Même si cela peut sembler compliqué la 1ère fois, les méthodes « Preload » et « serviceAutoStart » sont finalement assez rapide à mettre en place une fois qu’on a pris le coup de main.

Enfin, notez que même si rien n’empêche d’utiliser les deux dernières solutions simultanément, cela est déconseillé car ça peut entrainer des instabilités (notamment des initialisations s’effectuant plusieurs fois).

 

Ressource :

http://www.iis.net/configreference/system.webserver/applicationinitialization

http://www.iis.net/configreference/system.applicationhost/serviceautostartproviders

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s