Diferencias entre Go 1.11 y Go 1.12+

La migración al entorno de ejecución de Go 1.12+ te permite usar funciones de lenguaje actualizadas y compilar apps que sean más portátiles, con código idiomático.

Cambios en el entorno de ejecución de Go 1.12+ en App Engine

Si estás considerando una migración al entorno de ejecución de Go 1.12+, debes tener en cuenta las siguientes diferencias entre Go 1.12 y entornos de ejecución anteriores en el entorno estándar de App Engine:

  • Para reducir el esfuerzo y la complejidad del proceso de 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 heredados y API de App Engine en el entorno de ejecución de Go 1.12+, como Memcache. Tu app de Go 1.12 o versiones posteriores puede llamar a las API de servicios agrupados en paquetes a través del SDK de App Engine para Go y acceder a la misma funcionalidad 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 Go 1.12 o versiones posteriores sigue el estándar de registro en Cloud Logging. En el entorno de ejecución de Go 1.12 o versiones posteriores, los registros de la app ya no se agrupan con los registros de solicitudes, pero están separados en registros diferentes. Para obtener más información sobre cómo leer y escribir registros en el entorno de ejecución de Go 1.12+, 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 Aplicable solo a Go 1.12 y versiones posteriores Debe configurarse como true si deseas acceder a los servicios agrupados en paquetes heredados de Go 1.12+.
login Compatible si app_engine_apis es true Si no usas los servicios agrupados en paquetes heredados para Go 1.12+, usa estos métodos alternativos para autenticar usuarios.
runtime Modificado Cambia el elemento runtime para especificar Go 1.12 o versiones posteriores.

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.