Entorno de ejecución de Cloud Functions
Cloud Run Functions se ejecuta en un entorno sin servidores y completamente administrado en el que Google administra la infraestructura, los sistemas operativos y los entornos de ejecución. Cada función se ejecuta en un contexto propio, seguro y aislado, se escala automáticamente y cuenta con un ciclo de vida independiente de otras funciones.
Entornos de ejecución
Cloud Run Functions admite varios entornos de ejecución de lenguajes. Cada uno incluye un conjunto estándar de paquetes de sistemas, así como las herramientas y bibliotecas necesarias para ese lenguaje. Necesitarás el valor del ID del entorno de ejecución si implementas funciones desde la línea de comandos o con Terraform.
Las actualizaciones de seguridad y mantenimiento están disponibles para todos los entornos de ejecución de 1ª y 2ª gen. Estas actualizaciones se aplican de forma automática o manual según el entorno y su configuración. Para obtener más información sobre las actualizaciones del entorno de ejecución, consulta Protege tu función de Cloud Run.
Node.js
Python
| Entorno de ejecución | Generación | Entorno | ID del entorno de ejecución | Imagen del entorno de ejecución |
|---|---|---|---|---|
| Python 3.13 | 2ª gen. | Ubuntu 22.04 | python313 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/python313 |
| Python 3.12 | 1ª y 2ª gen. | Ubuntu 22.04 | python312 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/python312 |
| Python 3.11 | 1ª y 2ª gen. | Ubuntu 22.04 | python311 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/python311 |
| Python 3.10 | 1ª y 2ª gen. | Ubuntu 22.04 | python310 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/python310 |
| Python 3.9 | 1ª y 2ª gen. | Ubuntu 18.04 | python39 | us-central1-docker.pkg.dev/serverless-runtimes/google-18-full/runtimes/python39 |
| Python 3.8 | 1ª y 2ª gen. | Ubuntu 18.04 | python38 | us-central1-docker.pkg.dev/serverless-runtimes/google-18-full/runtimes/python38 |
| Python 3.7 | 1ª gen. | Ubuntu 18.04 | python37 | us-central1-docker.pkg.dev/serverless-runtimes/google-18-full/runtimes/python37 |
Go
Java
| Entorno de ejecución | Generación | Entorno | ID del entorno de ejecución | Imagen del entorno de ejecución |
|---|---|---|---|---|
| Java 25 (versión preliminar) |
2ª gen. | Ubuntu 24.04 | java25 | us-central1-docker.pkg.dev/serverless-runtimes/google-24-full/runtimes/java25 |
| Java 21 | 2ª gen. | Ubuntu 22.04 | java21 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/java21 |
| Java 17 | 1ª y 2ª gen. | Ubuntu 22.04 | java17 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/java17 |
| Java 11 | 1ª y 2ª gen. | Ubuntu 18.04 | java11 | us-central1-docker.pkg.dev/serverless-runtimes/google-18-full/runtimes/java11 |
Ruby
| Entorno de ejecución | Generación | Entorno | ID del entorno de ejecución | Imagen del entorno de ejecución |
|---|---|---|---|---|
| Ruby 3.4 | 2ª gen. | Ubuntu 22.04 | ruby34 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/ruby34 |
| Ruby 3.3 | 1ª y 2ª gen. | Ubuntu 22.04 | ruby33 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/ruby33 |
| Ruby 3.2 | 1ª y 2ª gen. | Ubuntu 22.04 | ruby32 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/ruby32 |
| Ruby 3.0 | 1ª y 2ª gen. | Ubuntu 18.04 | ruby30 | us-central1-docker.pkg.dev/serverless-runtimes/google-18-full/runtimes/ruby30 |
| Ruby 2.7 | 1ª y 2ª gen. | Ubuntu 18.04 | ruby27 | us-central1-docker.pkg.dev/serverless-runtimes/google-18-full/runtimes/ruby27 |
| Ruby 2.6 | 1ª y 2ª gen. | Ubuntu 18.04 | ruby26 | us-central1-docker.pkg.dev/serverless-runtimes/google-18-full/runtimes/ruby26 |
PHP
| Entorno de ejecución | Entorno | Generación | ID del entorno de ejecución | Imagen del entorno de ejecución |
|---|---|---|---|---|
| PHP 8.4 | 2ª gen. | Ubuntu 22.04 | php84 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/php84 |
| PHP 8.3 | 2ª gen. | Ubuntu 22.04 | php83 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/php83 |
| PHP 8.2 | 1ª y 2ª gen. | Ubuntu 22.04 | php82 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/php82 |
| PHP 8.1 | 1ª y 2ª gen. | Ubuntu 18.04 | php81 | us-central1-docker.pkg.dev/serverless-runtimes/google-18-full/runtimes/php81 |
| PHP 7.4 | 1ª y 2ª gen. | Ubuntu 18.04 | php74 | us-central1-docker.pkg.dev/serverless-runtimes/google-18-full/runtimes/php74 |
.NET Core
| Entorno de ejecución | Generación | Entorno | ID del entorno de ejecución | Imagen del entorno de ejecución |
|---|---|---|---|---|
| .NET Core 8 | 2ª gen. | Ubuntu 22.04 | dotnet8 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/dotnet8 |
| .NET Core 6 | 1ª y 2ª gen. | Ubuntu 22.04 | dotnet6 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/dotnet6 |
| .NET Core 3 | 1ª y 2ª gen. | Ubuntu 18.04 | dotnet3 | us-central1-docker.pkg.dev/serverless-runtimes/google-18-full/runtimes/dotnet3 |
Comportamiento del escalado automático
Cloud Run Functions implementa el paradigma sin servidores, en el que solo ejecutas el código sin tener que preocuparte por la infraestructura subyacente, como los servidores o las máquinas virtuales. Una vez implementadas, las funciones se administran y escalan automáticamente.
Cloud Run Functions administra las solicitudes entrantes asignándolas a las instancias de tu función. Según el volumen de solicitudes, así como la cantidad de instancias de funciones existentes, Cloud Run Functions puede asignar una solicitud a una instancia existente o crear una nueva.
En los casos en que el volumen de solicitudes entrantes exceda la cantidad de instancias existentes, Cloud Run Functions puede iniciar varias instancias nuevas para administrarlas. Este comportamiento del escalado automático permite que Cloud Run Functions administre muchas solicitudes en paralelo, cada una con una instancia diferente de la función.
En algunos casos, no se recomienda el escalamiento ilimitado. Para solucionar esto, Cloud Run Functions permite establecer una cantidad máxima de instancias que pueden coexistir en un momento determinado para una función en particular.
Sin estado
Para habilitar la administración automática y el escalamiento de las funciones, estas deben ser sin estado. La invocación de una función no debe depender del estado de la memoria configurado por una invocación anterior. Las invocaciones pueden controlarse con diferentes instancias de funciones, que no comparten variables globales, memoria, sistemas de archivos ni otro estado.
Si necesitas compartir estados entre las invocaciones, la función debe usar un servicio como Memorystore, Datastore, Firestore o Cloud Storage para conservar los datos. Consulta las bases de datos deGoogle Cloud y los productos de almacenamiento deGoogle Cloud para obtener más información sobre las opciones de bases de datos y almacenamiento que proporciona Google Cloud.
Simultaneidad
Cloud Run Functions (2ª gen.)
Cloud Run Functions (2ª gen.) admite la administración de varias solicitudes simultáneas en una sola instancia de función. Esto puede ser útil para prevenir inicios en frío, ya que una instancia ya preparada puede procesar varias solicitudes de forma simultánea, lo que reduce la latencia general. Para obtener más información, consulta Simultaneidad.
Cloud Run Functions (1ª gen.)
En Cloud Run Functions (1ª gen.), cada instancia de una función administra solo una solicitud simultánea a la vez. Esto significa que mientras tu código procesa una solicitud, no hay posibilidad de que una segunda solicitud se enrute a la misma instancia. Por lo tanto, la solicitud original puede usar la cantidad total de recursos (memoria y CPU) que asignes.
Dado que diferentes instancias de funciones procesan solicitudes simultáneas en Cloud Run Functions (1ª gen.), no comparten variables ni memoria local. Consulta Sin estado y Vida útil de las instancias de funciones para obtener más información.
Inicios en frío
Una instancia de función nueva se inicia en dos casos:
Cuando implementas la función.
Cuando una instancia de función nueva se crea automáticamente para escalarse verticalmente hasta la carga o, de manera ocasional, a fin de reemplazar una instancia existente.
Iniciar una instancia de función nueva implica cargar el entorno de ejecución y el código. Las solicitudes que incluyen el inicio de instancias de funciones, llamadas inicios en frío, pueden ser más lentas que las que se enrutan a instancias de funciones existentes. Sin embargo, si la función recibe una carga constante, la cantidad de inicios en frío suele ser insignificante, a menos que la función falle con frecuencia y requiera reiniciar el entorno de la función.
Si el código de la función genera una excepción no detectada o hace que falle el proceso actual, la instancia de función puede reiniciarse. Esto puede generar más inicios en frío, lo que da como resultado una latencia más alta, por lo que recomendamos capturar excepciones y, en lo posible, evitar la finalización del proceso actual.
Si la función es sensible a la latencia, considera establecer una cantidad mínima de instancias para evitar inicios en frío.
Vida útil de las instancias de funciones
Por lo general, las instancias de funciones son resilientes y se reutilizan en invocaciones de funciones posteriores, a menos que se reduzca verticalmente su escala debido a la falta de tráfico en curso o a la falla de la función. Esto significa que, cuando la ejecución de una función finaliza, la misma instancia de función puede controlar otra invocación.
Alcance de la función en comparación con el alcance global
La invocación de una sola función hace que se ejecute solo el cuerpo de la función declarada como el punto de entrada. El alcance global del código fuente de la función solo se ejecuta en inicios en frío y no en instancias que ya se inicializaron.
Node.js
Python
Go
Java
Ruby
Puedes usar variables globales con el objetivo de optimizar el rendimiento, pero no debes depender del estado establecido en el alcance global por invocaciones de funciones anteriores. Consulta Sin estado para obtener más información.
Puedes suponer que, para cada instancia de función, el alcance global se ejecutó solo una vez antes de que se invocara el código de la función. Sin embargo, no debes depender de la cantidad total de ejecuciones de alcance global ni de su tiempo, ya que pueden variar según la actividad del escalado automático.
Cronograma de ejecución de funciones
Las funciones tienen acceso a los recursos que tienen asignados (como la memoria y CPU) solo durante su período de ejecución. El código que se ejecuta fuera del período de ejecución no tiene garantía de ejecutarse y puede detenerse en cualquier momento. Por lo tanto, siempre debes indicar el final de la ejecución de la función de forma correcta y evitar ejecutar cualquier otro código. Consulta Funciones de HTTP, Funciones en segundo plano y Funciones de CloudEvent para obtener orientación.
La ejecución de la función también está sujeta al tiempo de espera de esta última. Consulta Tiempo de espera de las funciones para obtener más información.
Ten en cuenta el cronograma de ejecución cuando inicialices la aplicación. Las tareas en segundo plano no deben crearse en alcance global durante la inicialización, ya que se ejecutarían fuera de la duración de una solicitud.
Garantías de ejecución
Por lo general, las funciones se invocan una vez por cada evento entrante. Sin embargo, Cloud Run Functions no garantiza una sola invocación en todos los casos debido a las diferencias en las situaciones de error.
La cantidad máxima o mínima de veces que la función puede invocarse para un único evento depende del tipo de función:
Las funciones de HTTP se invocan una vez como máximo. Esto se debe al carácter síncrono de las llamadas HTTP, lo que implica que se mostrará cualquier error que ocurra durante la invocación de la función sin reintentos. Se espera que el emisor de una función de HTTP corrija los errores y vuelva a intentar el proceso si es necesario.
Las funciones basadas en eventos se invocan una vez como mínimo. Esto se debe al carácter asíncrono de los eventos, en los que no hay ningún emisor que espere por la respuesta. En extrañas circunstancias, el sistema podría invocar una función basada en eventos más de una vez para garantizar la entrega del evento. Si la invocación de una función basada en eventos falla con un error, no se invocará de nuevo, a menos que se habiliten los reintentos en caso de error para esa función.
Para asegurarte de que la función se comporte de forma correcta en los reintentos de ejecución, debes implementarla, lo que la vuelve idempotente y permite que se produzcan los resultados esperados (y sus efectos secundarios) incluso si un evento se entrega varias veces. En el caso de las funciones de HTTP, esto también implica mostrar el valor esperado incluso si el emisor vuelve a intentar las llamadas al extremo de la función de HTTP. Consulta Reintenta las funciones basadas en eventos para obtener más información sobre cómo hacer que la función se vuelva idempotente.
Memoria y sistema de archivos
Cada función tiene una cierta cantidad de memoria asignada para su uso, la cual se puede configurar durante la implementación. Consulta Configura la memoria para obtener más información.
El entorno de ejecución de la función incluye un sistema de archivos en la memoria que contiene los archivos de origen y los directorios implementados con la función (consulta Estructura el código fuente). El directorio que contiene los archivos de origen solo se puede leer, pero el resto del sistema de archivos se puede escribir (excepto los archivos que usa el sistema operativo). El uso del sistema de archivos se tiene en cuenta para el uso de memoria de una función.
La función puede interactuar con el sistema de archivos por medio de métodos estándar en cada lenguaje de programación.
Red
La función puede acceder al Internet público con métodos estándar en cada lenguaje de programación, ya sea a través de las bibliotecas integradas que ofrece el entorno de ejecución o de bibliotecas externas que incluyas como dependencias.
Intenta reutilizar las conexiones de red en las invocaciones de funciones. Sin embargo, ten en cuenta que el sistema podría cerrar una conexión que no se usa durante 10 minutos y que los intentos posteriores de usar una conexión cerrada podrían generar un error de “restablecimiento de la conexión”. El código debe usar una biblioteca que administre bien las conexiones cerradas o que lo haga de manera explícita si usa constructos de redes de nivel inferior.
Aislamiento de funciones
Cada función implementada se aísla del resto, incluso de aquellas implementadas desde el mismo archivo fuente. En particular, no comparten memoria, variables globales, sistemas de archivos ni otros estados.
Para compartir datos entre las funciones implementadas, puedes usar servicios como Memorystore, Datastore, Firestore o Cloud Storage. Como alternativa, puedes invocar una función desde otra con los activadores apropiados y pasando los datos necesarios. Por ejemplo, realiza una solicitud HTTP al extremo de una función de HTTP o publica un mensaje en un tema de Pub/Sub para activar una función de Pub/Sub.