Neste tutorial, você vai aprender a criar um serviço de chat em tempo real com várias salas usando WebSockets com uma conexão persistente para comunicação bidirecional. Com WebSockets, o cliente e o servidor podem enviar mensagens uns para os outros sem procurar atualizações no servidor.
Embora seja possível configurar o Cloud Run para usar a afinidade da sessão, isso fornece uma afinidade de melhor esforço, o que significa que qualquer nova solicitação ainda poderá ser possivelmente roteada para uma instância diferente. Consequentemente, as mensagens dos usuários no serviço de chat precisam ser sincronizadas em todas as instâncias, não apenas entre os clientes conectados a uma instância.
Design para um serviço de chat em tempo real
Este serviço de chat de amostra usa uma instância do Memorystore para Redis para armazenar e sincronizar mensagens de usuários em todas as instâncias. O Redis usa um mecanismo Pub/Sub, não confundir com o produto Cloud Pub/Sub, para enviar dados a clientes inscritos conectados a qualquer instância, eliminando a pesquisa de HTTP para atualizações.
No entanto, mesmo com atualizações push, qualquer instância de contêiner ativada receberá apenas novas mensagens enviadas ao contêiner. Para carregar mensagens anteriores, o histórico de mensagens precisaria ser armazenado e recuperado de uma solução de armazenamento permanente. Neste exemplo, usamos a funcionalidade convencional do Redis de um armazenamento de objetos para armazenar em cache e recuperar o histórico de mensagens.
A instância do Redis é protegida da Internet usando IPs privados com acesso controlado e limitado a serviços em execução na mesma rede privada virtual que a instância do Redis. Recomendamos que você use a saída direta da VPC.
Limitações
Neste tutorial, não mostramos a autenticação do usuário final ou o armazenamento em cache da sessão. Para saber mais sobre a autenticação de usuários finais, consulte o tutorial do Cloud Run sobre autenticação do usuário final.
Neste tutorial, não implementamos um banco de dados como o Firestore para armazenamento e recuperação indefinidos do histórico de mensagens do chat.
São necessários elementos adicionais para que este serviço de amostra esteja pronto para produção. Uma instância do Redis de nível padrão é recomendada para fornecer alta disponibilidade usando a replicação e o failover automático.
Objetivos
Gravar, criar e implantar um serviço do Cloud Run que usa WebSockets.
Conecte-se a uma instância do Memorystore para Redis para publicar e assinar novas mensagens em instâncias de contêiner.
Conecte o serviço do Cloud Run com o Memorystore usando a saída VPC direta.
Custos
Neste documento, você vai usar os seguintes componentes faturáveis do Google Cloud:
Para gerar uma estimativa de custo baseada na sua projeção de uso, utilize a calculadora de preços.
Antes de começar
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
-
Enable the Cloud Run, Memorystore for Redis, Artifact Registry, and Cloud Build APIs.
Roles required to enable APIs
To enable APIs, you need the Service Usage Admin IAM role (
roles/serviceusage.serviceUsageAdmin), which contains theserviceusage.services.enablepermission. Learn how to grant roles. - Instale e inicialize a gcloud CLI.
-
Leitor do Artifact Registry (
roles/artifactregistry.reader) -
Editor do Cloud Build (
roles/cloudbuild.builds.editor) -
Administrador do Cloud Memorystore para Redis (
roles/redis.admin) -
Administrador do Cloud Run (
roles/run.admin) -
Criar contas de serviço (
roles/iam.serviceAccountCreator) -
Administrador de projetos do IAM (
roles/resourcemanager.projectIamAdmin) -
Administrador da conta de serviço (
roles/iam.serviceAccountAdmin) -
Consumidor do Service Usage (
roles/serviceusage.serviceUsageConsumer)
Funções exigidas
Para conseguir as permissões necessárias a fim de concluir o tutorial, peça ao administrador para conceder a você os seguintes papéis do IAM no projeto:
Para mais informações sobre a concessão de papéis, consulte Gerenciar o acesso a projetos, pastas e organizações.
Também é possível conseguir as permissões necessárias por meio de papéis personalizados ou de outros papéis predefinidos.
Configurar os padrões da gcloud
Para configurar a gcloud com os padrões do serviço do Cloud Run, realize as etapas a seguir:
Defina seu projeto padrão:
gcloud config set project PROJECT_ID
Substitua PROJECT_ID pelo nome do projeto que você criou para este tutorial.
Configure a gcloud para a região escolhida:
gcloud config set run/region REGION
Substitua REGION pela região compatível do Cloud Run.
Locais do Cloud Run
O Cloud Run é regional, o que significa que a infraestrutura que executa seus serviços do Cloud Run está localizada em uma região específica e é gerenciada pelo Google para estar disponível de maneira redundante em todas as zonas da região.
Atender aos seus requisitos de latência, disponibilidade ou durabilidade são os principais fatores para selecionar a região em que seus serviços do Cloud Run são executados.
Geralmente, é possível selecionar a região mais próxima de seus usuários, mas considere
a localização dos outros Google Cloud
produtos usados pelo serviço do Cloud Run.
O uso de produtos do Google Cloud em vários locais pode afetar a latência e o custo do serviço.
O Cloud Run está disponível nas regiões a seguir:
Sujeitas aos preços do nível 1
asia-east1(Taiwan)asia-northeast1(Tóquio)asia-northeast2(Osaka)asia-south1(Mumbai, Índia)europe-north1(Finlândia)Baixo CO2
europe-north2(Estocolmo)Baixo CO2
europe-southwest1(Madri)Baixo CO2
europe-west1(Bélgica)Baixo CO2
europe-west4(Países Baixos)Baixo CO2
europe-west8(Milão)europe-west9(Paris)Baixo CO2
me-west1(Tel Aviv)northamerica-south1(México)us-central1(Iowa)Baixo CO2
us-east1(Carolina do Sul)us-east4(Norte da Virgínia)us-east5(Columbus)us-south1(Dallas)Baixo CO2
us-west1(Oregon)Baixo CO2
Sujeitas aos preços do nível 2
africa-south1(Johannesburgo)asia-east2(Hong Kong)asia-northeast3(Seul, Coreia do Sul)asia-southeast1(Singapura)asia-southeast2(Jacarta)asia-south2(Déli, Índia)australia-southeast1(Sydney)australia-southeast2(Melbourne)europe-central2(Varsóvia, Polônia)europe-west10(Berlim)europe-west12(Turim)europe-west2(Londres, Reino Unido)Baixo CO2
europe-west3(Frankfurt, Alemanha)europe-west6(Zurique, Suíça)Baixo CO2
me-central1(Doha)me-central2(Damã)northamerica-northeast1(Montreal)Baixo CO2
northamerica-northeast2(Toronto)Baixo CO2
southamerica-east1(São Paulo, Brasil)Baixo CO2
southamerica-west1(Santiago, Chile)Baixo CO2
us-west2(Los Angeles)us-west3(Salt Lake City)us-west4(Las Vegas)
Se você já criou um serviço do Cloud Run, é possível visualizar a região no painel do Cloud Run no console doGoogle Cloud .
Recuperar a amostra de código
Para recuperar o exemplo de código para uso, siga estas etapas:
Clone o repositório de amostra na máquina local:
Node.js
git clone https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git
Outra alternativa é fazer o download da amostra como um arquivo ZIP e extraí-lo.
Mude para o diretório que contém o código de amostra do Cloud Run:
Node.js
cd nodejs-docs-samples/run/websockets/
Entenda o código do WebSocket
O Socket.io é uma biblioteca que permite a comunicação bidirecional em tempo real entre o navegador e o servidor. Embora o Socket.io não seja uma implementação WebSocket, ele une a funcionalidade para fornecer uma API mais simples para vários protocolos de comunicação com recursos adicionais, como maior confiabilidade, reconexão automática e transmissão para todos ou um subconjunto de clientes.
Integração no lado do cliente
O cliente instancia uma nova instância de soquete para cada conexão. Como este exemplo é renderizado no servidor, o URL do servidor não precisa ser definido. A instância de soquete pode emitir e ouvir eventos.
Integração no servidor
No servidor, o servidor Socket.io é inicializado e anexado ao servidor HTTP. Semelhante ao lado do cliente, uma vez que o servidor Socket.io faz uma conexão com o cliente, uma instância de soquete é criada para cada conexão que pode ser usada para emitir e ouvir mensagens. Ele também oferece uma interface para criar "salas" ou um canal arbitrário em que os soquetes podem entrar e sair.
O Socket.io também fornece um adaptador Redis para transmitir eventos para todos os clientes, independentemente de qual servidor está veiculando o soquete. O Socket.io usa apenas o mecanismo Pub/Sub do Redis e não armazena dados.
O adaptador Redis do Socket.io pode reutilizar o cliente Redis usado para armazenar o histórico de mensagens da sala. Cada contêiner cria uma conexão com a instância do Redis e o Cloud Run pode criar um grande número de instâncias. Isso está dentro das 65.000 conexões compatíveis com o Redis.
Reconexão
O Cloud Run tem um tempo limite máximo de 60 minutos. Portanto, você precisa adicionar a lógica de reconexão para possíveis tempos limite. Em alguns casos, o Socket.io tenta se reconectar automaticamente após eventos de desconexão ou erro de conexão. Não há garantia de que o cliente se reconectará à mesma instância de contêiner.
As instâncias vão persistir se houver uma conexão ativa até que todas as solicitações sejam encerradas ou expirem. Mesmo que você use a afinidade da sessão do Cloud Run, é possível que novas solicitações tenham a carga balanceada para contêineres ativos. Isso permite a redução do reduzir escalonamento horizontal. Se você estiver preocupado com um grande número de contêineres que persistem após um pico de tráfego, diminua o valor máximo de tempo limite para que os soquetes não utilizados sejam limpos com mais frequência.
Enviar o serviço
Crie uma instância do Memorystore para Redis:
gcloud redis instances create INSTANCE_ID --size=1 --region=REGION
Substitua:
- INSTANCE_ID: o nome da instância, por exemplo,
my-redis-instance. - REGION_ID: a região
de todos os seus recursos e serviços, por exemplo,
europe-west1.
A instância receberá automaticamente um intervalo de IP do intervalo de rede de serviço padrão. Neste tutorial, 1 GB de memória é usado para o cache local de mensagens na instância do Redis. Saiba mais sobre Como determinar o tamanho inicial de uma instância do Memorystore para seu caso de uso.
- INSTANCE_ID: o nome da instância, por exemplo,
Defina uma variável de ambiente com o endereço IP da rede autorizada da instância do Redis:
export REDISHOST=$(gcloud redis instances describe INSTANCE_ID --region REGION --format "value(host)")
Crie uma conta de serviço para servir como a identidade de serviço. Por padrão, ela não tem privilégios além da associação ao projeto.
gcloud iam service-accounts create chat-identity gcloud projects add-iam-policy-binding PROJECT_ID \ --member=serviceAccount:chat-identity@PROJECT_ID.iam.gserviceaccount.com \ --role=roles/serviceusage.serviceUsageConsumer
Encontre o nome da rede VPC autorizada pela instância do Redis executando o seguinte comando:
gcloud redis instances describe INSTANCE_ID --region REGION --format "value(authorizedNetwork)"
Substitua:
- INSTANCE_ID: o nome da instância, por exemplo,
my-redis-instance. - REGION_ID: a região
de todos os seus recursos e serviços, por exemplo,
europe-west1.
Anote o nome da rede VPC.
- INSTANCE_ID: o nome da instância, por exemplo,
Crie e implante a imagem do contêiner no Cloud Run:
gcloud run deploy chat-app --source . \ --allow-unauthenticated \ --timeout 3600 \ --service-account chat-identity \ --network NETWORK \ --subnet SUBNET \ --update-env-vars REDISHOST=$REDISHOST
Substitua:
- NETWORK é o nome da rede VPC autorizada a que a instância do Redis está anexada.
- SUBNET é o nome da sub-rede. A sub-rede precisa ser
/26ou maior. A saída de VPC direta é compatível com intervalos IPv4 RFC 1918, RFC 6598 e classe E.
Responda a todas as solicitações para instalar as APIs necessárias respondendo ao
yquando solicitado. Você só precisa fazer isso uma vez para um projeto. Responda a outras solicitações fornecendo a plataforma e a região, se você não tiver definido os padrões delas, conforme descrito na página de configuração. Saiba mais sobre como implantar a partir do código-fonte.
Testar o serviço
Para testar o serviço completo:
Navegue até o URL fornecido pela etapa de implantação.
Adicione seu nome e uma sala de chat para fazer login.
Envie uma mensagem para a sala.
Se você optar por continuar desenvolvendo esses serviços, lembre-se de que eles têm acesso restrito do Identity and Access Management (IAM, na sigla em inglês) ao restante do Google Cloud e precisarão receber mais papéis do IAM para acessar muitos outros serviços.
Limpar
Para evitar cobranças extras na sua conta do Google Cloud , exclua todos os recursos implantados com este tutorial.
Excluir o projeto
Se você criou um novo projeto para este tutorial, exclua-o. Se você usou um projeto atual e precisa mantê-lo sem as mudanças adicionadas neste tutorial, exclua os recursos criados para o tutorial.
O jeito mais fácil de evitar cobranças é excluindo o projeto que você criou para o tutorial.
Para excluir o projeto:
- In the Google Cloud console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- In the dialog, type the project ID, and then click Shut down to delete the project.
Excluir recursos do tutorial
Exclua o serviço do Cloud Run que você implantou neste tutorial. Os serviços do Cloud Run não geram custos até receberem solicitações.
Para excluir o serviço do Cloud Run, execute o seguinte comando:
gcloud run services delete SERVICE-NAME
SERVICE-NAME pelo nome do serviço;
Também é possível excluir os serviços do Cloud Run no console doGoogle Cloud .
Remova a configuração da região padrão do
gcloudque você adicionou durante a configuração do tutorial:gcloud config unset run/regionRemova a configuração do projeto:
gcloud config unset projectExclua outros recursos do Google Cloud criados neste tutorial:
- Exclua a imagem do contêiner com o nome
gcr.io/PROJECT_ID/chat-appdo Artifact Registry. - Exclua a conta de serviço
chat-identity@PROJECT_ID.iam.gserviceaccount.com - Exclua a instância do Memorystore para Redis
- Exclua a imagem do contêiner com o nome
A seguir
Saiba mais sobre como o Socket.io funciona e uso mais avançado.
Saiba mais sobre a saída de VPC direta com uma rede VPC.
Analise as práticas recomendadas para Memorystore e Como usar WebSockets no Cloud Run.