Ambiente de execução do Cloud Functions
As funções do Cloud Run são executadas em um ambiente sem servidor totalmente gerenciado, no qual o Google processa infraestrutura, sistemas operacionais e ambientes de execução. Cada função é executada no próprio contexto de execução seguro e isolado, com dimensionamento automático e um ciclo de vida independente de outras funções.
Ambientes de execução
As funções do Cloud Run são compatíveis com ambientes de execução de várias linguagens. Cada um contém um conjunto padrão de pacotes do sistema, assim como as ferramentas e bibliotecas necessárias para essa linguagem. Você precisará do valor do ID do ambiente de execução se estiver implantando funções pela linha de comando, ou pelo Terraform.
Atualizações de segurança e manutenção são disponibilizadas para todos os ambientes de execução da 1a e 2a geração. Essas atualizações são aplicadas de forma automática ou manual, dependendo do ambiente e de como você o configurou. Para mais informações sobre atualizações do ambiente de execução, consulte Proteger as funções do Cloud Run.
Node.js
Ambiente de execução | Geração | Ambiente | ID do ambiente de execução | Imagem do ambiente de execução |
---|---|---|---|---|
Node.js 22 (somente visualização) | Segunda geração | Ubuntu 22.04 | nodejs22 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/nodejs22 |
Node.js 20 | 1a geração, 2a geração | Ubuntu 22.04 | nodejs20 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/nodejs20 |
Node.js 18 | 1a geração, 2a geração | Ubuntu 22.04 | nodejs18 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/nodejs18 |
Node.js 16 | 1a geração, 2a geração | Ubuntu 18.04 | nodejs16 | us-central1-docker.pkg.dev/serverless-runtimes/google-18-full/runtimes/nodejs16 |
Node.js 14 | 1a geração, 2a geração | Ubuntu 18.04 | nodejs14 | us-central1-docker.pkg.dev/serverless-runtimes/google-18-full/runtimes/nodejs14 |
Node.js 12 | 1a geração, 2a geração | Ubuntu 18.04 | nodejs12 | us-central1-docker.pkg.dev/serverless-runtimes/google-18-full/runtimes/nodejs12 |
Node.js 10 | 1a geração, 2a geração | Ubuntu 18.04 | nodejs10 | us-central1-docker.pkg.dev/serverless-runtimes/google-18-full/runtimes/nodejs10 |
Node.js 8 | 1a geração, 2a geração | Ubuntu 18.04 | nodejs8 | Desativado |
Node.js 6 | 1a geração, 2a geração | Ubuntu 18.04 | nodejs6 | Desativado |
Python
Ambiente de execução | Geração | Ambiente | ID do ambiente de execução | Imagem do ambiente de execução |
---|---|---|---|---|
Python 3.12 | 1a geração, 2a geração | Ubuntu 22.04 | python312 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/python312 |
Python 3.11 | 1a geração, 2a geração | Ubuntu 22.04 | python311 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/python311 |
Python 3.10 | 1a geração, 2a geração | Ubuntu 22.04 | python310 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/python310 |
Python 3.9 | 1a geração, 2a geração | Ubuntu 18.04 | python39 | us-central1-docker.pkg.dev/serverless-runtimes/google-18-full/runtimes/python39 |
Python 3.8 | 1a geração, 2a geração | Ubuntu 18.04 | python38 | us-central1-docker.pkg.dev/serverless-runtimes/google-18-full/runtimes/python38 |
Python 3.7 | 1ª geração | Ubuntu 18.04 | python37 | us-central1-docker.pkg.dev/serverless-runtimes/google-18-full/runtimes/python37 |
Go
Java
Ambiente de execução | Geração | Ambiente | ID do ambiente de execução | Imagem do ambiente de execução |
---|---|---|---|---|
Java 21 | Segunda geração | Ubuntu 22.04 | java21 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/java21 |
Java 17 | 1a geração, 2a geração | Ubuntu 22.04 | java17 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/java17 |
Java 11 | 1a geração, 2a geração | Ubuntu 18.04 | java11 | us-central1-docker.pkg.dev/serverless-runtimes/google-18-full/runtimes/java11 |
Ruby
Ambiente de execução | Geração | Ambiente | ID do ambiente de execução | Imagem do ambiente de execução |
---|---|---|---|---|
Ruby 3.3 | 1a geração, 2a geração | Ubuntu 22.04 | ruby33 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/ruby32 |
Ruby 3.2 | 1a geração, 2a geração | Ubuntu 22.04 | ruby32 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/ruby32 |
Ruby 3.0 | 1a geração, 2a geração | Ubuntu 18.04 | ruby30 | us-central1-docker.pkg.dev/serverless-runtimes/google-18-full/runtimes/ruby30 |
Ruby 2.7 | 1a geração, 2a geração | Ubuntu 18.04 | ruby27 | us-central1-docker.pkg.dev/serverless-runtimes/google-18-full/runtimes/ruby27 |
Ruby 2.6 | 1a geração, 2a geração | Ubuntu 18.04 | ruby26 | us-central1-docker.pkg.dev/serverless-runtimes/google-18-full/runtimes/ruby26 |
PHP
Ambiente de execução | Ambiente | Geração | ID do ambiente de execução | Imagem do ambiente de execução |
---|---|---|---|---|
PHP 8.3 | Segunda geração | Ubuntu 22.04 | php83 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/php83 |
PHP 8.2 | 1a geração, 2a geração | Ubuntu 22.04 | php82 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/php82 |
PHP 8.1 | 1a geração, 2a geração | Ubuntu 18.04 | php81 | us-central1-docker.pkg.dev/serverless-runtimes/google-18-full/runtimes/php81 |
PHP 7.4 | 1a geração, 2a geração | Ubuntu 18.04 | php74 | us-central1-docker.pkg.dev/serverless-runtimes/google-18-full/runtimes/php74 |
.NET Core
Ambiente de execução | Geração | Ambiente | ID do ambiente de execução | Imagem do ambiente de execução |
---|---|---|---|---|
.NET Core 8 | Segunda geração | Ubuntu 22.04 | dotnet8 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/dotnet8 |
.NET Core 6 | 1a geração, 2a geração | Ubuntu 22.04 | dotnet6 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/dotnet6 |
.NET Core 3 | 1a geração, 2a geração | Ubuntu 18.04 | dotnet3 | us-central1-docker.pkg.dev/serverless-runtimes/google-18-full/runtimes/dotnet3 |
Comportamento de escalonamento automático
As funções do Cloud Run implementam o paradigma sem servidor, onde você executa seu código sem se preocupar com a infraestrutura subjacente, como servidores e máquinas virtuais. Depois de implantadas, as funções são gerenciadas e escalonadas automaticamente.
As funções do Cloud Run lidam com as solicitações recebidas atribuindo-as a instances da sua função. Dependendo do volume de solicitações e do número de instâncias de função existentes, as funções do Cloud Run podem atribuir uma solicitação a uma instância existente ou criar uma nova.
Nos casos em que o volume de solicitações de entrada excede o número de instâncias existentes, as funções do Cloud Run podem iniciar várias novas instâncias para processar solicitações. Esse comportamento de escalonamento automático permite que as funções do Cloud Run lidem com muitas solicitações em paralelo, cada uma usando uma instância diferente da sua função.
Em alguns casos, o escalonamento ilimitado pode ser indesejável. Para resolver isso, as funções do Cloud Run permitem configurar um número máximo de instâncias que podem coexistir a qualquer momento para uma função específica.
Sem estado
Para permitir o gerenciamento automático e o escalonamento das funções, elas precisam ser sem estado. Uma invocação de função não pode depender do estado na memória definido por uma invocação anterior. As invocações podem ser processadas por instâncias de função diferentes, que não compartilham variáveis globais, memória, sistemas de arquivos ou outro estado.
Se você precisa compartilhar estados em invocações de função, sua função deve usar um serviço como Memorystore, Datastore, Firestore ou Cloud Storage para manter os dados. Consulte bancos de dados do Google Cloud e produtos de armazenamento do Google Cloud para ver mais informações sobre as opções de banco de dados e armazenamento fornecidas pelo Google Cloud.
Simultaneidade
Funções do Cloud Run (2ª geração)
As funções do Cloud Run (2ª geração) são compatíveis com o processamento de várias solicitações simultâneas em uma única instância de função. Isso pode ser útil para evitar inicializações a frio, já que uma instância já aquecida pode processar várias solicitações simultaneamente, reduzindo assim a latência geral. Para detalhes, consulte Simultaneidade.
Funções do Cloud Run (1ª geração)
Nas funções do Cloud Run (1ª geração), cada instância de uma função processa apenas uma solicitação simultânea por vez. Isso quer dizer que o código está processando uma solicitação. Não há possibilidade de uma segunda solicitação ser encaminhada para a mesma instância. Portanto, a solicitação original pode usar toda a quantidade de recursos (memória e CPU) alocados.
Como as solicitações simultâneas nas funções do Cloud Run (1ª geração) são processadas por instâncias de função diferentes, elas não compartilham variáveis nem memória local. Para mais informações, consulte Sem estado e Tempo de vida da instância de função.
Inicializações a frio
Uma nova instância de função é iniciada em dois casos:
Quando você implanta a função.
Quando uma nova instância de função é criada automaticamente para ser escalonada até a carga ou para substituir uma instância existente às vezes.
O início de uma nova instância de função envolve o carregamento do tempo de execução e do código. As solicitações que incluem inicialização de instância de função, denominadas inicializações a frio, podem ser mais lentas do que as solicitações roteadas para instâncias de função existentes. Porém, se a função receber carga constante, o número de partidas a frio normalmente será insignificante, a menos que a função falhe sempre e exija a reinicialização do ambiente de função.
Se o código de função gerar uma exceção não capturada ou travar o processo atual, a instância da função poderá ser reiniciada. Isso pode levar a mais inicializações a frio, resultando em maior latência. Portanto, recomendamos capturar exceções e evitar o encerramento do processo atual. Consulte Como relatar erros para uma discussão sobre como processar e informar erros nas funções do Cloud Run.
Se a função for sensível à latência, defina um número mínimo de instâncias para evitar inicializações a frio.
Vida útil da instância de função
As instâncias de função normalmente são resilientes e reutilizadas por invocações de função subsequentes, a menos que o número de instâncias esteja sendo reduzido devido à falta de tráfego contínuo ou à falha na função. Isso significa que quando uma execução de função termina, outra invocação pode ser manipulada pela mesma instância.
Escopo de função x escopo global
Uma única invocação de função resulta na execução apenas do corpo da função declarada como o ponto de entrada. O escopo global do código-fonte da função é executado apenas em inicializações a frio, e não em instâncias que já foram inicializadas.
Node.js
Python
Go
Java
Ruby
É possível usar variáveis globais como uma otimização de desempenho, mas não é possível depender do estado definido no escopo global por invocações de função anteriores. Consulte Sem estado para ver mais informações.
Suponha que, para cada instância de função, o escopo global tenha sido executado exatamente uma vez antes que o código de função seja invocado. No entanto, não dependa do número total nem do tempo das execuções de escopo global, já que elas podem variar dependendo da atividade de escalonamento automático.
Linha do tempo da execução da função
Uma função tem acesso aos recursos alocados (memória e CPU) apenas durante a execução da função. Não é garantido que o código seja executado fora do período de execução. Ele também pode ser interrompido a qualquer momento. Portanto, sempre sinalize o fim da execução da função corretamente e evite executar qualquer código além dela. Para mais orientações, consulte Funções HTTP, Funções em segundo plano e Funções do CloudEvent.
A execução da função também está sujeita à duração do tempo limite da função. Consulte Tempo limite da função para mais informações.
Considere o cronograma de execução ao inicializar seu aplicativo. As tarefas em segundo plano não devem ser criadas no escopo global durante a inicialização, já que serão executadas fora da duração de uma solicitação.
Garantias de execução
As funções normalmente são invocadas uma vez para cada evento recebido. No entanto, as funções do Cloud Run não garantem uma única invocação em todos os casos por causa de diferenças em cenários de erro.
O número máximo ou mínimo de vezes que a função pode ser invocada para um único evento depende do tipo da função:
As funções HTTP são invocadas, no máximo, uma vez. Isso acontece por causa da natureza síncrona das chamadas HTTP, e isso significa que qualquer erro no processamento da invocação da função será retornado sem nova tentativa. O autor da chamada de uma função HTTP processará os erros e tentará novamente, se necessário.
As funções orientadas a eventos são invocadas pelo menos uma vez. Isso ocorre devido à natureza assíncrona dos eventos, em que não há nenhum autor da chamada aguardando a resposta. Em raras circunstâncias, o sistema poderá invocar uma função orientada a eventos mais de uma vez para garantir a entrega do evento. Se uma invocação da função orientada a eventos falhar com um erro, ela não será invocada novamente, a menos que as novas tentativas em caso de falha estejam ativadas para essa função.
Para garantir que a função se comporte corretamente em tentativas de execução repetidas, você precisa torná-la idempotente implementando-a para que os resultados e efeitos colaterais sejam produzidos mesmo que um evento seja exibido várias vezes. No caso de funções HTTP, isso também indicará o retorno do valor desejado mesmo se o autor da chamada tentar novamente chamadas para o endpoint da função HTTP. Consulte Como repetir funções orientadas a eventos para mais informações sobre como tornar sua função idempotente.
Memória e sistema de arquivos
Cada função tem uma certa quantidade de memória alocada para uso. É possível configurar a quantidade de memória na implantação. Consulte Limites de memória para mais informações.
O ambiente de execução da função inclui um sistema de arquivos na memória que contém os arquivos de origem e diretórios implantados com sua função. Consulte Como estruturar o código-fonte. O diretório que contém os arquivos de origem é somente leitura, mas o restante do sistema de arquivos é gravável (exceto os arquivos usados pelo sistema operacional). O uso do sistema de arquivos é contabilizado no uso da memória de uma função.
Sua função pode interagir com o sistema de arquivos usando métodos padrão em cada linguagem de programação.
Rede
Sua função pode acessar a Internet pública usando métodos padrão em cada linguagem de programação, seja por meio de bibliotecas integradas oferecidas pelo ambiente de execução ou por bibliotecas de terceiros incluídas como dependências.
Tente reutilizar as conexões de rede entre as invocações de função, conforme descrito em Como otimizar a rede. No entanto, uma conexão que permanece sem uso por 10 minutos pode ser fechada pelo sistema, e outras tentativas de usar uma conexão fechada resultam em um erro de "redefinição de conexão". O código precisa usar uma biblioteca que processe bem conexões fechadas ou processá-las explicitamente, caso esteja usando construtos de rede de baixo nível.
Isolamento de funções
Cada função implantada permanece isolada de todas as outras funções, mesmo as implantadas pelo mesmo arquivo de origem. Em especial, elas não compartilham memória, variáveis globais, sistemas de arquivos ou outros estados.
Para compartilhar dados em funções implantadas, é possível usar serviços como Memorystore, Datastore, Firestore ou Cloud Storage. Como alternativa, é possível invocar uma função de outra usando os gatilhos apropriados e transmitindo os dados necessários. Por exemplo, faça uma solicitação HTTP para o endpoint de uma função HTTP ou publique uma mensagem em um tópico Pub/Sub para acionar uma função Pub/Sub.