1. Introdução
Para começar a criar funções do Cloud Run, use os seguintes codelabs:
- Introdução às funções do Cloud Run em HTTP
- Primeiros passos com as funções do Cloud Run orientadas a eventos
Caso contrário, este codelab ensina a criar o Cloud Functions (2ª geração).
Visão geral
O Cloud Functions (2ª geração) é a próxima versão do Google Cloud Functions, a oferta de funções como serviço do Google Cloud. Esta nova versão vem com um conjunto de recursos avançados e agora é alimentada pelo Cloud Run e pelo Eventarc, oferecendo controle mais avançado sobre desempenho e escalonabilidade, além de mais controle sobre o ambiente de execução das funções e gatilhos de mais de 90 origens de eventos.
Neste codelab, você vai aprender a criar funções do Cloud que respondem a chamadas HTTP e são acionadas por mensagens do Pub/Sub e registros de auditoria do Cloud.
Novidades
Esta nova versão do Cloud Functions oferece uma experiência de FaaS otimizada com tecnologia do Cloud Run, Cloud Build, Artifact Registry e Eventarc.
Infraestrutura aprimorada
- Processamento de solicitação mais longo:execute o Cloud Functions por mais tempo do que o padrão de 5 minutos, facilitando a execução de cargas de trabalho de solicitações mais longas, como o processamento de grandes fluxos de dados do Cloud Storage ou do BigQuery. Para funções HTTP, esse tempo é de até 60 minutos. No momento, esse tempo é de até 10 minutos.
- Instâncias maiores:aproveite até 16 GB de RAM e 4 vCPUs no Cloud Functions, permitindo maior carga de trabalho na memória, com mais computação e mais paralelo.
- Simultaneidade:processe até mil solicitações simultâneas com uma única instância de função. Isso minimiza as inicializações a frio e melhora a latência ao escalonar.
- Instâncias mínimas:fornecem instâncias pré-aquecidas para reduzir as inicializações a frio e garantir que o tempo de inicialização do aplicativo não afete o desempenho dele.
- Divisão de tráfego:ofereça suporte a várias versões das suas funções, divida o tráfego entre diferentes versões e reverta a função para uma versão anterior.
Cobertura mais ampla dos eventos e suporte ao CloudEvents
- Integração com o Eventarc:o Cloud Functions agora inclui suporte nativo para o Eventarc, que traz mais de 90 origens de eventos usando os Registros de auditoria do Cloud (BigQuery, Cloud SQL, Cloud Storage etc.). Além disso, o Cloud Functions ainda oferece suporte a eventos de fontes personalizadas com a publicação direta no Cloud Pub/Sub.
- Formato do CloudEvent:todas as funções orientadas a eventos aderem aos CloudEvents padrão do setor ( cloudevents.io), independentemente da origem, para garantir uma experiência consistente para os desenvolvedores. Os payloads são enviados por meio de um CloudEvent estruturado com um payload cloudevent.data e implementam o padrão CloudEvent.
O que você vai aprender
- Visão geral do Cloud Functions (2ª geração).
- Como criar uma função que responda a chamadas HTTP.
- Como criar uma função que responda a mensagens do Pub/Sub.
- Como escrever uma função que responde a eventos do Cloud Storage.
- Como criar uma função que responda aos Registros de auditoria do Cloud.
- Como dividir o tráfego entre duas revisões.
- Como se livrar das inicializações a frio com instâncias mínimas.
- Como definir a simultaneidade.
2. Configuração e requisitos
Configuração de ambiente autoguiada
- Faça login no Console do Google Cloud e crie um novo projeto ou reutilize um existente. Crie uma conta do Gmail ou do Google Workspace, se ainda não tiver uma.
- O Nome do projeto é o nome de exibição para os participantes do projeto. É uma string de caracteres não usada pelas APIs do Google É possível atualizar o local a qualquer momento.
- O ID do projeto precisa ser exclusivo em todos os projetos do Google Cloud e não pode ser alterado após a definição. O console do Cloud gera automaticamente uma string exclusiva. Em geral, não importa o que seja. Na maioria dos codelabs, é necessário fazer referência ao ID do projeto, normalmente identificado como
PROJECT_ID
. Se você não gostar do ID gerado, crie outro aleatório. Se preferir, teste o seu e confira se ele está disponível. Ela não pode ser alterada após esta etapa e permanecerá durante a duração do projeto. - Para sua informação, há um terceiro valor, um Número de projeto, que algumas APIs usam. Saiba mais sobre esses três valores na documentação.
- Em seguida, ative o faturamento no console do Cloud para usar os recursos/APIs do Cloud. A execução deste codelab não será muito cara, se tiver algum custo. Para encerrar os recursos e evitar cobranças além deste tutorial, exclua os recursos criados ou exclua o projeto inteiro. Novos usuários do Google Cloud estão qualificados para o programa de US$ 300 de avaliação sem custos.
Inicie o Cloud Shell
Embora o Google Cloud e o Spanner possam ser operados remotamente do seu laptop, neste codelab usaremos o Google Cloud Shell, um ambiente de linha de comando executado no Cloud.
No Console do Google Cloud, clique no ícone do Cloud Shell na barra de ferramentas superior à direita:
O provisionamento e a conexão com o ambiente levarão apenas alguns instantes para serem concluídos: Quando o processamento for concluído, você verá algo como:
Essa máquina virtual contém todas as ferramentas de desenvolvimento necessárias. Ela oferece um diretório principal persistente de 5 GB, além de ser executada no Google Cloud. Isso aprimora o desempenho e a autenticação da rede. Neste codelab, todo o trabalho pode ser feito com um navegador. Você não precisa instalar nada.
Configurar a gcloud
No Cloud Shell, verifique se o ID do projeto está definido e salvo em uma variável PROJECT_ID
e se REGION
está definido como us-west1
:
gcloud config set project [YOUR-PROJECT-ID] PROJECT_ID=$(gcloud config get-value project) REGION=us-west1
Ativar APIs
Ative todos os serviços necessários:
gcloud services enable \ artifactregistry.googleapis.com \ cloudfunctions.googleapis.com \ cloudbuild.googleapis.com \ eventarc.googleapis.com \ run.googleapis.com \ logging.googleapis.com \ pubsub.googleapis.com
3. Função HTTP
Para a primeira função, vamos criar uma função autenticada do Node.js que responda a solicitações HTTP. Também vamos usar um tempo limite de 10 minutos para mostrar como uma função pode ter mais tempo para responder a solicitações HTTP.
Criação
Crie uma pasta para o app e navegue até ela:
mkdir ~/hello-http && cd $_
Crie um arquivo index.js
que simplesmente responda a solicitações HTTP:
const functions = require('@google-cloud/functions-framework'); functions.http('helloWorld', (req, res) => { res.status(200).send('HTTP with Node.js in GCF 2nd gen!'); });
Crie um arquivo package.json
para especificar as dependências:
{ "name": "nodejs-functions-gen2-codelab", "version": "0.0.1", "main": "index.js", "dependencies": { "@google-cloud/functions-framework": "^2.0.0" } }
Implantar
Implante a função:
gcloud functions deploy nodejs-http-function \ --gen2 \ --runtime nodejs16 \ --entry-point helloWorld \ --source . \ --region $REGION \ --trigger-http \ --timeout 600s
Embora não seja estritamente necessário para esta etapa, observe o tempo limite de 600 segundos. Isso permite que a função tenha um tempo limite maior para responder a solicitações HTTP.
Depois que a função é implantada, ela fica disponível na seção "Cloud Functions" do Console do Cloud:
Teste
Teste a função com o seguinte comando:
gcloud functions call nodejs-http-function \ --gen2 --region $REGION
A mensagem HTTP with Node.js in GCF 2nd gen!
vai aparecer como resposta.
4. Função do Pub/Sub
Para a segunda função, vamos criar uma função Python acionada por uma mensagem do Pub/Sub publicada em um tópico específico.
Configurar tokens de autenticação do Pub/Sub
Se você ativou a conta de serviço do Pub/Sub até 8 de abril de 2021, conceda o papel iam.serviceAccountTokenCreator
à conta de serviço do Pub/Sub:
PROJECT_NUMBER=$(gcloud projects list --filter="project_id:$PROJECT_ID" --format='value(project_number)') gcloud projects add-iam-policy-binding $PROJECT_ID \ --member serviceAccount:service-$PROJECT_NUMBER@gcp-sa-pubsub.iam.gserviceaccount.com \ --role roles/iam.serviceAccountTokenCreator
Criação
Crie um tópico do Pub/Sub para usar no exemplo:
TOPIC=cloud-functions-gen2-topic gcloud pubsub topics create $TOPIC
Crie uma pasta para o app e navegue até ela:
mkdir ~/hello-pubsub && cd $_
Crie um arquivo main.py
que simplesmente registre uma mensagem contendo o ID do CloudEvent:
import functions_framework @functions_framework.cloud_event def hello_pubsub(cloud_event): print('Pub/Sub with Python in GCF 2nd gen! Id: ' + cloud_event['id'])
Crie um arquivo requirements.txt
com o seguinte conteúdo para especificar as dependências:
functions-framework==3.*
Implantar
Implante a função:
gcloud functions deploy python-pubsub-function \ --gen2 \ --runtime python39 \ --entry-point hello_pubsub \ --source . \ --region $REGION \ --trigger-topic $TOPIC
Depois que a função for implantada, você poderá vê-la na seção Cloud Functions do Console do Cloud:
Teste
Para testar a função, envie uma mensagem para o tópico:
gcloud pubsub topics publish $TOPIC --message="Hello World"
Você verá o CloudEvent recebido nos registros:
gcloud functions logs read python-pubsub-function \ --region $REGION --gen2 --format "value(log)"
5. Função do Cloud Storage
Para a próxima função, vamos criar uma função Node.js que responde a eventos de um bucket do Cloud Storage.
Configurar
Para usar as funções do Cloud Storage, conceda a função pubsub.publisher
do IAM à conta de serviço do Cloud Storage:
SERVICE_ACCOUNT=$(gsutil kms serviceaccount -p $PROJECT_NUMBER) gcloud projects add-iam-policy-binding $PROJECT_ID \ --member serviceAccount:$SERVICE_ACCOUNT \ --role roles/pubsub.publisher
Criação
Crie uma pasta para o app e navegue até ela:
mkdir ~/hello-storage && cd $_
Crie um arquivo index.js
que simplesmente responda a eventos do Cloud Storage:
const functions = require('@google-cloud/functions-framework'); functions.cloudEvent('helloStorage', (cloudevent) => { console.log('Cloud Storage event with Node.js in GCF 2nd gen!'); console.log(cloudevent); });
Crie um arquivo package.json
para especificar as dependências:
{ "name": "nodejs-functions-gen2-codelab", "version": "0.0.1", "main": "index.js", "dependencies": { "@google-cloud/functions-framework": "^2.0.0" } }
Implantar
Primeiro, crie um bucket do Cloud Storage (ou use um bucket que você já tem):
export BUCKET="gs://gcf-gen2-storage-$PROJECT_ID" gsutil mb -l $REGION $BUCKET
Implante a função:
gcloud functions deploy nodejs-storage-function \ --gen2 \ --runtime nodejs16 \ --entry-point helloStorage \ --source . \ --region $REGION \ --trigger-bucket $BUCKET \ --trigger-location $REGION
Depois que a função for implantada, ela vai aparecer na seção "Cloud Functions" do Console do Cloud.
Teste
Teste a função fazendo upload de um arquivo para o bucket:
echo "Hello World" > random.txt gsutil cp random.txt $BUCKET/random.txt
Você verá o CloudEvent recebido nos registros:
gcloud functions logs read nodejs-storage-function \ --region $REGION --gen2 --limit=100 --format "value(log)"
6. Função de registros de auditoria do Cloud
Na próxima função, vamos criar uma função Node.js que recebe um evento de registro de auditoria do Cloud quando uma instância de VM do Compute Engine é criada. Em resposta, ele adiciona um rótulo à VM recém-criada, especificando o criador dela.
Determinar as VMs do Compute Engine recém-criadas
O Compute Engine emite dois registros de auditoria quando uma VM é criada.
O primeiro é emitido no início da criação da VM e tem esta aparência:
O segundo é emitido após a criação da VM e tem esta aparência:
Observe o campo de operação com os valores first: true
e last: true
. O segundo registro de auditoria contém todas as informações necessárias para rotular uma instância. Portanto, vamos usar a flag last: true
para detectá-la no Cloud Functions.
Configurar
Para usar as funções de registro de auditoria do Cloud, ative os registros de auditoria para o Eventarc. Você também precisa usar uma conta de serviço com o papel eventarc.eventReceiver
.
- Ative os tipos de registro de auditoria do Cloud Leitura de administradores, Leitura de dados e Gravação de dados para a API Compute Engine:
- Conceda à conta de serviço padrão do Compute Engine o papel do IAM
eventarc.eventReceiver
:
gcloud projects add-iam-policy-binding $PROJECT_ID \ --member serviceAccount:$PROJECT_NUMBER-compute@developer.gserviceaccount.com \ --role roles/eventarc.eventReceiver
Acessar o código
Clone o repositório que contém o aplicativo:
git clone https://github.com/GoogleCloudPlatform/eventarc-samples.git
Navegue até o diretório do app:
cd eventarc-samples/gce-vm-labeler/gcf/nodejs
O arquivo index.js
contém o código do aplicativo que recebe o registro de auditoria agrupado em um CloudEvent. Em seguida, ele extrai os detalhes da instância de VM do Compute Engine e define um rótulo nela. Fique à vontade para estudar index.js
com mais detalhes por conta própria.
Implantar
É possível implantar a função com gcloud
como antes. Observe como a função está filtrando os registros de auditoria para inserções do Compute Engine com a flag --trigger-event-filters
:
gcloud functions deploy gce-vm-labeler \ --gen2 \ --runtime nodejs16 \ --entry-point labelVmCreation \ --source . \ --region $REGION \ --trigger-event-filters="type=google.cloud.audit.log.v1.written,serviceName=compute.googleapis.com,methodName=beta.compute.instances.insert" \ --trigger-location us-central1
Também é possível implantar a função e adicionar um acionador do Eventarc no console do Google Cloud.
Primeiro, acesse a seção do Cloud Functions e crie uma função com um ambiente de 2a geração:
Clique no botão Add Eventarc Trigger
:
Isso abre um painel lateral à direita, onde você pode escolher diferentes provedores de eventos e eventos para o acionador do Eventarc.
Escolha o provedor de eventos e o evento corretos e clique em Save Trigger
:
Por fim, na próxima página, você pode atualizar os arquivos index.js
e package.json
com arquivos index.js
e package.json
no GitHub e clicar no botão Deploy
:
Teste
Para testar a função de registro de auditoria, você precisa criar uma VM do Compute Engine no Console do Cloud. Também é possível criar VMs com gcloud
, mas elas não parecem gerar registros de auditoria.
Acesse a seção Compute Engine > Instâncias de VM do console do Cloud e crie uma nova VM. Depois que a criação da VM for concluída, o rótulo creator
adicionado vai aparecer na VM no console do Cloud na seção Informações básicas ou usando o seguinte comando:
gcloud compute instances describe YOUR_VM_NAME
Você verá o rótulo na saída como o exemplo a seguir:
... labelFingerprint: ULU6pAy2C7s= labels: creator: atameldev ...
7. Divisão de tráfego
O Cloud Functions (2nd gen) é compatível com várias revisões das funções, dividindo o tráfego entre diferentes revisões e revertendo a função para uma versão anterior. Isso é possível porque as funções de 2ª geração são serviços do Cloud Run.
Nesta etapa, você vai implantar 2 revisões de uma função e dividir o tráfego entre elas de 50 a 50.
Criação
Crie uma pasta para o app e navegue até ela:
mkdir ~/traffic-splitting && cd $_
Crie um arquivo main.py
com uma função Python que leia uma variável de ambiente de cor e responda com Hello World
nessa cor de plano de fundo:
import os color = os.environ.get('COLOR') def hello_world(request): return f'<body style="background-color:{color}"><h1>Hello World!</h1></body>'
Implantar
Implante a primeira revisão da função com um plano de fundo laranja:
COLOR=orange gcloud functions deploy hello-world-colored \ --gen2 \ --runtime python39 \ --entry-point hello_world \ --source . \ --region $REGION \ --trigger-http \ --allow-unauthenticated \ --update-env-vars COLOR=$COLOR
Nesse ponto, se você testar a função visualizando o gatilho HTTP (a saída do URI do comando de implantação acima) no navegador, verá Hello World
com um plano de fundo laranja:
Implante a segunda revisão com um plano de fundo amarelo:
COLOR=yellow gcloud functions deploy hello-world-colored \ --gen2 \ --runtime python39 \ --entry-point hello_world \ --source . \ --region $REGION \ --trigger-http \ --allow-unauthenticated \ --update-env-vars COLOR=$COLOR
Como esta é a revisão mais recente, se você testar a função, verá Hello World
com um plano de fundo amarelo:
Dividir o tráfego em 50-50
Para dividir o tráfego entre as revisões laranja e amarela, você precisa encontrar os IDs de revisão dos serviços do Cloud Run subjacentes. Este é o comando para conferir os IDs de revisão:
gcloud run revisions list --service hello-world-colored \ --region $REGION --format 'value(REVISION)'
A saída será semelhante a esta:
hello-world-colored-00001-man hello-world-colored-00002-wok
Agora, divida o tráfego entre essas duas revisões da seguinte maneira (atualize o X-XXX
de acordo com os nomes das revisões):
gcloud run services update-traffic hello-world-colored \ --region $REGION \ --to-revisions hello-world-colored-0000X-XXX=50,hello-world-colored-0000X-XXX=50
Teste
Acesse o URL público para testar a função. Na metade do tempo, você vai ver a revisão laranja e, na outra metade, a revisão amarela:
Consulte reversões, lançamentos graduais e migração de tráfego para mais informações.
8. Instâncias mínimas
No Cloud Functions (2ª geração), é possível especificar um número mínimo de instâncias de função a serem mantidas quentes e prontas para exibir solicitações. Isso é útil para limitar o número de inicializações a frio.
Nesta etapa, você vai implantar uma função com inicialização lenta. Você vai observar o problema de inicialização a frio. Em seguida, implante a função com o valor mínimo da instância definido como 1 para se livrar da inicialização a frio.
Criação
Crie uma pasta para o app e navegue até ela:
mkdir ~/min-instances && cd $_
Crie um arquivo main.go
. Esse serviço Go tem uma função init
que fica inativa por 10 segundos para simular uma inicialização longa. Ela também tem uma função HelloWorld
que responde a chamadas HTTP:
package p import ( "fmt" "net/http" "time" ) func init() { time.Sleep(10 * time.Second) } func HelloWorld(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, "Slow HTTP Go in GCF 2nd gen!") }
Implantar
Implante a primeira revisão da função com o valor mínimo padrão da instância, que é zero:
gcloud functions deploy slow-function \ --gen2 \ --runtime go116 \ --entry-point HelloWorld \ --source . \ --region $REGION \ --trigger-http \ --allow-unauthenticated
Teste a função com este comando:
gcloud functions call slow-function \ --gen2 --region $REGION
Você vai notar um atraso de 10 segundos (início frio) na primeira chamada e depois vai receber a mensagem. As chamadas seguintes devem ser retornadas imediatamente.
Definir instâncias mínimas
Para se livrar da inicialização a frio na primeira solicitação, reimplante a função com a flag --min-instances
definida como 1, conforme mostrado abaixo:
gcloud functions deploy slow-function \ --gen2 \ --runtime go116 \ --entry-point HelloWorld \ --source . \ --region $REGION \ --trigger-http \ --allow-unauthenticated \ --min-instances 1
Teste
Teste a função novamente:
gcloud functions call slow-function \ --gen2 --region $REGION
O atraso de 10 segundos não vai mais aparecer na primeira solicitação. O problema de inicialização a frio da primeira invocação (depois de muito tempo sem) desaparece, graças às instâncias mínimas.
Consulte Como usar instâncias mínimas para mais informações.
9. Simultaneidade
No Cloud Functions (2nd gen), uma instância de função processa uma solicitação simultânea por padrão, mas é possível especificar o número de solicitações simultâneas que podem ser processadas simultaneamente por uma instância. Isso também pode ser útil para evitar inicializações a frio, já que uma nova instância de função não precisa ser criada para cada solicitação paralela.
Nesta etapa, você vai usar a função com inicialização lenta da etapa anterior. Você vai enviar 10 solicitações e observar o problema de inicialização a frio novamente, já que novas instâncias de função precisam ser criadas para processar as solicitações.
Para corrigir o problema de inicialização a frio, você vai implantar outra função com um valor de simultaneidade de 100. Agora, as 10 solicitações não causam o problema de inicialização a frio, e uma única instância de função pode processar todas as solicitações.
Teste sem simultaneidade
Encontre o URL da função:
SLOW_URL=$(gcloud functions describe slow-function --region $REGION --gen2 --format="value(serviceConfig.uri)")
Use uma ferramenta de comparação de mercado de código aberto chamada hey
para enviar 10 solicitações simultâneas para a função lenta. O hey
já está instalado no Cloud Shell:
hey -n 10 -c 10 $SLOW_URL
A saída de hey
vai mostrar que algumas solicitações estão demorando muito:
Summary: Total: 10.9053 secs Slowest: 10.9048 secs Fastest: 0.4439 secs Average: 9.7930 secs Requests/sec: 0.9170 Total data: 310 bytes Size/request: 31 bytes Response time histogram: 0.444 [1] |■■■■ 1.490 [0] | 2.536 [0] | 3.582 [0] | 4.628 [0] | 5.674 [0] | 6.720 [0] | 7.767 [0] | 8.813 [0] | 9.859 [0] | 10.905 [9] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
Isso ocorre porque mais instâncias de função estão sendo criadas para processar as solicitações. Se você verificar a contagem de instâncias ativas da função, também vai notar que mais de uma instância foi criada em algum momento e está causando o problema de inicialização a frio:
Implantar
Implante uma nova função idêntica à anterior. Após a implantação, você vai aumentar a simultaneidade:
gcloud functions deploy slow-concurrent-function \ --gen2 \ --runtime go116 \ --entry-point HelloWorld \ --source . \ --region $REGION \ --trigger-http \ --allow-unauthenticated \ --min-instances 1
Definir simultaneidade
Defina a simultaneidade do serviço subjacente do Cloud Run para a função como 100 (pode ser no máximo 1.000). Isso garante que pelo menos 100 solicitações possam ser tratadas por uma única instância de função:
gcloud run services update slow-concurrent-function \ --concurrency 100 \ --cpu 1 \ --region $REGION
Testar com simultaneidade
Encontre o URL da função:
SLOW_CONCURRENT_URL=$(gcloud functions describe slow-concurrent-function --region $REGION --gen2 --format="value(serviceConfig.uri)")
Em seguida, use hey
para enviar 10 solicitações simultâneas:
hey -n 10 -c 10 $SLOW_CONCURRENT_URL
Na saída de hey
, você vai notar que todas as solicitações são processadas rapidamente:
Summary: Total: 0.2164 secs Slowest: 0.2163 secs Fastest: 0.0921 secs Average: 0.2033 secs Requests/sec: 46.2028 Total data: 310 bytes Size/request: 31 bytes Response time histogram: 0.092 [1] |■■■■ 0.105 [0] | 0.117 [0] | 0.129 [0] | 0.142 [0] | 0.154 [0] | 0.167 [0] | 0.179 [0] | 0.191 [0] | 0.204 [0] | 0.216 [9] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
Uma única instância de função conseguiu processar todas as solicitações, e o problema de inicialização a frio foi resolvido, graças ao aumento da simultaneidade.
Consulte simultaneidade para mais informações.
10. Parabéns!
Parabéns por concluir o codelab.
O que vimos
- Visão geral do Cloud Functions (2a geração).
- Como criar uma função que responda a chamadas HTTP.
- Como criar uma função que responda a mensagens do Pub/Sub.
- Como escrever uma função que responde a eventos do Cloud Storage.
- Como criar uma função que responda aos Registros de auditoria do Cloud.
- Como dividir o tráfego entre duas revisões.
- Como se livrar das inicializações a frio com instâncias mínimas.
- Como definir a simultaneidade.