Mode de gestion des instances

Les instances constituent la base d'App Engine : elles fournissent toutes les ressources nécessaires à l'hébergement d'une application. Sont inclus l'environnement d'exécution, les API App Engine, ainsi que la mémoire et le code de l'application. Chaque instance comprend une couche de sécurité qui garantit qu'une instance ne peut pas modifier une autre instance par inadvertance.

Les instances sont les unités de calcul dont se sert App Engine pour procéder au scaling automatique de votre application. À tout moment, l'application peut être exécutée sur une ou plusieurs instances, les requêtes étant réparties sur l'ensemble d'entre elles.

Présentation des instances

Les instances sont résidentes ou dynamiques. Une instance dynamique démarre et s'arrête automatiquement en fonction des besoins actuels. Une instance résidente s'exécute en permanence, ce qui peut améliorer les performances de l'application. Ces deux types d'instances instancient le code inclus dans une version du service App Engine.

Si vous utilisez le scaling manuel pour une application, celle-ci s'exécute sur des instances résidentes. Si vous utilisez le scaling de base ou automatique, l'application s'exécute sur des instances dynamiques.

La configuration de l'application consiste, entre autres, à spécifier le mode de scaling de ses services, y compris les paramètres suivants :

  • Le nombre initial d'instances pour un service
  • La façon dont les instances sont créées ou arrêtées en fonction du trafic
  • Le temps alloué à une instance pour le traitement d'une requête

Le type de scaling que vous définissez pour un service détermine si ses instances sont résidentes ou dynamiques :

  • Les services avec scaling automatique utilisent des instances dynamiques.
  • Les services avec scaling manuel utilisent des instances résidentes.
  • Les services avec scaling de base utilisent des instances dynamiques.

Dans App Engine, l'utilisation des instances est facturée à l'heure. Vous pouvez suivre leur utilisation sur la page Instances de la console Google Cloud Platform. Si vous souhaitez limiter les coûts engendrés par vos instances, vous pouvez définir un plafond budgétaire. Chaque service que vous déployez sur App Engine se comporte comme un microservice qui évolue indépendamment selon le type de scaling configuré.

Procéder au scaling des instances dynamiques

À un instant donné, les applications App Engine sont alimentées par un certain nombre d'instances dynamiques, en fonction du volume de requêtes entrantes. Le nombre d'instances dynamiques s'accroît à mesure que les requêtes adressées à votre application augmentent.

Le programmeur App Engine détermine s'il convient de diffuser chaque nouvelle requête avec une instance existante (qui est inactive ou accepte les requêtes simultanées), de placer la requête dans une file d'attente ou de démarrer une nouvelle instance pour cette requête. Cette décision se fonde sur le nombre d'instances disponibles, la rapidité avec laquelle votre application diffuse les requêtes (sa latence) et le temps nécessaire au démarrage d'une nouvelle instance.

Si vous appliquez le scaling automatique, vous pouvez optimiser le comportement du programmeur pour obtenir le compromis souhaité entre coûts et performances. Pour ce faire, vous devez définir les valeurs de target_cpu_utilization, target_throughput_utilization et max_concurrent_requests.

Paramètre d'autoscaling Description
Utilisation du processeur cible Définit le seuil d'utilisation du processeur à partir duquel d'autres instances sont démarrées pour gérer le trafic.
Utilisation du débit cible Définit le seuil de débit pour le nombre de requêtes simultanées au-delà duquel d'autres instances sont démarrées pour gérer le trafic.
Nombre max. de requêtes simultanées Définit le nombre de requêtes simultanées qu'une instance peut accepter avant que le programmeur ne génère une nouvelle instance.

Regardez la vidéo sur les nouveaux paramètres du programmeur App Engine pour découvrir leurs effets.

Chaque instance dispose de sa propre file d'attente pour les requêtes entrantes. App Engine surveille le nombre de requêtes présentes dans la file d'attente de chaque instance. Si les files d'attente d'une application deviennent trop longues en raison d'une charge accrue, App Engine crée automatiquement une instance pour gérer cette charge.

