Ambiente de execução do Cloud Functions
As funções do Cloud Run são executadas num ambiente sem servidor totalmente gerido onde a Google trata da infraestrutura, dos sistemas operativos e dos ambientes de tempo de execução. Cada função é executada no seu próprio contexto de execução seguro isolado, é dimensionada automaticamente e tem um ciclo de vida independente de outras funções.
Tempos de execução
As funções do Cloud Run suportam vários tempos de execução de idiomas. Cada um contém um conjunto padrão de pacotes do sistema, bem como as ferramentas e as bibliotecas necessárias para esse idioma. Precisa do valor do ID de tempo de execução se estiver a implementar funções a partir da linha de comandos ou através do Terraform.
As atualizações de segurança e manutenção são disponibilizadas a todos os ambientes de execução de 1.ª e 2.ª geração. Estas atualizações são aplicadas automaticamente ou manualmente, consoante o ambiente e a forma como o configurou. Para mais informações acerca das atualizações do ambiente de execução, consulte o artigo Proteja a sua função do Cloud Run.
Node.js
Tempo de execução | Geração | Ambiente | ID do ambiente de execução | Imagem do tempo de execução |
---|---|---|---|---|
Node.js 24 (apenas pré-visualização) |
2.ª geração | Ubuntu 24.04 | nodejs24 | us-central1-docker.pkg.dev/serverless-runtimes/google-24-full/runtimes/nodejs24 |
Node.js 22 | 2.ª geração | Ubuntu 22.04 | nodejs22 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/nodejs22 |
Node.js 20 | 1.ª geração, 2.ª geração | Ubuntu 22.04 | nodejs20 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/nodejs20 |
Node.js 18 | 1.ª geração, 2.ª geração | Ubuntu 22.04 | nodejs18 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/nodejs18 |
Node.js 16 | 1.ª geração, 2.ª geração | Ubuntu 18.04 | nodejs16 | us-central1-docker.pkg.dev/serverless-runtimes/google-18-full/runtimes/nodejs16 |
Node.js 14 | 1.ª geração, 2.ª geração | Ubuntu 18.04 | nodejs14 | us-central1-docker.pkg.dev/serverless-runtimes/google-18-full/runtimes/nodejs14 |
Node.js 12 | 1.ª geração, 2.ª geração | Ubuntu 18.04 | nodejs12 | us-central1-docker.pkg.dev/serverless-runtimes/google-18-full/runtimes/nodejs12 |
Node.js 10 | 1.ª geração, 2.ª geração | Ubuntu 18.04 | nodejs10 | us-central1-docker.pkg.dev/serverless-runtimes/google-18-full/runtimes/nodejs10 |
Node.js 8 | 1.ª geração, 2.ª geração | Ubuntu 18.04 | nodejs8 | Desativado |
Node.js 6 | 1.ª geração, 2.ª geração | Ubuntu 18.04 | nodejs6 | Desativado |
Python
Go
Java
Tempo de execução | Geração | Ambiente | ID do ambiente de execução | Imagem do tempo de execução |
---|---|---|---|---|
Java 21 | 2.ª geração | Ubuntu 22.04 | java21 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/java21 |
Java 17 | 1.ª geração, 2.ª geração | Ubuntu 22.04 | java17 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/java17 |
Java 11 | 1.ª geração, 2.ª geração | Ubuntu 18.04 | java11 | us-central1-docker.pkg.dev/serverless-runtimes/google-18-full/runtimes/java11 |
Ruby
Tempo de execução | Geração | Ambiente | ID do ambiente de execução | Imagem do tempo de execução |
---|---|---|---|---|
Ruby 3.4 | 2.ª geração | Ubuntu 22.04 | ruby34 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/ruby34 |
Ruby 3.3 | 1.ª geração, 2.ª geração | Ubuntu 22.04 | ruby33 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/ruby33 |
Ruby 3.2 | 1.ª geração, 2.ª geração | Ubuntu 22.04 | ruby32 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/ruby32 |
Ruby 3.0 | 1.ª geração, 2.ª geração | Ubuntu 18.04 | ruby30 | us-central1-docker.pkg.dev/serverless-runtimes/google-18-full/runtimes/ruby30 |
Ruby 2.7 | 1.ª geração, 2.ª geração | Ubuntu 18.04 | ruby27 | us-central1-docker.pkg.dev/serverless-runtimes/google-18-full/runtimes/ruby27 |
Ruby 2.6 | 1.ª geração, 2.ª geração | Ubuntu 18.04 | ruby26 | us-central1-docker.pkg.dev/serverless-runtimes/google-18-full/runtimes/ruby26 |
PHP
Tempo de execução | Ambiente | Geração | ID do ambiente de execução | Imagem do tempo de execução |
---|---|---|---|---|
PHP 8.4 | 2.ª geração | Ubuntu 22.04 | php84 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/php84 |
PHP 8.3 | 2.ª geração | Ubuntu 22.04 | php83 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/php83 |
PHP 8.2 | 1.ª geração, 2.ª geração | Ubuntu 22.04 | php82 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/php82 |
PHP 8.1 | 1.ª geração, 2.ª geração | Ubuntu 18.04 | php81 | us-central1-docker.pkg.dev/serverless-runtimes/google-18-full/runtimes/php81 |
PHP 7.4 | 1.ª geração, 2.ª geração | Ubuntu 18.04 | php74 | us-central1-docker.pkg.dev/serverless-runtimes/google-18-full/runtimes/php74 |
.NET Core
Tempo de execução | Geração | Ambiente | ID do ambiente de execução | Imagem do tempo de execução |
---|---|---|---|---|
.NET Core 8 | 2.ª geração | Ubuntu 22.04 | dotnet8 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/dotnet8 |
.NET Core 6 | 1.ª geração, 2.ª geração | Ubuntu 22.04 | dotnet6 | us-central1-docker.pkg.dev/serverless-runtimes/google-22-full/runtimes/dotnet6 |
.NET Core 3 | 1.ª geração, 2.ª geração | Ubuntu 18.04 | dotnet3 | us-central1-docker.pkg.dev/serverless-runtimes/google-18-full/runtimes/dotnet3 |
Comportamento da escala automática
As funções do Cloud Run implementam o paradigma sem servidor, no qual executa o seu código sem se preocupar com a infraestrutura subjacente, como servidores ou máquinas virtuais. Após a implementação, as suas funções são geridas e dimensionadas automaticamente.
As funções do Cloud Run processam os pedidos recebidos atribuindo-os a instâncias da sua função. Consoante o volume de pedidos, bem como o número de instâncias de funções existentes, as funções do Cloud Run podem atribuir um pedido a uma instância existente ou criar uma nova.
Nos casos em que o volume de pedidos recebidos excede o número de instâncias existentes, as funções do Cloud Run podem iniciar várias novas instâncias para processar pedidos. Este comportamento de escalabilidade automática permite que as funções do Cloud Run processem muitos pedidos em paralelo, cada um usando uma instância diferente da sua função.
Em alguns casos, o aumento ilimitado pode ser indesejável. Para resolver este problema, as funções do Cloud Run permitem-lhe configurar um número máximo de instâncias que podem coexistir em qualquer altura para uma função específica.
Apátrida
Para ativar a gestão e o dimensionamento automáticos das suas funções, as funções têm de 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 diferentes instâncias de funções, que não partilham variáveis globais, memória, sistemas de ficheiros nem outro estado.
Se precisar de partilhar o estado entre invocações de funções, a sua função deve usar um serviço como o Memorystore, Datastore, Firestore ou Cloud Storage para persistir os dados. Consulte as Google Cloud bases de dados e os Google Cloud produtos de armazenamento para mais informações sobre as opções de bases de dados e armazenamento fornecidas pela Google Cloud.
Simultaneidade
Funções do Cloud Run (2.ª geração)
As funções do Cloud Run (2.ª geração) suportam o processamento de vários pedidos simultâneos numa instância de função única. Isto pode ser útil para evitar inícios a frio, uma vez que uma instância já aquecida pode processar vários pedidos em simultâneo, reduzindo assim a latência geral. Para obter detalhes, consulte a secção Concorrência.
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 um pedido concorrente de cada vez. Isto significa que, enquanto o seu código está a processar um pedido, não existe a possibilidade de um segundo pedido ser encaminhado para a mesma instância. Assim, o pedido original pode usar a quantidade total de recursos (memória e CPU) que atribui.
Uma vez que os pedidos simultâneos nas funções do Cloud Run (1.ª geração) são processados por instâncias de funções diferentes, não partilham variáveis nem memória local. Consulte os artigos Sem estado e Tempo de vida da instância da função para mais informações.
Inícios a frio
Uma nova instância de função é iniciada em dois casos:
Quando implementa a sua função.
Quando é criada automaticamente uma nova instância de função para aumentar a escala de acordo com a carga ou, ocasionalmente, para substituir uma instância existente.
O início de uma nova instância de função envolve o carregamento do tempo de execução e do seu código. Os pedidos que incluem o arranque da instância da função, denominado arranque a frio, podem ser mais lentos do que os pedidos encaminhados para instâncias de funções existentes. No entanto, se a sua função receber uma carga constante, o número de inícios a frio é normalmente insignificante, a menos que a função falhe frequentemente e exija o reinício do ambiente de funções.
Se o código da função gerar uma exceção não capturada ou falhar no processo atual, a instância da função pode ser reiniciada. Isto pode levar a inícios a frio, o que resulta numa latência mais elevada. Por isso, recomendamos que intercete exceções e, caso contrário, evite a terminação do processo atual.
Se a sua função for sensível à latência, considere definir um número mínimo de instâncias para evitar inícios a frio.
Tempo de vida da instância da função
Normalmente, as instâncias de funções são resilientes e reutilizadas por invocações de funções subsequentes, a menos que o número de instâncias esteja a ser reduzido devido à falta de tráfego contínuo ou a sua função falhe. Isto significa que, quando a execução de uma função termina, outra invocação de função pode ser processada pela mesma instância de função.
Âmbito da função versus âmbito 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 âmbito global do código fonte da sua função só é executado em inícios a frio e não em instâncias que já foram inicializadas.
Node.js
Python
Go
Java
Ruby
Pode usar variáveis globais como uma otimização do desempenho, mas não deve confiar no estado definido no âmbito global por invocações de funções anteriores. Consulte a secção Sem estado para mais informações.
Pode assumir que, para cada instância de função, o âmbito global foi executado exatamente uma vez antes de o código da função ser invocado. No entanto, não deve depender do número total nem do momento das execuções de âmbito global, uma vez que podem variar consoante a atividade de dimensionamento automático.
Linha cronológica da execução da função
Uma função tem acesso aos respetivos recursos atribuídos (memória e CPU) apenas durante a execução da função. Não é garantida a execução de código fora do período de execução, e este pode ser interrompido em qualquer altura. Por conseguinte, deve sempre sinalizar corretamente o fim da execução da função e evitar executar código para além da mesma. Consulte as funções HTTP, funções em segundo plano e funções CloudEvent para ver orientações.
A execução da função também está sujeita à duração do tempo limite da função. Consulte a secção Limite de tempo de processamento da função para mais informações.
Tenha em conta a cronologia de execução ao inicializar a sua aplicação. Não devem ser criadas tarefas em segundo plano no âmbito global durante a inicialização, uma vez que seriam executadas fora da duração de um pedido.
Garantias de execução
Normalmente, as suas funções 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 devido a diferenças nos cenários de erro.
O número máximo ou mínimo de vezes que a sua função pode ser invocada para um único evento depende do tipo de função:
As funções HTTP são invocadas, na maioria, uma vez. Isto deve-se à natureza síncrona das chamadas HTTP e significa que qualquer erro que ocorra durante a invocação da função é devolvido sem novas tentativas. O autor da chamada de uma função HTTP deve processar os erros e repetir a operação, se necessário.
As funções acionadas por eventos são invocadas, pelo menos, uma vez. Isto deve-se à natureza assíncrona dos eventos, em que não existe nenhum autor da chamada que aguarde a resposta. Em circunstâncias raras, o sistema pode invocar uma função acionada por eventos mais do que uma vez para garantir a entrega do evento. Se uma invocação de função baseada em eventos falhar com um erro, a função não é invocada novamente, a menos que as tentativas em caso de falha estejam ativadas para essa função.
Para se certificar de que a sua função se comporta corretamente em tentativas de execução repetidas, deve torná-la idempotente, implementando-a de modo que os resultados desejados (e os efeitos secundários) sejam produzidos mesmo que um evento seja enviado várias vezes. No caso das funções HTTP, isto também significa devolver o valor pretendido, mesmo que o autor da chamada volte a tentar chamar o ponto final da função HTTP. Consulte o artigo Voltar a tentar funções acionadas por eventos para mais informações sobre como tornar a sua função idempotente.
Memória e sistema de ficheiros
Cada função tem uma determinada quantidade de memória alocada para a sua utilização. Pode configurar a quantidade de memória na implementação. Consulte o artigo Configurar memória para mais informações.
O ambiente de execução da função inclui um sistema de ficheiros na memória que contém os ficheiros de origem e os diretórios implementados com a sua função (consulte a secção Estruturar o código-fonte). O diretório que contém os ficheiros de origem é apenas de leitura, mas o resto do sistema de ficheiros é gravável (exceto os ficheiros usados pelo sistema operativo). A utilização do sistema de ficheiros conta para a utilização de memória de uma função.
A sua função pode interagir com o sistema de ficheiros através de métodos padrão em cada linguagem de programação.
Rede
A sua função pode aceder à Internet pública através de métodos padrão em cada linguagem de programação, quer através de bibliotecas incorporadas oferecidas pelo tempo de execução ou bibliotecas de terceiros que inclui como dependências.
Tente reutilizar as ligações de rede nas invocações de funções. No entanto, tenha em atenção que uma ligação que permaneça não utilizada durante 10 minutos pode ser fechada pelo sistema, e as tentativas adicionais de usar uma ligação fechada resultam num erro "connection reset". O seu código deve usar uma biblioteca que processe bem as ligações fechadas ou processá-las explicitamente se usar construções de rede de baixo nível.
Isolamento de funções
Todas as funções implementadas estão isoladas de todas as outras funções, mesmo as que foram implementadas a partir do mesmo ficheiro de origem. Em particular, não partilham memória, variáveis globais, sistemas de ficheiros nem outro estado.
Para partilhar dados entre funções implementadas, pode usar serviços como o Memorystore, Datastore, Firestore ou Cloud Storage. Em alternativa, pode invocar uma função a partir de outra usando os respetivos acionadores adequados e transmitindo os dados necessários. Por exemplo, fazer um pedido HTTP ao ponto final de uma função HTTP ou publicar uma mensagem num tópico Pub/Sub para acionar uma função Pub/Sub.