Neste tutorial, você verá como criar um serviço de chat em tempo real com várias salas usando WebSockets com conexão persistente para comunicação bidirecional. Com o 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.
Visão geral do design
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 para não confundir com o produto Cloud Pub/Sub, para enviar dados a clientes inscritos conectados a qualquer instância, visando eliminar 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. Portanto, é necessário um conector de acesso VPC sem servidor para que o serviço do Cloud Run se conecte ao Redis. Saiba mais sobre o acesso VPC sem servidor.
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 conectores de acesso VPC sem servidor.
Custos
Neste documento, você usará os seguintes componentes faturáveis do Google Cloud:
Para gerar uma estimativa de custo baseada na projeção de uso deste tutorial, use 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.
-
Make sure 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.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Cloud Run, Memorystore for Redis, Serverless VPC Access, Artifact Registry, and Cloud Build APIs.
- Instale e inicialize a CLI gcloud.
Funções exigidas
Para conseguir as permissões necessárias para concluir o tutorial, peça ao administrador para conceder a você os seguintes papéis do IAM no seu projeto:
-
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
) -
Agente de serviço de acesso VPC sem servidor (
roles/vpcaccess.serviceAgent
) -
Administrador da conta de serviço (
roles/iam.serviceAccountAdmin
) -
Consumidor do Service Usage (
roles/serviceusage.serviceUsageConsumer
)
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.
Configuração dos padrões 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 produtos do Google Cloud 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 CO2europe-southwest1
(Madri) Baixo CO2europe-west1
(Bélgica) Baixo CO2europe-west4
(Países Baixos) Baixo CO2europe-west8
(Milão)europe-west9
(Paris) Baixo CO2me-west1
(Tel Aviv)us-central1
(Iowa) Baixo CO2us-east1
(Carolina do Sul)us-east4
(Norte da Virgínia)us-east5
(Columbus)us-south1
(Dallas) Baixo CO2us-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) Baixo CO2europe-west12
(Turim)europe-west2
(Londres, Reino Unido) Baixo CO2europe-west3
(Frankfurt, Alemanha) Baixo CO2europe-west6
(Zurique, Suíça) Baixo CO2me-central1
(Doha)me-central2
(Damã)northamerica-northeast1
(Montreal) Baixo CO2northamerica-northeast2
(Toronto) Baixo CO2southamerica-east1
(São Paulo, Brasil) Baixo CO2southamerica-west1
(Santiago, Chile) Baixo CO2us-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 do Google Cloud.
Como recuperar o exemplo 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/
Noções básicas sobre o código
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 transmitir 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 fácil 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 de contêiner. Isso está dentro das 65.000 conexões compatíveis com o Redis. Se você precisa oferecer suporte a essa quantidade de tráfego, também precisa avaliar a capacidade do conector de acesso VPC sem servidor.
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 de contêiner persistirão 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 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.
Como 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 pelo nome da instância, ou seja,
my-redis-instance
, e REGION_ID pela região de todos os seus recursos e serviços, ou seja,us-central1
.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.
Configure um conector de acesso VPC sem servidor:
Para se conectar à instância do Redis, o serviço do Cloud Run (totalmente gerenciado) precisa acessar a rede VPC autorizada da instância do Redis.
Cada conector VPC requer a própria sub-rede
/28
para colocar instâncias de conector. Ele não pode sobrepor nenhuma reserva de endereço IP atual na rede VPC. Por exemplo,10.8.0.0
(/28
) funcionará na maioria dos novos projetos, ou é possível especificar outro intervalo de IP personalizado não utilizado, como10.9.0.0
(/28
). É possível ver quais intervalos de IP estão reservados no console do Google Cloud.gcloud compute networks vpc-access connectors create CONNECTOR_NAME \ --region REGION \ --range "10.8.0.0/28"
Substitua CONNECTOR_NAME pelo nome do conector.
Esse comando cria um conector na rede VPC padrão, igual à instância do Redis, com tamanho de máquina
e2-micro
. Aumentar o tamanho da máquina do conector melhora a capacidade do conector, mas também aumenta o custo. O conector também precisa estar na mesma região da instância do Redis. Saiba mais sobre Como configurar o acesso VPC sem servidor.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, isso 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
Crie e implante a imagem do contêiner no Cloud Run:
gcloud run deploy chat-app --source . \ --vpc-connector CONNECTOR_NAME \ --allow-unauthenticated \ --timeout 3600 \ --service-account chat-identity \ --update-env-vars REDISHOST=$REDISHOST
Responda a todas as solicitações para instalar as APIs necessárias respondendo ao
y
quando 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
Para testar o serviço completo:
Navegue até o URL fornecido pela etapa de implantação acima.
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 gerenciamento de identidade e acesso (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
Se você criou um novo projeto para este tutorial, exclua o projeto. Se você usou um projeto atual e quer mantê-lo sem as alterações incluídas neste tutorial, exclua os recursos criados para o tutorial.
Como excluir o projeto
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.
Como excluir recursos do tutorial
Exclua o serviço do Cloud Run que você implantou neste tutorial:
gcloud run services delete SERVICE-NAME
SERVICE-NAME é o nome escolhido do serviço.
Também é possível excluir os serviços do Cloud Run no Console do Google Cloud.
Remova a configuração da região padrão da gcloud que você adicionou durante a configuração do tutorial:
gcloud config unset run/region
Remova a configuração do projeto:
gcloud config unset project
Exclua outros recursos do Google Cloud criados neste tutorial:
- Exclua a imagem do contêiner com o nome
gcr.io/PROJECT_ID/chat-app
do Artifact Registry. - Exclua a conta de serviço
chat-identity@PROJECT_ID.iam.gserviceaccount.com
- Exclua a instância do Memorystore para Redis
- Excluir o conector de acesso VPC sem servidor
- 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 Como configurar o acesso VPC sem servidor.
Analise as práticas recomendadas para Memorystore e Como usar WebSockets no Cloud Run.
Explore as Ferramentas de diagnóstico de acesso VPC sem servidor para solucionar problemas de rede sem servidor.