Cette page explique comment migrer des environnements d'exécution Java de la première à la deuxième génération. Pour mettre à jour votre application de deuxième génération afin qu'elle utilise la dernière version compatible de Java, consultez la page Mettre à niveau une application existante.
Java 8 n'est plus compatible depuis le 31 janvier 2024. Vos applications Java 8 existantes continueront à fonctionner et à recevoir du trafic. Toutefois, App Engine peut bloquer le redéploiement des applications qui utilisent des environnements d'exécution après leur date de fin de compatibilité. Nous vous recommandons de migrer vers la dernière version compatible de Java en suivant les instructions de cette page.
La migration vers les environnements d'exécution Java de deuxième génération vous permet d'utiliser des fonctionnalités de langage à jour et de créer des applications plus portables, avec du code idiomatique.
Comprendre vos options de migration
Pour réduire la complexité et les efforts liés à la migration, l'environnement standard App Engine vous permet d'accéder à de nombreux services groupés et API anciens, tels que Memcache, dans les environnements d'exécution Java de deuxième génération. Votre application Java peut appeler les API de services groupés via le fichier JAR de l'API App Engine et accéder à la plupart des fonctionnalités de l'environnement d'exécution Java 8.
Vous avez également la possibilité d'utiliser des produits Google Cloud qui offrent des fonctionnalités similaires aux anciens services groupés. Ces produits Google Cloud fournissent des bibliothèques clientes Cloud pour Java idiomatiques. Pour les services groupés qui ne sont pas disponibles séparément dans Google Cloud, tels que le traitement d'image, la recherche et les messages, vous pouvez utiliser des fournisseurs tiers ou d'autres solutions.
Pour en savoir plus sur la migration vers des services non groupés, consultez la section Migrer à partir de services groupés.
La procédure d'exécution de l'environnement d'exécution diffère selon que vous choisissez ou non d'utiliser les anciens services groupés :
Migrer vers les environnements d'exécution Java de deuxième génération avec services groupés | Migrer vers les environnements d'exécution Java de deuxième génération sans services groupés |
---|---|
Accédez aux services groupés à l'aide du fichier JAR des API App Engine. | Vous pouvez éventuellement utiliser les produits Google Cloud ou les services tiers recommandés. |
Utilisez Vous devrez peut-être également configurer des fichiers YAML supplémentaires selon les fonctionnalités de votre application. |
Utilisez Vous devrez peut-être également configurer des fichiers YAML supplémentaires selon les fonctionnalités de votre application. |
Les applications sont déployées via Jetty. Utilisez le format WAR pour empaqueter votre application. | Les applications sont déployées à l'aide de votre propre serveur. Utilisez le format JAR pour empaqueter votre application. Pour en savoir plus sur la conversion de votre fichier WAR existant en fichier JAR exécutable, consultez la section Réempaqueter un fichier WAR. |
Présentation du processus de migration
Voici quelques modifications que vous devrez apporter à votre application App Engine Java 8 et votre processus de déploiement pour utiliser les environnements d'exécution Java de deuxième génération :
- Téléchargez Google Cloud CLI.
- Migrez le plug-in Maven App Engine autonome vers le plug-in Maven basé sur gcloud CLI ou le plug-in Gradle basé sur gcloud CLI.
- Installer le fichier JAR de l'API App Engine si vous utilisez les anciens services groupés
Principales différences entre les environnements d'exécution Java 8 et Java de deuxième génération
Voici un récapitulatif des différences entre les environnements d'exécution Java 8 et Java de deuxième génération dans l'environnement standard App Engine :
Environnement d'exécution Java 8 | Environnements d'exécution Java de deuxième génération | |
---|---|---|
Déploiement de serveur | Serveur déployé pour vous à l'aide de Jetty | Si votre application n'utilise pas les anciens services groupés, vous devez déployer un serveur vous-même1. |
Anciens services groupés App Engine | Fourni | Fourni |
Utiliser les bibliothèques clientes Cloud pour Java | Oui | Oui |
Extensions de langages et compatibilité avec la bibliothèque système | Oui | Oui |
Accès au réseau externe | Oui | Oui |
Accès au système de fichiers | Accès en lecture/écriture à /tmp
|
Accès en lecture/écriture à /tmp
|
Environnement d'exécution du langage | Modifié pour App Engine | Environnement d'exécution Open Source non modifié |
Mécanisme d'isolation | Bac à sable de conteneur basé sur gVisor | Bac à sable de conteneur basé sur gVisor |
Tester avec un serveur de développement local | Compatible | Compatible |
Configuration de la sécurité des threads (thread safety) | Peut être spécifiée dans le fichier appengine-web.xml .
|
Ne peut pas être spécifiée dans les fichiers de configuration. Toutes les applications sont supposées être "thread-safe" (à thread sécurisé)3. |
Logging | Utilise un paramètre java.util.logging. ConsoleHandler , qui écrit dans stderr et vide le flux après chaque enregistrement. |
Cloud Logging standard2 |
Compatibilité avec le plug-in DataNucleus 2.x | Compatible | Non compatible 4 |
Remarques :
Si votre application n'utilise pas les anciens services groupés, les environnements d'exécution Java de deuxième génération peuvent exécuter n'importe quel framework Java tant que vous empaquetez un serveur Web configuré pour répondre aux requêtes HTTP sur le port spécifié par la variable d'environnement
PORT
(recommandée) ou sur le port 8080. Par exemple, les environnements d'exécution Java de deuxième génération peuvent exécuter un fichier JAR Spring Boot Uber tel quel. Pour plus d'exemples, consultez la section Flexibilité du framework.Si votre application utilise les anciens services groupés, App Engine la déploie à l'aide de Jetty de la même manière que dans l'environnement d'exécution Java 8.
La journalisation dans les environnements d'exécution Java de deuxième génération suit la norme de journalisation de Cloud Logging. Dans les environnements d'exécution Java de deuxième génération, les journaux d'applications ne sont plus groupés avec les journaux de requêtes, mais sont séparés dans des enregistrements différents. Pour en savoir plus sur la lecture et l'écriture de journaux dans les environnements d'exécution Java de deuxième génération, consultez le guide de journalisation.
Pour configurer une application non thread-safe dans l'environnement d'exécution Java de deuxième génération, de la même manière qu'avec la définition de
<threadsafe>false</threadsafe>
dans Java 8, définissez la simultanéité maximale sur 1 dans votre fichierapp.yaml
, ou dans le fichierappengine-web.xml
si vous utilisez les anciens services groupés.Google ne prend pas en charge la bibliothèque DataNucleus dans les environnements d'exécution de deuxième génération. Les versions plus récentes de DataNucleus présentent une incompatibilité ascendante avec les versions utilisées dans Java 8. Pour accéder à Datastore, nous vous recommandons d'utiliser la bibliothèque cliente en mode Datastore ou la solution Java Objectify (version 6 ou ultérieure). Objectify est une API Open Source pour Datastore qui fournit un niveau d'abstraction plus élevé.
Différences d'utilisation de la mémoire
Les environnements d'exécution de deuxième génération présentent une utilisation de référence de la mémoire plus élevée que les environnements d'exécution de première génération. Cela est dû à plusieurs facteurs, tels que les différentes versions d'image de base et les différences dans la manière dont les deux générations calculent l'utilisation de la mémoire.
Dans les environnements d'exécution de deuxième génération, l'utilisation de la mémoire des instances est calculée comme la somme de la mémoire utilisée par un processus d'application et du nombre de fichiers d'application mis en cache de manière dynamique en mémoire. Pour éviter que les applications qui utilisent beaucoup de mémoire ne provoquent des arrêts d'instance en raison du dépassement des limites de mémoire, effectuez une mise à niveau vers une classe d'instance plus grande avec plus de mémoire.
Différences d'utilisation du processeur
Les environnements d'exécution de deuxième génération peuvent constater une utilisation de référence plus élevée lors du démarrage à froid de l'instance. Selon la configuration du scaling d'une application, cela peut avoir des effets secondaires inattendus, tels qu'un nombre d'instances plus élevé que prévu si une application est configurée pour évoluer en fonction de l'utilisation du processeur. Pour éviter ce problème, examinez et testez les configurations de scaling des applications pour vous assurer que le nombre d'instances est acceptable.
Différences au niveau des en-têtes de requête
Les environnements d'exécution de première génération permettent de transmettre à l'application des en-têtes de requêtes comportant des traits de soulignement (par exemple, X-Test-Foo_bar
). Les environnements d'exécution de deuxième génération introduisent Nginx dans l'architecture hôte. Suite à cette modification, les environnements d'exécution de deuxième génération sont configurés pour supprimer automatiquement les en-têtes comportant des traits de soulignement (_
). Pour éviter les problèmes liés à l'application, évitez d'utiliser des traits de soulignement dans les en-têtes de requête de l'application.
Souplesse du framework
Les environnements d'exécution Java de deuxième génération n'incluent aucun framework de diffusion Web, sauf si vous utilisez les anciens services groupés. Cela signifie que vous pouvez utiliser un framework autre qu'un framework basé sur un servlet. Si vous utilisez les anciens services groupés, les environnements d'exécution Java de deuxième génération fournissent le framework de diffusion Web Jetty.
Le dépôt Google Cloud GitHub contient des exemples hello world
utilisant des frameworks Web Java populaires :
Migrer des fichiers XML vers le format YAML
gcloud CLI n'accepte pas les formats de fichier suivants :
cron.xml
datastore-index.xml
dispatch.xml
queue.xml
Les exemples suivants montrent comment migrer vos fichiers xml
vers des fichiers yaml
.
Migrer automatiquement des fichiers
Pour migrer vos fichiers xml
automatiquement :
Vous devez disposer de gcloud CLI en version 226.0.0 ou ultérieure. Pour effectuer la mise à jour vers la dernière version :
gcloud components update
Pour chaque fichier que vous souhaitez migrer, spécifiez l'une des sous-commandes suivantes (
cron-xml-to-yaml
,datastore-indexes-xml-to-yaml
,dispatch-xml-to-yaml
,queue-xml-to-yaml
) et le nom du fichier :gcloud beta app migrate-config queue-xml-to-yaml MY-QUEUE-XML-FILE.xml
Revérifiez manuellement le fichier converti avant de le déployer en production.
Pour voir un exemple de conversion réussie de fichier
xml
enyaml
, consultez les onglets de la section Migrer manuellement des fichiers.
Migrer manuellement des fichiers
Pour migrer manuellement des fichiers xml
vers le format yaml
:
cron.yaml
Créez un fichier cron.yaml
avec un objet cron
contenant une liste d'objets, chacun avec des champs correspondant à chacun des attributs de tag <cron>
de votre fichier cron.xml
, comme indiqué ci-dessous.
Fichier cron.yaml
converti :
cron:
- url: '/recache'
schedule: 'every 2 minutes'
description: 'Repopulate the cache every 2 minutes'
- url: '/weeklyreport'
schedule: 'every monday 08:30'
target: 'version-2'
timezone: 'America/New_York'
description: 'Mail out a weekly report'
Fichier cron.xml
d'origine :
<?xml version="1.0" encoding="UTF-8"?>
<cronentries>
<cron>
<url>/recache</url>
<description>Repopulate the cache every 2 minutes</description>
<schedule>every 2 minutes</schedule>
</cron>
<cron>
<url>/weeklyreport</url>
<description>Mail out a weekly report</description>
<schedule>every monday 08:30</schedule>
<timezone>America/New_York</timezone>
<target>version-2</target>
</cron>
</cronentries>
Pour plus d'informations, consultez la documentation de référence de cron.yaml
.
dispatch.yaml
Créez un fichier dispatch.yaml
avec un objet dispatch
contenant une liste d'objets, chacun avec des champs correspondant à chacun des attributs de tag <dispatch>
de votre fichier dispatch.xml
, comme indiqué ci-dessous.
Fichier dispatch.yaml
converti :
dispatch:
- url: '*/favicon.ico'
module: default
- url: 'simple-sample.uc.r.appspot.com/'
module: default
- url: '*/mobile/*'
module: mobile-frontend
Fichier dispatch.xml
d'origine
<?xml version="1.0" encoding="UTF-8"?>
<dispatch-entries>
<dispatch>
<url>*/favicon.ico</url>
<module>default</module>
</dispatch>
<dispatch>
<url>simple-sample.uc.r.appspot.com/</url>
<module>default</module>
</dispatch>
<dispatch>
<url>*/mobile/*</url>
<module>mobile-frontend</module>
</dispatch>
</dispatch-entries>
Pour plus d'informations, consultez la documentation de référence de dispatch.yaml
.
index.yaml
Créez un fichier index.yaml
avec un objet indexes
contenant une liste d'objets, chacun avec des champs correspondant à chacun des attributs de tag <datastore-index>
de votre fichier datastore-indexes.xml
, comme indiqué ci-dessous.
Fichier index.yaml
converti :
indexes:
- ancestor: false
kind: Employee
properties:
- direction: asc
name: lastName
- direction: desc
name: hireDate
- ancestor: false
kind: Project
properties:
- direction: asc
name: dueDate
- direction: desc
name: cost
Fichier datastore-index.xml
d'origine :
<?xml version="1.0" encoding="utf-8"?>
<datastore-indexes
autoGenerate="true">
<datastore-index kind="Employee" ancestor="false">
<property name="lastName" direction="asc" />
<property name="hireDate" direction="desc" />
</datastore-index>
<datastore-index kind="Project" ancestor="false">
<property name="dueDate" direction="asc" />
<property name="cost" direction="desc" />
</datastore-index>
</datastore-indexes>
Pour plus d'informations, consultez la documentation de référence de index.yaml
.
queue.yaml
Créez un fichier queue.yaml
avec un objet queue
contenant une liste d'objets, chacun avec des champs correspondant à chacun des attributs de tag <queue>
de votre fichier queue.xml
, comme indiqué ci-dessous.
Fichier queue.yaml
converti :
queue:
- name: fooqueue
mode: push
rate: 1/s
retry_parameters:
task_retry_limit: 7
task_age_limit: 2d
- name: barqueue
mode: push
rate: 1/s
retry_parameters:
min_backoff_seconds: 10
max_backoff_seconds: 200
max_doublings: 0
Fichier queue.xml
d'origine :
<queue-entries>
<queue>
<name>fooqueue</name>
<rate>1/s</rate>
<retry-parameters>
<task-retry-limit>7</task-retry-limit>
<task-age-limit>2d</task-age-limit>
</retry-parameters>
</queue>
<queue>
<name>barqueue</name>
<rate>1/s</rate>
<retry-parameters>
<min-backoff-seconds>10</min-backoff-seconds>
<max-backoff-seconds>200</max-backoff-seconds>
<max-doublings>0</max-doublings>
</retry-parameters>
</queue>
<queue-entries>