Configurer des requêtes de préchauffage pour améliorer les performances

Vous pouvez utiliser des requêtes de préchauffage afin d'éviter la latence des requêtes et des réponses lorsque le code de votre application est chargé dans une instance nouvellement créée.

App Engine doit fréquemment charger le code de l'application dans une nouvelle instance. Le chargement d'une instance peut se produire dans les situations suivantes :

  • Lorsque vous redéployez une version de votre application
  • Lorsque des instances sont créées parce que la charge générée par les requêtes dépasse la capacité de l'ensemble actuel des instances en cours d'exécution
  • En cas d'opérations de maintenance et de réparation de l'infrastructure sous-jacente ou du matériel physique

Le chargement du code de l'application dans une nouvelle instance peut déclencher des requêtes de chargement. Ces requêtes peuvent entraîner une augmentation de la latence de requête pour vos utilisateurs, mais vous pouvez éviter ce temps de latence grâce à des requêtes de préchauffage. Les requêtes de préchauffage chargent le code de votre application dans une nouvelle instance avant que des requêtes en temps réel n'atteignent cette instance.

Si les requêtes de préchauffage sont activées pour votre application, App Engine tente de détecter à quel moment cette dernière a besoin d'une nouvelle instance, et lance une requête de préchauffage pour initialiser une nouvelle instance. Cependant, ces tentatives de détection ne fonctionnent pas à chaque fois. Par conséquent, vous pouvez subir des requêtes de chargement, même si les requêtes de préchauffage sont activées dans votre application. Par exemple, si votre application ne diffuse aucun trafic, la première requête envoyée à l'application sera toujours une requête de chargement, et non une requête de préchauffage.

Les requêtes de préchauffage utilisent des instances-heures comme toute autre requête adressée à votre application App Engine. Dans la plupart des cas où les requêtes de préchauffage sont activées, vous ne remarquerez pas d'augmentation du nombre d'instances-heures, car votre application est simplement initialisée dans une requête de préchauffage. Vos instances-heures peuvent augmenter si vous décidez d'effectuer plus de travail, comme la mise en cache préalable lors d'une requête de préchauffage. Si vous définissez min_idle_instances sur une valeur supérieure à 0, vous risquez de recevoir des requêtes de préchauffage lorsque ces instances démarrent pour la première fois, mais elles resteront disponibles après cette date.

La requête de préchauffage par défaut entraîne l'indexation de tous les fichiers JAR en mémoire et l'initialisation de votre application et vos filtres.

Activer des requêtes de préchauffage

Les requêtes de préchauffage sont employées par le programmeur App Engine, qui contrôle l'autoscaling des instances en fonction de la configuration fournie par l'utilisateur. Dans l'environnement d'exécution Java d'App Engine, les requêtes de préchauffage sont activées par défaut. App Engine envoie donc des requêtes GET à /_ah/warmup, ce qui vous permet de répondre et d'initialiser le code de votre application selon vos besoins. Vous pouvez répondre aux requêtes de préchauffage en utilisant l'une des méthodes suivantes :

Utiliser un servlet <load-on-startup>
La méthode la plus simple pour fournir une logique de préchauffage consiste à marquer vos propres servlets comme <load-on-startup> dans le fichier de configuration web.xml.
Utiliser un ServletContextListener
Cette méthode vous permet d'exécuter une logique personnalisée avant que l'un de vos servlets ne soit appelé par le biais d'une requête de préchauffage ou d'une requête de chargement.
Utiliser un servlet de préchauffage personnalisé
L'utilisation d'un servlet de préchauffage personnalisé appelle la méthode service du servlet seulement lors d'une requête de préchauffage, et non lors des requêtes de chargement.

Vous devrez peut-être implémenter votre propre gestionnaire pour /_ah/warmup en fonction de la méthode choisie.

Avant de commencer

