Saltar para o conteúdo

Guias

Dashboards em tempo real com Laravel, Redis e WebSockets

· 6 min de leitura

O Laravel consegue alimentar dashboards em tempo real sobre fluxos de grande volume desde que os eventos brutos nunca cheguem ao browser: pôr a ingestão num buffer em Redis, processá-la em workers com filas, pré-agregar em intervalos de tempo e difundir por WebSockets apenas resumos. Os alertas devem assentar em limiares dinâmicos aprendidos com o histórico recente, e não em limites fixos, e uma plataforma de streaming dedicada entra quando as necessidades de replay, de ordenação ou de volume ultrapassam as filas Redis.

Manter os eventos brutos longe do browser

O erro mais comum nos dashboards em tempo real é enviar cada evento recebido para todos os ecrãs ligados. Com grande volume, os browsers ficam para trás, o servidor WebSocket satura e o gráfico torna-se ilegível de qualquer forma.

Divida o sistema em quatro etapas: ingestão, processamento, agregação e difusão. Cada etapa tem a sua própria capacidade e pode abrandar sem arrastar as outras. O dashboard recebe atualizações agregadas a um ritmo fixo, por exemplo uma vez por segundo por painel, e não eventos brutos.

Os nossos engenheiros usaram esta estrutura na Slump, uma plataforma de monitorização em tempo real das tendências da rede 5G, dos indicadores de capacidade e da previsão de saturação para operadores de todo o sul de Espanha, construída sobre um back end Laravel 11 e 12 que ingere dados de streaming de grande volume.

Pôr a ingestão num buffer para que os picos de tráfego não se tornem falhas

O endpoint de ingestão deve fazer o mínimo possível: validar o payload, acrescentá-lo a um buffer e responder. A análise, o enriquecimento e as escritas na base de dados pertencem aos workers.

Com volumes moderados, o Redis funciona bem como buffer. Envie os eventos para uma lista ou um stream Redis e deixe os workers ir buscá-los em lotes, porque uma inserção em lote é muito mais barata para a base de dados do que centenas de inserções de uma só linha.

  • Validar o esquema e rejeitar os eventos mal formados logo à entrada
  • Responder depressa e nunca escrever na base de dados principal dentro do pedido
  • Ler do buffer em lotes, e não um evento por job
  • Limitar o tamanho do buffer e alertar quando cresce, para que a contrapressão fique visível antes de se transformar em perda de dados

Escalar o processamento com filas separadas e o Horizon

As filas Laravel assentes em Redis dão workers que se podem acrescentar horizontalmente. O Laravel Horizon mostra o número de workers, o débito e os tempos de espera por fila, e é assim que se verifica se o processamento acompanha a ingestão.

Separe as filas por prioridade. A avaliação dos alertas nunca deve esperar atrás de um atraso de reprocessamento histórico, por isso dê ao processamento, à agregação, aos alertas e às exportações as suas próprias filas e grupos de workers.

Torne cada job idempotente. Os streams reenviam mensagens, os workers falham a meio de um lote e há novas tentativas, por isso processar o mesmo evento duas vezes não pode duplicar um contador. Um identificador de evento verificado num conjunto Redis de curta duração basta muitas vezes.

Agregar em intervalos de tempo antes de difundir

Os dashboards mostram taxas, médias, percentis e tendências, não eventos individuais. Calcule-os nos workers em intervalos de tempo fixos, por exemplo por segundo e por minuto, para cada entidade apresentada: uma célula, uma região, um cliente.

Mantenha os agregados em direto no Redis, com hashes ou sorted sets indexados por intervalo, e escreva cada intervalo fechado na base de dados para o histórico. O desenho das consultas sobre essas tabelas de histórico pesa tanto como o caminho em direto, porque os utilizadores vão querer ver um dia ou uma semana inteira.

Na Slump, o redesenho da cache Redis e a otimização das consultas reduziram a latência de ingestão, e foi isso que manteve a vista em direto atualizada sob carga.

Difundir resumos por WebSockets com o Reverb ou um serviço alojado

O broadcasting do Laravel envia eventos para canais aos quais o front end se subscreve através do Laravel Echo. O Laravel Reverb é o servidor WebSocket oficial do Laravel, e serviços alojados como o Pusher ou o Ably funcionam através da mesma API de broadcasting.

  • Difundir com um temporizador a partir do estado agregado, e não uma vez por cada evento recebido
  • Usar canais privados e autorizar cada subscrição no servidor, para que os utilizadores vejam apenas as entidades a que têm acesso
  • Enviar snapshots compactos ou deltas, e não conjuntos de dados completos
  • Ao voltar a ligar, o cliente deve carregar o estado atual por HTTP e depois retomar o fluxo
  • Correr várias instâncias do Reverb atrás de um balanceador de carga, com pub/sub Redis entre elas, à medida que o número de ligações cresce

