Migrer de Go 1.11 vers le dernier environnement d'exécution Go

Cette page explique comment migrer des environnements d'exécution Go 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 Go, consultez la page Mettre à niveau une application existante.

Go 1.11 n'est plus compatible à partir du 30 janvier 2024. Vos applications Go 1.11 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 Go en suivant les instructions de cette page.

La migration vers un environnement d'exécution Go de deuxième génération compatible vous permet d'utiliser des fonctionnalités de langage à jour et de créer des applications plus portables, avec du code idiomatique.

Modifications apportées aux environnements d'exécution de deuxième génération

Tenez compte des différences suivantes lors de la mise à niveau vers un environnement d'exécution Go de deuxième génération compatible :

  • Pour réduire la complexité et les efforts liés à la migration, l'environnement standard App Engine vous permet d'accéder à de nombreux anciens services et API groupés dans les environnements d'exécution de deuxième génération, tels que Memcache. Votre application Go de deuxième génération peut appeler les API de services groupés à l'aide du SDK App Engine pour Go et accéder à la plupart des fonctionnalités de l'environnement d'exécution Go 1.11.

    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 idiomatiques pour Go. 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 faire appel à des fournisseurs tiers ou à d'autres solutions.

    Pour en savoir plus sur la migration vers des services non groupés, consultez la page Effectuer la migration à partir de services groupés.

  • Le comportement de certains éléments du fichier de configuration app.yaml a été modifié. Pour en savoir plus, consultez la section Modifications apportées au fichier app.yaml.

  • La journalisation dans l'environnement d'exécution de deuxième génération suit la norme de journalisation dans Cloud Logging. Dans les environnements d'exécution 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 de deuxième génération, consultez le guide de journalisation.

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.

Modifications apportées au fichier app.yaml

Le comportement de certains éléments du fichier de configuration app.yaml a été modifié :

Élément Type de modification Description
app_engine_apis Obligatoire pour les applications utilisant d'anciens services groupés Doit être défini sur true si vous souhaitez accéder aux anciens services groupés pour les environnements d'exécution de deuxième génération.
login Compatible si app_engine_apis est true Si vous n'utilisez pas les anciens services groupés pour les environnements d'exécution de deuxième génération, appliquez d' autres méthodes d'authentification des utilisateurs.
runtime Modifié Modifiez l'élément runtime pour spécifier un environnement d'exécution de deuxième génération.

Pour en savoir plus, consultez la documentation de référence sur app.yaml.

Créer un package main

Votre service doit inclure une instruction package main dans au moins l'un des fichiers sources. S'il utilise le package google.golang.org/appengine, il doit inclure un appel à appengine.Main().

Écrire un package "main"

Si votre service ne contient pas encore de package main, ajoutez l'instruction package main et rédigez une fonction main(). La fonction main() doit au minimum :

  • lire la variable d'environnement PORT et appeler la fonction http.ListenAndServe() :

    port := os.Getenv("PORT")
    if port == "" {
    	port = "8080"
    	log.Printf("Defaulting to port %s", port)
    }
    
    log.Printf("Listening on port %s", port)
    if err := http.ListenAndServe(":"+port, nil); err != nil {
    	log.Fatal(err)
    }

Enregistrer les gestionnaires HTTP

Vous pouvez enregistrer vos gestionnaires HTTP en choisissant une des options suivantes :

  • La méthode privilégiée consiste à déplacer manuellement tous les appels http.HandleFunc() de vos packages vers la fonction main() de votre package main.
  • Vous pouvez également importer les packages de l'application dans votre package main, en veillant à ce que chaque fonction init() contenant des appels adressés à http.HandleFunc() s'exécute au démarrage.

    Vous pouvez trouver tous les packages qui utilisent l'appel http.HandleFunc() à l'aide du script bash suivant, puis copier le résultat dans le bloc import de votre package main :

    gp=$(go env GOPATH) && p=$(pwd) && pkg=${p#"$gp/src/"} && find . -name "*.go" | xargs grep "http.HandleFunc" --files-with-matches | grep -v vendor/ | grep -v '/main.go' | sed "s#\./\(.*\)/[^/]\+\.go#\t_ \"$pkg/\1\"#" | sort | uniq
    

Structurer les fichiers

Go exige que chaque package dispose de son propre répertoire. Vous pouvez indiquer à App Engine où se trouve votre package main en utilisant main: dans le fichier app.yaml de votre projet. Par exemple, si votre application possédait la structure de fichiers suivante :

myapp/
├── app.yaml
├── foo.go
├── bar.go
└── web/
    └── main.go

Votre fichier app.yaml contiendrait :

main: ./web # Relative filepath to the directory containing your main package.

Pour plus d'informations sur l'option main, consultez la documentation de référence sur app.yaml.

Déplacer des fichiers vers GOPATH

Localisez votre variable d'environnement GOPATH à l'aide de la commande suivante :

go env GOPATH

Déplacez tous les fichiers et importations pertinents vers GOPATH. Si vous utilisez des importations relatives, telles que import ./guestbook, mettez-les à jour pour qu'elles utilisent le chemin complet : import github.com/example/myapp/guestbook.