Usando Apache Kafka na prática
Apache Kafka é uma das ferramentas mais utilizadas para comunicação assíncrona e processamento de eventos em sistemas distribuídos. Neste artigo veremos os principais conceitos do Kafka, quando utilizá-lo e alguns exemplos práticos.
O que é Apache Kafka?
Apache Kafka é uma plataforma de streaming distribuída criada para processar grandes volumes de dados em tempo real.
Diferente de uma comunicação síncrona entre serviços, onde uma aplicação precisa esperar pela resposta da outra, no Kafka as mensagens são enviadas para tópicos e consumidas posteriormente pelos serviços interessados.
Isso permite construir aplicações mais desacopladas, escaláveis e resilientes.
Conceitos principais
Producer
É a aplicação responsável por publicar mensagens em um tópico.
Exemplo:
- Um serviço de pedidos envia o evento OrderCreated.
Consumer
É a aplicação que consome mensagens dos tópicos.
Exemplo:
- Um serviço de notificações recebe o evento OrderCreated e envia um e-mail ao cliente.
Topic
É onde as mensagens ficam armazenadas.
Um tópico pode conter milhares ou milhões de eventos.
Exemplos:
- orders
- payments
- notifications
Partition
As partições permitem distribuir os dados entre vários servidores, aumentando a escalabilidade do Kafka.
Quanto mais partições, maior a capacidade de processamento paralelo.
Quando utilizar Kafka?
Kafka é uma excelente escolha quando:
- Existem múltiplos serviços que precisam reagir aos mesmos eventos;
- Há necessidade de processar grandes volumes de dados;
- É importante desacoplar sistemas;
- O processamento pode ser assíncrono;
- Existem requisitos de alta disponibilidade.
Alguns exemplos:
- E-commerce;
- Sistemas financeiros;
- Processamento de pagamentos;
- Sistemas de monitoramento;
- Logs e métricas;
- Integrações entre microsserviços.
Exemplo prático
Imagine um e-commerce.
Quando um pedido é criado, diversos serviços precisam ser notificados:
- Estoque;
- Pagamentos;
- E-mail;
- Faturamento.
Em vez de chamar todos os serviços diretamente, a API publica um evento:
OrderCreated
Os consumidores interessados recebem esse evento e executam suas tarefas de forma independente.
Cliente
↓
API Pedidos
↓
Kafka (orders)
↓
┌─────────────┬─────────────┬─────────────┐
│ Estoque │ Pagamento │ Notificação │
└─────────────┴─────────────┴─────────────┘
Essa abordagem reduz acoplamento e facilita a evolução do sistema.
Criando um Producer em .NET
Utilizando a biblioteca Confluent.Kafka:
var config = new ProducerConfig
{
BootstrapServers = "localhost:9092"
};
using var producer = new ProducerBuilder<string, string>(config).Build();
await producer.ProduceAsync(
"orders",
new Message<string, string>
{
Key = "1",
Value = "Pedido criado"
});
A mensagem será enviada para o tópico orders.
Criando um Consumer
var config = new ConsumerConfig
{
BootstrapServers = "localhost:9092",
GroupId = "notification-service",
AutoOffsetReset = AutoOffsetReset.Earliest
};
using var consumer = new ConsumerBuilder<string, string>(config).Build();
consumer.Subscribe("orders");
while (true)
{
var message = consumer.Consume();
Console.WriteLine(message.Message.Value);
}
Esse consumidor ficará ouvindo o tópico e processando as mensagens recebidas.
Kafka x Banco de Dados
Uma dúvida comum é pensar que o Kafka substitui um banco de dados.
Na verdade, eles possuem propósitos diferentes.
Banco de dadosKafkaArmazenamento de dadosStreaming de eventosConsultasProcessamento em tempo realCRUDComunicação assíncronaEstado atualHistórico de eventos
Normalmente ambos trabalham juntos.
Dicas para trabalhar com Kafka
1. Utilize eventos bem definidos
Prefira nomes como:
- OrderCreated
- PaymentApproved
- UserRegistered
Eventos representam fatos que já aconteceram.
2. Evite mensagens gigantes
Quanto menores forem as mensagens, melhor será a performance.
Em muitos casos, enviar apenas o ID da entidade é suficiente.
{
"orderId": 100
}
O consumidor pode buscar as informações necessárias posteriormente.
3. Planeje as partições
As partições influenciam diretamente na capacidade de processamento e paralelismo.
Um número inadequado pode gerar gargalos futuros.
4. Trate falhas
Nem sempre o processamento será bem-sucedido.
Implemente:
- Retry;
- Dead Letter Queue;
- Logs e observabilidade.
5. Mantenha consumidores idempotentes
Uma mesma mensagem pode ser processada mais de uma vez.
Por isso, os consumidores devem ser preparados para evitar efeitos duplicados.
Vantagens do Kafka
- Alta performance;
- Escalabilidade horizontal;
- Processamento em tempo real;
- Persistência das mensagens;
- Desacoplamento entre serviços;
- Alta disponibilidade.
Desvantagens
- Curva de aprendizado maior;
- Infraestrutura mais complexa;
- Necessidade de monitoramento;
- Planejamento de tópicos e partições.
Quando não utilizar?
Kafka pode ser um exagero para:
- Pequenos sistemas;
- Aplicações monolíticas simples;
- Processos que precisam de resposta imediata;
- Filas de baixo volume.
Nesses cenários, RabbitMQ ou até chamadas HTTP podem ser suficientes.
Conclusão
Apache Kafka é uma excelente ferramenta para sistemas distribuídos e aplicações orientadas a eventos. Sua capacidade de processar grandes volumes de mensagens e desacoplar serviços faz dele uma das soluções mais utilizadas em arquiteturas modernas.
Entretanto, é importante avaliar a complexidade do ambiente antes de adotá-lo. Em muitos casos, uma solução mais simples pode atender perfeitamente às necessidades do projeto.
Saiba mais
- Apache Kafka Documentation
https://kafka.apache.org/documentation/ - Confluent Kafka .NET Client
https://github.com/confluentinc/confluent-kafka-dotnet - Apache Kafka Quick Start
https://kafka.apache.org/quickstart - Confluent Developer
https://developer.confluent.io/ - Designing Event-Driven Systems
https://www.confluent.io/designing-event-driven-systems/