Lorsque les requêtes de préchauffage sont activées, le programmeur démarre des instances lorsqu'il détermine que davantage d'instances sont nécessaires. Le programmeur utilise les requêtes de préchauffage pour démarrer votre application. Vous verrez donc les journaux, même si votre application ne traite pas ces requêtes de préchauffage.

Le message suivant indique les requêtes de préchauffage dans les journaux /_ah/warmup :

This request caused a new process to be started for your application, and thus caused your application code to be loaded for the first time. This request may thus take longer and use more CPU than a typical request for your application.

Notez que l'appel des requêtes de préchauffage n'est pas garanti. Dans certains cas, des requêtes de chargement sont envoyées à la place, par exemple s'il s'agit de la première instance démarrée ou en cas de forte augmentation du trafic. Cependant, si les requêtes de préchauffage sont activées, le système fera de son mieux pour envoyer les requêtes aux instances déjà préchauffées.

Dans Java 8, les requêtes de préchauffage sont activées par défaut. Pour les activer, ajoutez - warmup à la directive inbound_services dans le fichier appengine-web.xml. Comme les préchauffages sont activés par défaut, vous ne devez les activer explicitement que si vous avez déjà déployé une application avec des requêtes de préchauffage désactivées dans appengine-web.xml. Dans ce cas, vous devez définir la valeur <warmup-requests-enabled> sur true, puis la redéployer.

Utiliser un servlet <load-on-startup>

La façon la plus simple de créer une logique de préchauffage consiste à marquer vos propres servlets comme étant <load-on-startup> dans le fichier web.xml. Cette méthode n'implique aucun changement au niveau du code de l'application et initialise tous les servlets spécifiés au moment de l'initialisation de l'application.

Dans votre fichier web.xml, pour les servlets que vous souhaitez charger au démarrage, ajoutez l'élément <load-on-startup>1</load-on-startup> à votre élément <servlet>. Exemple :

<servlet>
  <servlet-name>my-servlet</servlet-name>
  <servlet-class>com.company.MyServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
</servlet>

Ces lignes chargent la classe de servlet spécifiée et appellent la méthode init() du servlet. La requête de préchauffage initialise les servlets spécifiés avant de répondre à toute requête active. Toutefois, en cas d'absence de requête de préchauffage, les servlets spécifiés dans <load-on-startup> sont enregistrés à la première requête adressée à une nouvelle instance, ce qui génère une requête de chargement. Comme indiqué précédemment, App Engine peut ne pas émettre de requête de préchauffage chaque fois que votre application a besoin d'une nouvelle instance.

Utiliser un ServletContextListener

Si vous souhaitez exécuter une logique personnalisée avant l'appel de vos servlets :

  1. Enregistrez un ServletContextListener dans votre fichier web.xml.

    <listener>
      <listener-class>com.company.MyListener</listener-class>
    </listener>
    
  2. Fournissez une classe avec votre servlet et votre code de filtre :

    public class MyListener implements ServletContextListener {
      public void contextInitialized(ServletContextEvent event) {
        // This will be invoked as part of a warmup request, or
        // the first user request if no warmup request was invoked.
      }
      public void contextDestroyed(ServletContextEvent event) {
        // App Engine does not currently invoke this method.
      }
    }
    

Le ServletContextListener s'exécute lors d'une requête de préchauffage. En cas d'absence de requête de préchauffage, il s'exécute lors de la première requête adressée à une nouvelle instance. Cela peut entraîner des requêtes de chargement.

Utiliser un servlet de préchauffage personnalisé

Le servlet de préchauffage personnalisé appelle la méthode service du servlet seulement lors d'une requête de préchauffage. Vous pouvez éviter que les temps de chargement n'augmentent lors des requêtes de chargement en incluant la logique onéreuse dans un servlet de préchauffage personnalisé.

Pour créer ce type de servlet, il suffit de remplacer la définition du servlet intégré pour _ah_warmup dans web.xml :

<servlet>
  <servlet-name>_ah_warmup</servlet-name>
  <servlet-class>com.company.MyWarmupServlet</servlet-class>
</servlet>