App Engine évolue à la hausse très rapidement. Ainsi, si vous envoyez des lots de requêtes à vos services (par exemple, à une file d'attente de tâches en vue de leur traitement), un grand nombre d'instances sont créées rapidement. Si possible, nous vous recommandons de contrôler ce comportement en limitant le débit, c'est-à-dire le nombre de requêtes envoyées par seconde. Par exemple, dans une file d'attente de tâches App Engine, vous pouvez contrôler la fréquence à laquelle les tâches sont envoyées.

Inversement, App Engine réduit le nombre d'instances lorsque le volume des requêtes diminue. Ce scaling garantit que toutes les instances actuelles de l'application sont exploitées de manière à optimiser l'efficacité et la rentabilité.

Lorsqu'une application n'est pas utilisée du tout, App Engine désactive les instances dynamiques associées, mais les recharge immédiatement dès que cela s'avère nécessaire. Le rechargement des instances peut engendrer des requêtes de chargement et une latence supplémentaire pour les utilisateurs.

Vous pouvez spécifier un nombre minimal d'instances inactives. La définition d'un nombre approprié d'instances inactives pour votre application en fonction du volume des requêtes permet à cette dernière de diffuser chaque requête avec une latence faible, à moins que vous ne soyez confronté à un volume de requêtes anormalement élevé.

Scaling des instances

Lorsque vous transférez une version d'un service, le fichier app.yaml spécifie un type de scaling et une classe d'instance qui s'appliquent à chaque instance de cette version. Le type de scaling contrôle la manière dont les instances sont créées. La classe d'instance détermine les ressources de calcul (taille de la mémoire et vitesse du processeur) ainsi que leur tarification. Il existe trois types de scaling : manuel, de base et automatique. Les classes d'instance disponibles dépendent du type de scaling.

Scaling manuel
Un service avec scaling manuel utilise des instances résidentes qui exécutent en continu le nombre d'instances spécifié, quel que soit le niveau de charge. Cela facilite des tâches telles que des initialisations complexes et des applications qui dépendent de l'état de la mémoire au fil du temps.
Scaling automatique
Un service avec scaling automatique (autoscaling) utilise des instances dynamiques créées en fonction du taux de requêtes, de la latence des réponses et d'autres métriques de l'application. Toutefois, si vous spécifiez un nombre minimal d'instances inactives, ces dernières s'exécutent en tant qu'instances résidentes, tandis que les autres instances sont dynamiques.
Scaling de base
Un service avec scaling de base utilise des instances dynamiques. Chaque instance est créée lorsque l'application reçoit une requête et désactivée lorsque l'application devient inactive. Le scaling de base est idéal pour les tâches intermittentes ou liées à l'activité des utilisateurs.

Vous trouverez un comparatif des caractéristiques de performances des trois types de scaling dans le tableau ci-dessous :

Fonctionnalité Scaling automatique Scaling manuel Scaling de base
Délais Délai de 60 secondes pour les requêtes HTTP et de 10 minutes pour les tâches en file d'attente. L'exécution des requêtes peut prendre jusqu'à 24 heures. Une instance avec scaling manuel peut choisir de traiter /_ah/start et d'exécuter un programme ou un script pendant plusieurs heures sans renvoyer de code de réponse HTTP. L'exécution des tâches en file d'attente peut prendre jusqu'à 24 heures. Identique au scaling manuel.
Threads en arrière-plan Non autorisée Autorisée Autorisée
Résidence Les instances sont supprimées de la mémoire en fonction des schémas d'utilisation. Les instances restent en mémoire, et leur état est préservé entre les requêtes. Lorsque les instances redémarrent, une requête /_ah/stop apparaît dans les journaux. Si un hook d'arrêt est enregistré, il dispose de 30 secondes pour s'exécuter avant que l'arrêt ne se produise. Les instances sont supprimées en fonction du paramètre idle_timeout. Si une instance a été inactive (par exemple, elle n'a pas reçu de requête) pendant une durée supérieure à celle de idle_timeout, elle est supprimée.
Démarrage et arrêt Les instances sont créées à la demande pour la gestion des requêtes et désactivées automatiquement en cas d'inactivité. App Engine envoie automatiquement une requête de démarrage aux instances sous la forme d'une requête GET vide adressée à /_ah/start. Une instance qui est arrêtée manuellement dispose de 30 secondes pour terminer le traitement des requêtes avant d'être arrêtée de force. Les instances sont créées à la demande pour la gestion des requêtes et désactivées automatiquement en cas d'inactivité, en fonction du paramètre de configuration idle_timeout. Comme avec le scaling manuel, une instance qui est arrêtée manuellement dispose de 30 secondes pour terminer le traitement des requêtes avant d'être arrêtée de force.
Adressage des instances Les instances sont anonymes. L'instance "i" de la version "v" du service "s" est adressable via l'URL http://i.v.s.app_id.appspot.com. Si vous avez configuré un mappage de sous-domaines à l'aide de caractères génériques pour un domaine personnalisé, vous pouvez également adresser un service ou l'une de ses instances via une URL au format http://s.domain.com ou http://i.s.domain.com. Vous pouvez mettre l'état en cache dans chaque instance et le récupérer dans les requêtes ultérieures. Identique au scaling manuel.
Scaling App Engine adapte automatiquement le nombre d'instances en fonction du volume à traiter. Ce scaling tient compte des paramètres automatic_scaling fournis pour chaque version dans le fichier de configuration. Vous pouvez configurer le nombre d'instances de chaque version dans le fichier de configuration du service. Le nombre d'instances correspond généralement à la taille d'un ensemble de données en mémoire ou au débit souhaité pour un travail hors connexion. Vous pouvez ajuster très rapidement le nombre d'instances d'une version avec scaling manuel, sans arrêter les instances en cours d'exécution, à l'aide de la fonction set_num_instances de l'API Modules. Vous pouvez configurer un service avec scaling de base en définissant le nombre maximal d'instances dans le paramètre max_instances de basic_scaling. Le nombre d'instances actives évolue en fonction du volume à traiter.
Quota gratuit d'utilisation quotidienne 28 heures d'utilisation de l'instance 8 heures d'utilisation de l'instance 8 heures d'utilisation de l'instance

Cycle de vie des instances

États des instances

Une instance d'un service avec autoscaling est toujours en cours d'exécution. En revanche, une instance d'un service avec scaling manuel ou de base peut être en cours d'exécution ou arrêtée. Toutes les instances du même service et de la même version partagent le même état. Vous pouvez modifier l'état de vos instances en arrêtant vos versions par le biais de la page Versions de la console GCP, ainsi que des commandes gcloud app versions start et gcloud app versions stop ou de l'API Modules.

Démarrage

Chaque instance de service est créée en réponse à une requête de démarrage, qui correspond à une requête HTTP GET vide adressée à /_ah/start. App Engine envoie cette requête pour créer une instance. Les utilisateurs ne peuvent pas envoyer de requête à /_ah/start. Les instances avec scaling manuel et de base doivent répondre à la requête de démarrage pour pouvoir traiter toute autre requête. La requête de démarrage peut être utilisée à deux fins :

  • Pour démarrer un programme qui fonctionne indéfiniment, sans accepter d'autres requêtes
  • Pour initialiser une instance avant que le trafic augmente

Les instances avec scaling manuel, de base et automatique ne démarrent pas de la même façon. Lorsque vous démarrez une instance avec scaling manuel, App Engine envoie immédiatement une requête /_ah/start à chaque instance. Lorsque vous démarrez une instance d'un service avec scaling de base, App Engine l'autorise à accepter le trafic. Toutefois, la requête /_ah/start n'est envoyée à aucune instance tant que le service App Engine n'a pas reçu sa première requête d'utilisateur. Plusieurs instances avec scaling de base ne démarrent que si cela s'avère nécessaire pour faire face à l'augmentation du trafic. Les instances avec scaling automatique ne reçoivent pas de requête /_ah/start.

Si une instance répond à la requête /_ah/start avec le code d'état HTTP 200–299 ou 404, cela signifie qu'elle a bien démarré et qu'elle peut traiter des requêtes supplémentaires. Sinon, App Engine arrête l'instance. Les instances avec scaling manuel redémarrent immédiatement, tandis que les instances avec scaling de base ne redémarrent que si nécessaire pour diffuser le trafic.

Arrêt

Le processus d'arrêt peut être déclenché par différents événements planifiés et non planifiés, tels que les suivants :

  • Vous arrêtez manuellement une instance.
  • Vous déployez une version mise à jour sur le service.
  • L'instance dépasse la mémoire maximale pour sa classe instance_class configurée.
  • Votre application dépasse son quota d'heures d'utilisation de l'instance.
  • Votre instance est déplacée sur une autre machine, soit parce que la machine qui exécute actuellement l'instance redémarre, soit parce qu'App Engine a déplacé votre instance pour améliorer la distribution de la charge.
Une application peut déterminer si une instance avec scaling manuel est sur le point de s'arrêter de deux façons : soit la méthode is_shutting_down() de google.appengine.api.runtime commence à renvoyer true, soit vous pouvez enregistrer un hook d'arrêt, comme décrit ci-dessous (recommandé).

Quand App Engine lance l'arrêt d'une instance, les requêtes existantes disposent de 30 secondes pour s'exécuter, et les nouvelles requêtes renvoient immédiatement le code 404. Si une instance est en train de traiter une requête, App Engine met cette dernière en pause et exécute le hook d'arrêt. En l'absence de requête active, App Engine envoie une requête /_ah/stop, qui exécute le hook d'arrêt. La requête /_ah/stop contourne la logique de traitement normale et ne peut pas être gérée par un code utilisateur. Son seul but est d'appeler le hook d'arrêt. Si vous générez une exception dans votre hook d'arrêt au moment où vous traitez une autre requête, elle apparaîtra dans la requête, où vous pourrez l'intercepter.

Si vous avez activé les requêtes simultanées en spécifiant threadsafe: true dans app.yaml (valeur par défaut), la génération d'une exception à partir d'un hook d'arrêt permet de copier cette exception sur tous les threads. L'exemple de code ci-dessous illustre un hook d'arrêt de base :

from google.appengine.api import apiproxy_stub_map
from google.appengine.api import runtime

def my_shutdown_hook():
  apiproxy_stub_map.apiproxy.CancelApiCalls()
  save_state()
  # May want to raise an exception

runtime.set_shutdown_hook(my_shutdown_hook)

L'exemple suivant illustre la procédure d'utilisation de la méthode is_shutting_down() :

while more_work_to_do and not runtime.is_shutting_down():
  do_some_work()
  save_state()

Requêtes de chargement

Lorsque le service App Engine crée une instance pour votre application, l'instance doit d'abord charger les bibliothèques et les ressources requises pour gérer la requête. Cela se produit lorsque l'instance reçoit sa première requête, appelée requête de chargement. Dans le cadre de ce type de requête, l'application fait l'objet d'une initialisation, raison pour laquelle la requête prend plus de temps.

Suivez ces bonnes pratiques pour réduire la durée des requêtes de chargement :

  • Chargez seulement le code nécessaire au démarrage.
  • Accédez le moins possible au disque.
  • Dans certains cas, le chargement du code à partir d'un fichier zip ou jar est plus rapide que le chargement à partir de plusieurs fichiers distincts.

Requêtes de préchauffage

Les requêtes de préchauffage constituent un type particulier de requêtes de chargement qui chargent préalablement un code d'application dans une instance, avant l'émission de requêtes en temps réel. Les instances avec scaling manuel ou de base ne reçoivent pas de requête /_ah/warmup.

Pour en savoir plus sur l'utilisation des requêtes de préchauffage, consultez la page Configurer des requêtes de préchauffage.

Disponibilité de l'instance

App Engine tente d'exécuter indéfiniment les instances avec scaling manuel et de base. Toutefois, la disponibilité de ces instances n'est pas garantie pour le moment. Des pannes matérielles et logicielles à l'origine d'arrêts anticipés ou de redémarrages fréquents risquent de se produire sans avertissement. Par ailleurs, leur résolution peut prendre beaucoup de temps. Vous devez donc configurer votre application de sorte qu'elle tolère ces pannes.

Voici quelques stratégies efficaces pour éviter les temps d'arrêt dus aux redémarrages des instances :

  • Réduisez le temps nécessaire au redémarrage des instances existantes ou au démarrage des nouvelles instances.
  • Pour les calculs à exécution longue, créez régulièrement des points de contrôle afin de pouvoir reprendre l'activité à partir de ces derniers.
  • Votre application doit être "sans état" pour que rien ne soit stocké sur l'instance.
  • Utilisez des files d'attente pour l'exécution des tâches asynchrones.
  • Si vous configurez vos instances pour le scaling manuel , procédez comme suit :
    • Utilisez l'équilibrage de charge sur plusieurs instances.
    • Configurez plus d'instances que nécessaire pour gérer le trafic normal.
    • Écrivez une logique de remplacement qui se sert des résultats mis en cache lorsqu'une instance avec scaling manuel n'est pas disponible.

Facturation des instances

En général, les instances sont facturées à la minute en fonction de leur disponibilité. Des frais de démarrage de 15 minutes sont également appliqués (pour en savoir plus, consultez la page Tarifs). Les instances inactives ne vous sont facturées que dans la limite du nombre maximal d'instances inactives que vous avez défini pour chaque service. Le temps d'exécution est décompté en fonction de la mémoire de l'instance. Il est plus élevé pour les applications Java que pour les applications Python.

La facturation des instances résidentes est légèrement différente de celle des instances dynamiques :

  • Pour les instances résidentes, la facturation se termine 15 minutes après l'arrêt de l'instance.
  • Pour les instances dynamiques, la facturation se termine 15 minutes après la fin du traitement de la dernière requête.
Cette page vous a-t-elle été utile ? Évaluez-la :

Envoyer des commentaires concernant…

Environnement standard App Engine pour Python