Arquitetura real · Pleno
Slack: mensagens em tempo real (gateways, channel servers, Flannel)
Arquitetura real em produção. Pontos centrais: WebSocket e presença e consistent hashing.
Resposta curta
Arquitetura real em produção. Pontos centrais: WebSocket e presença e consistent hashing. Um aplicativo de trabalho precisa entregar cada mensagem a quem está online no canal, rápido e em qualquer parte do mundo.
01 · CONTEXTO
Mensagens em tempo real para muita gente
Um aplicativo de trabalho precisa entregar cada mensagem a quem está online no canal, rápido e em qualquer parte do mundo.
No Slack, todo cliente mantém uma conexão websocket persistente para receber eventos em tempo real e manter seu estado.
A infraestrutura de mensagens do Slack é feita de quatro serviços centrais, todos escritos em Java: Channel Servers, Gateway Servers, Admin Servers e Presence Servers. Segundo o próprio post, os servidores atendem dezenas de milhões de canais por host e dezenas de milhões de clientes conectados, e entregam mensagens pelo mundo em 500 ms.
02 · OS QUATRO SERVIÇOS
Quem faz o quê
| Serviço | Estado | Papel |
|---|---|---|
| Channel Server (CS) | Com estado, em memória | Mapeado a um subconjunto de canais por consistent hashing |
| Gateway Server (GS) | Com estado, em memória | Guarda informações do usuário e as assinaturas de canal do websocket |
| Admin Server (AS) | Sem estado, em memória | Faz a interface entre o backend Webapp e os CSs |
| Presence Server (PS) | Em memória | Sabe quais usuários estão online |
O GS é a interface entre os clientes e os CSs. Diferente dos outros servidores, ele é implantado em várias regiões geográficas, o que permite ao cliente conectar rápido a um host da região mais próxima. Para falhas de região há um mecanismo de drenagem que leva os usuários de uma região ruim à região boa mais próxima.
A presença, os pontos verdes do aplicativo, vem dos PSs: os usuários são hasheados para PSs individuais e o cliente faz as consultas pelo websocket, com o GS como proxy. O cliente só recebe notificações de presença de um subconjunto de usuários visíveis na tela.
03 · CHANNEL SERVERS E O ANEL
Cada canal tem um dono
Cada CS guarda em memória parte do histórico dos canais que lhe cabem. O ID do canal é hasheado e mapeado a um servidor único, por consistent hashing. Nos picos, cerca de 16 milhões de canais são servidos por host; e “canal” é um termo abstrato cujo ID é atribuído a uma entidade como usuário, time, empresa, arquivo, huddle ou canal comum.
Os canais de um mesmo time ficam espalhados por todos os CSs. Os CHARMs gerenciam o anel e substituem CSs não saudáveis; um novo CS fica pronto para atender em menos de 20 segundos. Quando um CS é substituído, os usuários dos canais dele veem latência elevada na entrega por menos de 20 segundos. Cada anel é definido e gerido pelos CHARMs, e AS e CSs descobrem a configuração consultando o Consul.
O anel é definido e gerido pelos CHARMs, e o Admin Server o descobre consultando o Consul.
O ID do canal é hasheado e mapeado a um Channel Server único.
Quando um CS não está saudável, o CHARM o substitui rapidamente; os usuários dos canais dele veem latência elevada na entrega por menos de 20 segundos.
04 · CONEXÃO DO CLIENTE
Do app ao websocket
Na inicialização, o cliente busca no Webapp o token e os dados para montar o websocket. Ele abre a conexão na região de borda mais próxima, e o Envoy, usado no Slack como balanceador de carga e terminação TLS, encaminha o pedido ao GS.
O cliente pede ao Webapp o token e os dados de conexão websocket.
O cliente abre o websocket na região de borda mais próxima e o Envoy o encaminha ao Gateway Server.
O GS busca no Webapp os dados do usuário, incluindo seus canais, e manda a primeira mensagem ao cliente.
Por consistent hashing, o GS assina de forma assíncrona os Channel Servers que hospedam esses canais.
Com isso, o cliente está pronto para enviar e receber mensagens em tempo real.
05 · MENSAGENS E EVENTOS
Do envio à tela dos outros
Enviar uma mensagem começa numa chamada à API do Webapp. O Webapp a entrega ao AS, que olha o ID do canal, descobre o CS pelo anel e a roteia ao CS responsável. O CS a envia a todo GS do mundo assinado ao canal, e cada GS a entrega a cada cliente conectado inscrito.
O cliente A chama a API do Webapp para enviar a mensagem.
O Webapp passa a mensagem ao AS, que acha pelo anel o CS do canal e a roteia a ele.
O CS envia a mensagem a cada GS assinado ao canal, de qualquer região.
Cada GS entrega a mensagem aos clientes conectados e inscritos no canal.
Além das mensagens, existem eventos: qualquer atualização em tempo real que muda o estado do cliente. Há centenas de tipos, como reações, favoritos adicionados e entrada de membros num canal, e eles seguem uma jornada parecida com a da mensagem. Lembretes, mensagens agendadas e eventos de calendário tendem a ocorrer no começo da hora, o que explica picos regulares de tráfego.
Eventos transitórios não são persistidos no banco e seguem um fluxo um pouco diferente; digitar num canal é um exemplo. Nesse caso, o cliente envia pelo websocket ao GS, que roteia ao CS pelo anel.
O cliente A, ao digitar, envia o evento pelo websocket ao seu GS.
O GS olha o ID do canal e roteia o evento ao CS responsável pelo anel.
O CS envia o evento a todos os GSs assinados ao canal, que o repassam aos clientes inscritos.
06 · FLANNEL
Cache na borda para a partida do app
Antes do Flannel, o servidor enviava ao cliente um snapshot completo dos dados do time pela chamada rtm.start e o cliente abria um WebSocket para os eventos. O cliente usava esses dados para se inicializar e abria um WebSocket para o fluxo de eventos. Em times muito grandes, o tempo de conexão ficava longo e a memória do cliente crescia; além disso, as tempestades de reconexão, como a de um escritório inteiro conectando de uma vez, são intensivas em recursos.
O Flannel é um serviço de cache em nível de aplicação, desenvolvido internamente e implantado nos pontos de presença de borda. Na partida do cliente ele guarda em cache dados de usuários, canais e bots e oferece APIs de consulta sob demanda; ele também antecipa dados, como o de um usuário mencionado, e os envia antes da mensagem para poupar uma consulta ao cliente.
O cliente se conecta ao Flannel.
O Flannel reúne os dados completos de inicialização e abre um WebSocket para os servidores do Slack na região AWS principal, para consumir eventos em tempo real.
O Flannel devolve ao cliente uma versão reduzida dos dados de inicialização, com a qual ele se inicializa.
Por consistent hashing, usuários do mesmo time e da mesma região de rede são direcionados à mesma instância do Flannel.
O Flannel usa consistent hashing para escolher o host a que o usuário conecta, mantendo afinidade de time: usuários do mesmo time e da mesma região de rede vão à mesma instância, para eficiência do cache. Usuários novos ou recém-desconectados são atendidos direto do cache, o que reduz o impacto das tempestades de reconexão nos servidores de backend. Segundo o post, o Flannel atendia, no pico, 4 milhões de conexões simultâneas e 600 mil consultas de cliente por segundo; o tamanho dos dados de inicialização foi reduzido 7 vezes num time de 1,5 mil usuários e 44 vezes num de 32 mil.
Como trabalho futuro, o post propõe mover o fanout de eventos para o Flannel, enviando uma cópia por servidor Flannel, e mover os clientes a um modelo pub/sub; com as atualizações de presença já migradas, os eventos de presença recebidos pelos clientes foram reduzidos por um fator de 5.
07 · O QUE LEVAR PARA UMA ENTREVISTA
Perguntas que o desenho responde
Um roteiro útil para um chat em tempo real é dividir as responsabilidades: uma camada segura as conexões dos clientes, outra decide quem é o dono de cada canal, e uma terceira entrega para quem está inscrito. Vale justificar cada divisão e dizer o que acontece quando uma peça é trocada.
Perguntas frequentes
O que é Slack: mensagens em tempo real (gateways, channel servers, Flannel)?
Arquitetura real em produção. Pontos centrais: WebSocket e presença e consistent hashing.
O que o design de Slack: mensagens em tempo real (gateways, channel servers, Flannel) cobre?
Ele está organizado nestas seções: Mensagens em tempo real para muita gente, Quem faz o quê, Cada canal tem um dono, Do app ao websocket, Do envio à tela dos outros e Cache na borda para a partida do app.
Quanto tempo leva Slack: mensagens em tempo real (gateways, channel servers, Flannel) e qual é o nível?
Leva cerca de 15 minutos para ler e tem nível Pleno.
Agora projete você mesmo
Rode este caso como uma entrevista na escola de System Design: você toma as decisões, o tutor as questiona e você vê a nota do seu desenho.