Migra de Go 1.11 al entorno de ejecución de Go más reciente

En esta página, se abordan las instrucciones para migrar de los entornos de ejecución de Go de primera generación a la segunda. Si quieres actualizar tu app de segunda generación para usar la última versión compatible de Go, consulta Actualiza una aplicación existente.

Go 1.11 alcanzó el fin de la asistencia el 30 de enero de 2024. Las aplicaciones existentes de Go 1.11 seguirán ejecutándose y recibiendo tráfico. Sin embargo, App Engine podría bloquear la reimplementación de aplicaciones que usan entornos de ejecución después de la fecha de finalización de la asistencia. Te recomendamos que migres al entorno de ejecución compatible más reciente de Go usando los lineamientos de esta página.

La migración a un entorno de ejecución de Go de segunda generación compatible te permite usar funciones de lenguaje actualizadas y compilar apps que sean más portátiles, con código idiomático.

Cambios en los entornos de ejecución de segunda generación

Ten en cuenta las siguientes diferencias cuando actualices a un entorno de ejecución de Go de segunda generación compatible:

  • Para reducir el esfuerzo y la complejidad de la migración del entorno de ejecución, el entorno estándar de App Engine te permite acceder a muchos de los servicios agrupados en paquetes y APIs heredados en los entornos de ejecución de segunda generación, como Memcache. Tu app de Go de segunda generación puede llamar a las APIs de servicios agrupados en paquetes a través del SDK de App Engine para Go y acceder a las mismas funciones que en el entorno de ejecución de Go 1.11.

    También tienes la opción de usar productos de Google Cloud que ofrecen funciones similares a las de los servicios agrupados en paquetes heredados. Estos productos de Google Cloud proporcionan bibliotecas cliente de Cloud para Go. Para los servicios en paquetes que no están disponibles como productos separados en Google Cloud, como procesamiento de imágenes, búsqueda, y mensajería, puedes usar proveedores externos o alguna otra solución.

    Para obtener más información sobre la migración a servicios sin agrupar, consulta Migra desde servicios en paquetes.

  • Se modificó el comportamiento de algunos elementos del archivo de configuración app.yaml: Para obtener más información, consulta Cambios en el archivo app.yaml.

  • El registro en el entorno de ejecución de segunda generación sigue el estándar de registro en Cloud Logging. En el entorno de ejecución de segunda generación, los registros de la app ya no se empaquetan con los registros de solicitud, sino que están separados en registros diferentes. Para obtener más información sobre cómo leer y escribir registros en los entornos de ejecución de segunda generación, consulta la guía de registro.

Diferencias en el uso de memoria

Los entornos de ejecución de segunda generación ven un modelo de referencia de uso de memoria más alto en comparación con los entornos de ejecución de primera generación. Esto se debe a varios factores, como las diferentes versiones de imagen base, y las diferencias en la forma en que las dos generaciones calculan el uso de memoria.

Los entornos de ejecución de segunda generación calculan el uso de memoria de las instancias como la suma de lo que usa un proceso de la aplicación y la cantidad de archivos de la aplicación almacenados en caché de forma dinámica en la memoria. Para evitar que las aplicaciones con uso intensivo de memoria experimenten apagados de instancias debido a que se excedieron los límites de memoria, actualiza a una clase de instancia más grande con más memoria.

Diferencias en el uso de CPU

Los entornos de ejecución de segunda generación pueden ver un modelo de referencia de uso de CPU más alto cuando se inicia en frío en la instancia. Según la configuración de escalamiento de una aplicación, esto puede tener efectos secundarios no deseados, como un recuento de instancias más alto de lo previsto si una aplicación está configurada para escalar en función del uso de CPU. Para evitar este problema, revisa y prueba las configuraciones de escalamiento de la aplicación para asegurarte de que la cantidad de instancias sea aceptable.

Diferencias en el encabezado de la solicitud

Los entornos de ejecución de primera generación permiten que los encabezados de la solicitud con guiones bajos (p.ej., X-Test-Foo_bar) se reenvíen a la aplicación. Los entornos de ejecución de segunda generación ingresan Nginx en la arquitectura del host. Como resultado de este cambio, los entornos de ejecución de segunda generación están configurados para quitar de forma automática los encabezados con guiones bajos (_). Para evitar problemas con la aplicación, evita usar guiones bajos en los encabezados de la solicitud de la aplicación.

Cambios en el archivo app.yaml

Se modificó el comportamiento de algunos elementos del archivo de configuración app.yaml:

Elemento Tipo de cambio Descripción
app_engine_apis Obligatorio para las apps que usan servicios agrupados en paquetes heredados Debe configurarse como true si deseas acceder a los servicios agrupados en paquetes heredados para los entornos de ejecución de segunda generación.
login Compatible si app_engine_apis es true Si no usas los servicios agrupados en paquetes heredados para los entornos de ejecución de segunda generación, usa estos métodos alternativos para autenticar usuarios.
runtime Modificado Cambia el elemento runtime para especificar un entorno de ejecución de segunda generación.

Para obtener más información, consulta la referencia de app.yaml.

Crea un paquete main

Tu servicio debe incluir una declaración package main en al menos un archivo de origen. Como alternativa, si tu servicio usa el paquete google.golang.org/appengine, incluye una llamada a appengine.Main().

Escribe un paquete main

Si tu servicio aún no contiene un paquete main, agrega la declaración package main y escribe una función main(). Como mínimo, la función main() debe hacer lo siguiente:

  • Leer la variable de entorno PORT y llamar a la función 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)
    }

Registra tus controladores HTTP

Puedes registrar tus controladores HTTP si seleccionas una de las siguientes opciones:

  • El método preferido es mover de forma manual todas las llamadas http.HandleFunc() de tus paquetes a la función main() en tu paquete main.
  • Como alternativa, puedes importar los paquetes de tu aplicación al paquete main con el fin de asegurarte de que cada función init() que contiene llamadas a http.HandleFunc() se ejecute al inicio.

    Puedes encontrar todos los paquetes que usan la llamada http.HandleFunc() con la siguiente secuencia de comandos de bash y copia el resultado en el bloque import del paquete 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
    

Estructura tus archivos

Go requiere que cada paquete tenga su propio directorio. Puedes indicarle a App Engine dónde está tu paquete main mediante main: en el archivo app.yaml de tu proyecto. Por ejemplo, si la estructura de archivos de tu aplicación se ve así:

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

Tu archivo app.yaml tendría lo siguiente:

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

Para obtener más información sobre la marca main, consulta la referencia de app.yaml.

Mueve archivos a tu GOPATH

Encuentra tu GOPATH mediante el siguiente comando:

go env GOPATH

Mueve todos los archivos relevantes y las importaciones a tu GOPATH. Si usas importaciones relativas, como import ./guestbook, actualiza las importaciones para que usen la ruta completa: import github.com/example/myapp/guestbook.