Kafka e o Primeiro Evento

Garantias: at-least-once, at-most-once, exactly-once

Você aplica garantias de entrega no Kafka com foco em confiabilidade para fluxos de negócio.

Avançado 45 min 30 pontos Leitura 0%

Nesta aula você vai

  • Diferenciar at-most-once, at-least-once e exactly-once
  • Configurar producer e consumer para comportamento previsível
  • Escolher estratégia adequada para customer.created

Garantias: at-least-once, at-most-once, exactly-once

Objetivos

  • Diferenciar at-most-once, at-least-once e exactly-once
  • Configurar producer e consumer para comportamento previsível
  • Escolher estratégia adequada para customer.created

Pré-requisitos

  • Tópico Kafka configurado
  • Producer/consumer básicos funcionando
  • Conhecimento de retries e falhas transitórias

Conceito

Garantia de entrega sempre envolve trade-off. at-most-once pode perder mensagem, mas evita duplicata. at-least-once evita perda, mas pode duplicar. exactly-once reduz duplicata e perda, porém aumenta custo e complexidade.

No início de um sistema distribuído, a escolha mais prática costuma ser at-least-once com consumidor idempotente. É robusto, simples de operar e cobre bem eventos de integração como customer.created.

Nesta aula, você configura producer com acks=all e consumidor com commit manual após processamento bem-sucedido para tornar o comportamento explícito.

Estrutura de arquivos

services/
  customer-service/src/main/java/.../KafkaCustomerPublisher.java
  order-service/app/consumers/customer_created_consumer.py
  order-service/app/service/customer_projection_service.py
infra/docker-compose.yml

Passo a passo

  1. Configurar producer Java com confirmação forte
Properties props = new Properties();
props.put("bootstrap.servers", "kafka:9092");
props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("acks", "all");
props.put("retries", "5");
props.put("enable.idempotence", "true");
  1. Configurar consumer Python com commit manual
consumer = KafkaConsumer(
    "customer.created.v1",
    bootstrap_servers="kafka:9092",
    group_id="order-service-customer-group",
    enable_auto_commit=False,
    auto_offset_reset="earliest",
)
  1. Processar e commitar somente após sucesso
for msg in consumer:
    event = json.loads(msg.value.decode("utf-8"))
    try:
        projection_service.upsert_customer(event)
        consumer.commit()
        print(f"commit realizado offset={msg.offset}")
    except Exception as exc:
        print(f"erro no processamento offset={msg.offset}: {exc}")
  1. Implementar idempotência simples na projeção
class CustomerProjectionService:
    _seen_events = set()

    def upsert_customer(self, event: dict):
        event_id = event["eventId"]
        if event_id in self._seen_events:
            return
        self._seen_events.add(event_id)
        # atualiza projeção local

Como testar

  1. Subir ambiente:
docker compose -f infra/docker-compose.yml up --build -d kafka customer-service order-service
  1. Publicar duas vezes o mesmo evento (mesmo eventId) e verificar idempotência:
docker compose -f infra/docker-compose.yml exec kafka \
  kafka-console-producer.sh --bootstrap-server kafka:9092 --topic customer.created.v1

Mensagem enviada duas vezes:

{"eventId":"evt-duplicado-1","customerId":"c-9","email":"c9@aprendi.dev","occurredAt":"2026-07-03T18:20:00Z"}
  1. Ver logs do consumidor:
docker compose -f infra/docker-compose.yml logs -f order-service

Saída esperada: processamento uma vez e commits sem erro.

Dicas de projeto

  • Para integração de domínio, prefira at-least-once + idempotência.
  • Faça commit de offset apenas após persistência concluída.
  • Registre eventId, partition e offset em log.
  • Teste cenários de falha entre processamento e commit.

Erros comuns

  • Usar auto commit com processamento demorado.
  • Assumir exactly-once sem validar consumidor.
  • Não implementar deduplicação por eventId.
  • Ignorar retries do producer.

Resumo

Você aplicou uma estratégia de entrega robusta para o primeiro evento do projeto: producer confiável, commit manual e idempotência. Isso reduz perda de mensagem e prepara o fluxo ponta a ponta.