Alertar com limiares dinâmicos em vez de limites fixos

Os limiares fixos falham nos dois sentidos em métricas de streaming. O tráfego às 3 da manhã não tem nada a ver com o tráfego às 20h, por isso um limite único ou dispara a noite toda ou deixa escapar os problemas durante o dia.

Um limiar dinâmico compara cada novo valor com uma referência aprendida com o histórico recente da mesma entidade, à mesma hora da semana. Uma versão simples e explicável mantém uma média móvel e um desvio-padrão por entidade e por hora da semana, e lança um alerta quando o valor fica fora dessa banda durante vários intervalos consecutivos.

Na Slump, os alertas dinâmicos de anomalias reduziram a monitorização manual, porque os operadores eram chamados para desvios reais em vez de ficarem a vigiar ecrãs.

  • Exigir persistência, por exemplo três intervalos consecutivos fora da banda, para reduzir o ruído
  • Manter um único alerta aberto por entidade e condição, atualizado em vez de repetido
  • Incluir em cada alerta o valor atual, a referência, a banda e uma ligação para o painel
  • Rever regularmente os alertas silenciados e ignorados e ajustar a banda

Saber quando acrescentar uma tecnologia de streaming dedicada

O Laravel com Redis cobre muito terreno, mas tem limites. Considere o Kafka, o Redpanda ou um serviço de streaming gerido, muitas vezes com um processador de streams como o Apache Flink, quando precisar de retenção longa e de replay dos eventos brutos, de ordenação estrita por chave entre muitos consumidores, ou de um débito que faça da memória do Redis o ponto de estrangulamento.

A mudança não tem de ser feita de uma só vez. Mantenha o Laravel para a API, os dashboards, a gestão de alertas e o broadcasting, e coloque o stream à frente da etapa de agregação. Construímos e fazemos evoluir sistemas em tempo real com esta estrutura, da ingestão às regras de alerta em que os operadores confiam.

Pontos essenciais

  • Nunca enviar eventos brutos para os browsers; difundir resumos agregados a um ritmo fixo.
  • Manter o endpoint de ingestão leve e pôr os eventos num buffer Redis para processamento em lote pelos workers.
  • Separar as filas por prioridade e tornar cada job idempotente, para que as novas tentativas não corrompam os contadores.
  • Os limiares dinâmicos baseados no histórico recente produzem menos alertas, e mais úteis, do que os limites fixos.
  • Acrescentar o Kafka ou uma plataforma semelhante quando for preciso replay, ordenação estrita ou um volume acima do que o Redis aguenta, e manter o Laravel na camada aplicacional.

Perguntas frequentes

O Laravel aguenta dashboards em tempo real com grandes volumes de dados?

Sim, quando a arquitetura mantém o trabalho pesado fora do caminho do pedido: um endpoint de ingestão leve, um buffer Redis, workers com filas que agregam em intervalos de tempo, e difusões por WebSocket apenas de resumos. O Laravel serve então a API, os dashboards e os alertas, enquanto os workers escalam de forma independente.

Laravel Reverb ou Pusher para WebSockets?

O Reverb é o servidor WebSocket oficial do Laravel e corre na infraestrutura da própria empresa, o que convém às equipas que querem controlar o custo e a localização dos dados. O Pusher ou o Ably eliminam o trabalho de operar servidores WebSocket. Ambos usam a mesma API de broadcasting do Laravel, por isso é possível mudar mais tarde.

O que é um limiar dinâmico em monitorização?

Um limiar dinâmico é um limite de alerta calculado a partir do histórico recente da mesma métrica, da mesma entidade e da mesma hora da semana, em vez de um número fixo. Adapta-se aos padrões diários e semanais, para que os alertas disparem perante desvios reais e não perante picos normais.

Diga-nos do que precisa.

Algo para construir, pessoas para encontrar ou uma questão por resolver. Numa chamada de 30 minutos, ouvimos e dizemos com franqueza como podemos ajudar e o que seria necessário.

Marcar uma chamada

30 minutos, em francês ou inglês. Gratuito.

Prefere escrever? Envie antes um breve resumo.