Quais são as considerações de implementação de filas de mensagens no processamento de webhooks
Se você processa um grande volume de webhooks, não é incomum enfrentar picos repentinos de tráfego. Esses picos podem consumir recursos rapidamente, o que leva à queda do servidor de processamento de webhooks.
Outro problema que pode surgir com picos de tráfego é o aumento do tempo de resposta de cada webhook. Praticamente todos os grandes produtores de webhooks (Shopify, Stripe, GitHub) impõem um limite rígido para o tempo de resposta de cada webhook. Se esse tempo for excedido, o produtor assume que o webhook falhou.
Para evitar esse tipo de problema, recomenda-se que o processamento de webhooks em grande volume seja feito de forma assíncrona. Uma das estratégias para processar webhooks de forma assíncrona é usar um message broker.
Neste artigo, vamos ver como o processamento assíncrono é feito com um message broker, com foco nas considerações de implementação e performance para colocar esse componente em produção.
Por que processar webhooks de forma assíncrona com um message broker?
Antes de começar, vamos entender o que é um message broker e como ele opera.
A função principal de um message broker é armazenar e distribuir mensagens de produtores para consumidores. O roteamento de mensagens até os consumidores é feito por meio de regras definidas no momento em que a mensagem é enviada ao broker. O broker usa essas regras para colocar a mensagem em uma fila, onde ela fica armazenada até ser consumida por um ou mais consumidores inscritos naquela fila.
Existem variações na forma como diferentes message brokers operam, com alguns usando o conceito de tópicos para definir um sistema de publish/subscribe. Mas o conceito é praticamente o mesmo: armazenar mensagens enviadas por produtores para serem consumidas por um ou mais consumidores.
Os consumidores buscam mensagens na taxa que conseguem processar, reduzindo a probabilidade de um consumidor ser sobrecarregado com requisições e sair do ar.
A maioria dos message brokers (se não todos) não suporta o protocolo HTTP usado no envio de webhooks. Portanto, para usar um message broker na ingestão de webhooks, você precisa fazer o proxy das requisições por meio de um API gateway.
O papel do API gateway é atuar como um middleware de conversão de protocolo, transformando as requisições HTTP dos webhooks no formato que o message broker suporta (por exemplo, AMQP e STOMP). Depois de traduzida, a mensagem é adicionada ao message broker (uma operação bastante rápida) e o produtor recebe imediatamente uma resposta assim que o broker confirma que a mensagem foi adicionada com sucesso.
Como os produtores enviam webhooks usando a versão segura do HTTP (HTTPS), os gateways frequentemente também ficam responsáveis pelo TLS termination.
Agora vamos ver alguns dos fatores importantes que você precisa considerar ao colocar o seu API gateway e o seu message broker em produção para garantir confiabilidade e recuperação de falhas.
Quais são as considerações de implementação para o API gateway?
Considerações de escalabilidade e performance
Como dito antes, os produtores costumam impor um limite rígido para o tempo de resposta de cada webhook. Esse limite significa que o API gateway tem um tempo máximo de requisição que ele não pode ultrapassar. Adicionar mensagens a um message broker é um processo bem rápido, e ainda que isso não seja preocupação, outras atividades executadas pelo gateway (descriptografia, definição de um trace id para monitoramento etc.) também precisam entrar na conta do tempo de resposta.
Além disso, cada tarefa que o gateway executa aumenta a latência total do processo à medida que o tráfego de webhooks cresce.
Imagine que você está entregando com sucesso um tempo de resposta de 3 segundos dentro de um limite de 5 segundos para 1000 webhooks concorrentes; esse limite será ultrapassado se o número de webhooks concorrentes dobrar de repente. Para lidar com a nova carga, você vai precisar escalar o seu API gateway.
Você pode optar por adicionar mais poder de processamento e memória ao servidor do gateway, mas essa abordagem sempre esbarra em um teto de performance.
O caminho recomendado é escalar o API gateway horizontalmente, implantando várias instâncias dele em um pool de workers e colocando um load balancer na frente.
O load balancer ajuda a distribuir o tráfego de webhooks entre o pool de gateways, e cada instância consegue processar e adicionar o webhook ao message broker rapidamente, resultando em tempos de resposta menores.
Provedores de nuvem como o Amazon API Gateway frequentemente oferecem escalabilidade pronta para uso, então talvez você nem precise se preocupar em escalar conforme o tráfego aumenta.
Quais são as considerações de implementação e escalabilidade para o message broker?
Escalabilidade
Message brokers costumam ter funcionalidades nativas para escalabilidade horizontal, mas ainda há limitações. Uma das principais é o throughput total de uma única fila, já que as mensagens que passam por ela precisam ser entregues a todos os assinantes conectados.
Embora brokers como RabbitMQ e ActiveMQ processem facilmente dezenas de milhares de mensagens por segundo, se você planeja processar centenas de milhares (ou milhões) de mensagens por segundo, talvez precise adicionar mecanismos de sharding customizados na sua aplicação para distribuir a carga entre várias instâncias do broker.
Uma das soluções para esse problema é o conceito de partições de tópico do Apache Kafka. As partições de tópico no Kafka podem ser usadas para dividir o trabalho de armazenar mensagens, escrever novas mensagens e processar mensagens existentes entre vários nós de um cluster de brokers.
Recuperação e durabilidade das mensagens
Um dos requisitos operacionais para processar webhooks em produção é a recuperação de falhas. No contexto de message brokers, a falha pode vir de um consumidor que se desconecta repentinamente do broker ou que rejeita uma mensagem por causa de um erro no processamento. Precisamos garantir que essas mensagens voltem para o pipeline de processamento.
Hoje em dia, todo broker suporta o conceito de dead letter queues. Uma dead letter queue guarda as mensagens rejeitadas. É possível se inscrever nessa fila para inspecionar problemas, disparar alertas e executar ações corretivas. É comum ver, em arquiteturas de webhooks, um componente de retry que usa essa fila para garantir que as mensagens com falha sejam reconciliadas.
Para garantir que você está lidando corretamente com situações de falha, recomenda-se que os consumidores confirmem explicitamente (ack) as mensagens de webhook consumidas do broker depois de processá-las com sucesso. Se ocorrer um erro no processo, o consumidor deve rejeitar a mensagem para que ela possa ser recolocada na fila ou enviada para a dead letter queue.
As mensagens também precisam ser declaradas explicitamente como duráveis e persistentes. Uma mensagem durável sobrevive a um reboot, enquanto uma mensagem persistente sobrevive à queda do servidor. No RabbitMQ, por exemplo, você precisa definir o parâmetro durable da mensagem como true para torná-la durável e configurar as mensagens como persistentes.
Performance
Para garantir que o seu broker tenha bom desempenho, você precisa coletar e monitorar métricas de uso. Essas métricas fornecem dados acionáveis que ajudam a refinar a configuração do broker para ganhar eficiência. Abaixo estão algumas métricas e funcionalidades de message broker que vale considerar ao decidir qual usar:
- Número de mensagens publicadas por segundo
- Tamanho médio das mensagens
- Número de mensagens consumidas por segundo
- Número de publicadores concorrentes
- Número de consumidores concorrentes
- Suporte a mensagens persistentes
- Suporte a acknowledgment de mensagens
Para saber mais sobre como medir e analisar a performance de um message broker, confira o nosso artigo sobre métricas de performance para uma solução de webhooks.
Conclusão
Neste artigo, vimos como um message broker pode ser usado para processar webhooks de forma assíncrona, garantindo que picos de tráfego ou aumentos de volume não derrubem o servidor de processamento. Também nos aprofundamos nas considerações de implementação e performance do message broker e do API gateway necessário para fazer o proxy das mensagens de webhook até o broker.
Este artigo é um recorte da nossa série completa sobre como construir uma solução de webhooks com padrão de produção. Se você quer uma análise de ponta a ponta, com mais detalhes sobre cada aspecto da solução, pode começar a série aqui.
Infraestrutura de webhooks, gerenciada para você
A Hookdeck cuida da ingestão, entrega, observabilidade e recuperação de erros — para que você não precise.