Integração do Spring Boot com RabbitMQ: Configuração e Uso Avançado

A integração do Spring Boot com o RabbitMQ permite a comunicação assíncrona e confiável entre serviços. Este guia aborda a configuração básica, padrões de mensagens, mecanismos de confirmação e tópicos avançados como filas de mensagens mortas.

  1. Configuração Básica e Padrão de Troca Direta

Para começar, adicione a dependência AMQP ao seu projeto.


<dependency>
    <groupid>org.springframework.boot</groupid>
    <artifactid>spring-boot-starter-amqp</artifactid>
</dependency>

Configure as propriedades de conexão no arquivo application.yml.


spring:
  rabbitmq:
    host: localhost
    port: 5672
    username: usuario
    password: senha
    virtual-host: /meu_vhost

Defina a configuração do RabbitMQ, incluindo filas, trocas e associações. O exemplo abaixo demonstar a configuração de uma troca do tipo fanout.


@Configuration
public class RabbitMqConfig {

    @Bean
    public Queue filaNotificacaoEmail() {
        return new Queue("notificacao.email.fila", true);
    }

    @Bean
    public Queue filaNotificacaoSms() {
        return new Queue("notificacao.sms.fila", true);
    }

    @Bean
    public FanoutExchange trocaNotificacao() {
        return new FanoutExchange("troca.notificacao.broadcast");
    }

    @Bean
    public Binding ligacaoEmail() {
        return BindingBuilder.bind(filaNotificacaoEmail()).to(trocaNotificacao());
    }

    @Bean
    public Binding ligacaoSms() {
        return BindingBuilder.bind(filaNotificacaoSms()).to(trocaNotificacao());
    }
}

Produtor de Mensagens


@Service
public class ProdutorNotificacoes {

    private final RabbitTemplate templateRabbit;

    public ProdutorNotificacoes(RabbitTemplate templateRabbit) {
        this.templateRabbit = templateRabbit;
    }

    public void enviarNotificacao(String conteudo) {
        templateRabbit.convertAndSend("troca.notificacao.broadcast", "", conteudo);
    }
}

Consumidor de Mensagens


@Component
public class ConsumidorNotificacoes {

    @RabbitListener(queues = "notificacao.email.fila")
    public void processarEmail(String mensagem) {
        System.out.println("Processando e-mail: " + mensagem);
        // Lógica para envio de e-mail
    }

    @RabbitListener(queues = "notificacao.sms.fila")
    public void processarSms(String mensagem) {
        System.out.println("Processando SMS: " + mensagem);
        // Lógica para envio de SMS
    }
}

  1. Configuração de Tempo de Vida (TTL)

O tempo de vida pode ser definido por mensagem ou globalmante na fila.

TTL por Mensagem


public void enviarComTTL(String corpo) {
    MessageProperties propriedades = new MessageProperties();
    propriedades.setExpiration("15000"); // 15 segundos
    Message mensagem = new Message(corpo.getBytes(), propriedades);
    templateRabbit.convertAndSend("troca.padrao", "chave.rota", mensagem);
}

TTL na Fila


@Bean
public Queue filaComTTL() {
    Map<string object=""> argumentos = new HashMap<>();
    argumentos.put("x-message-ttl", 30000);
    return new Queue("fila.ttl.expira", true, false, false, argumentos);
}
</string>
  1. Mecanismos de Confirmação de Mensagens

Para garantir a confiabilidade, ative as confirmações de publicação e retorno.


spring:
  rabbitmq:
    publisher-confirm-type: correlated
    publisher-returns: true

Implemente os callbacks para lidar com confirmações e retornos.


@Component
public class CallbackConfirmacao implements RabbitTemplate.ConfirmCallback {

    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String causa) {
        if (ack) {
            System.out.println("Mensagem confirmada: " + correlationData.getId());
        } else {
            System.err.println("Falha na confirmação: " + causa);
        }
    }
}

@Component
public class CallbackRetorno implements RabbitTemplate.ReturnCallback {

    @Override
    public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
        System.err.println("Mensagem retornada: " + new String(message.getBody()));
    }
}

No produtor, configure os callbacks e utilize a confirmação manual no consumidor.

Produtor com Confirmação


public void enviarComConfirmacao(String payload) {
    templateRabbit.setMandatory(true);
    CorrelationData dadosCorrelacao = new CorrelationData(UUID.randomUUID().toString());
    templateRabbit.convertAndSend("troca.default", "rota.teste", payload, dadosCorrelacao);
}

Consumidor com Acknowledgement Manual


@RabbitListener(queues = "fila.processamento.manual")
public void handleMessage(Message message, Channel canal) throws IOException {
    try {
        // Processar mensagem
        System.out.println("Mensagem recebida: " + new String(message.getBody()));
        canal.basicAck(message.getMessageProperties().getDeliveryTag(), false);
    } catch (Exception e) {
        canal.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
    }
}

  1. Fila de Mensagens Mortas (Dead Letter Queue)

Configure uma fila para receber mensagens que falharam no processamento.


@Bean
public Queue filaPrincipal() {
    Map<string object=""> argumentos = new HashMap<>();
    argumentos.put("x-dead-letter-exchange", "troca.mensagens.mortas");
    argumentos.put("x-dead-letter-routing-key", "rota.mensagens.mortas");
    return new Queue("fila.principal.processamento", true, false, false, argumentos);
}

@Bean
public Queue filaMensagensMortas() {
    return new Queue("fila.mensagens.mortas");
}

@Bean
public TopicExchange trocaMensagensMortas() {
    return new TopicExchange("troca.mensagens.mortas");
}

@Bean
public Binding ligacaoMensagensMortas() {
    return BindingBuilder.bind(filaMensagensMortas())
                         .to(trocaMensagensMortas())
                         .with("rota.mensagens.mortas");
}
</string>
  1. Considerações de Persistência e Monitoramento

Assegure a persistência de filas, trocas e mensagens para sobreviver a reinicializações do broker. Monitoramento de memória e disco é crucial para manter a saúde do sistema RabbitMQ em ambientes de produção.

  1. Transações Distribuídas com RabbitMQ

Utilize a confirmação de publicação e reenvio programático para garantir a entrega confiável. No consumidor, combine o manual acknowledgment com filas de mensagens mortas para evitar ciclos infinitos de retentativa.

  1. Propriedades de Configuração Detalhadas

Explore as diversas propriedades de configuração disponíveis no application.yml para otimizar o comportamento do produtor, consumidor e conexões.


spring:
  rabbitmq:
    host: localhost
    port: 5672
    virtual-host: /
    cache:
      channel:
        size: 5
      connection:
        mode: CHANNEL
    listener:
      simple:
        acknowledge-mode: manual
        concurrency: 1
        max-concurrency: 10
        prefetch: 5
    template:
      mandatory: true
      retry:
        enabled: true
        max-attempts: 3

Tags: spring-boot RabbitMQ AMQP mensagem-assincrona dead-letter-queue

Publicado em 7-22 22:24