Garantia de confiabilidade da mensagem RabbitMQ


Na verdade, não há implementação de atraso de mensagem no RabbitMQ, mas podemos implementar atraso de mensagem por meio de TTL e roteamento de mensagens mortas.

1. Garantia do produtor

1. Notificação de falha

Quando os produtores enviam mensagens aos corretores, devem garantir a fiabilidade das mensagens. Existem duas soluções principais:

  • Notificação de falha
  • Confirmação do remetente

1. Notificação de falha : Se uma mensagem não for entregue à fila, uma notificação de falha aparecerá e a notificação de falha poderá ser habilitada.Na programação nativa, ao enviar uma mensagem, defina o sinalizador obrigatório para habilitar o modo de detecção de falha
Insira a descrição da imagem aqui
. 2. Método de implementação:
configuração na primavera:

pring:
  rabbitmq:
    # 消息在未被队列收到的情况下返回
    publisher-returns: true

No código java, o remetente precisa implementar a interface ReturnCallback para implementar a notificação de falha:

public class sendToMessage implements RabbitTemplate.ReturnCallback {
    
    
    
    @Override
    public void returnedMessage(Message message, int i, String s, String s1, String s2) {
    
    
        
    }

    @Override
    public void returnedMessage(ReturnedMessage returned) {
    
    
        RabbitTemplate.ReturnCallback.super.returnedMessage(returned);
    }
}

3. O problema encontrado: se a mensagem for roteada corretamente para a fila, o editor não receberá nenhuma notificação. O problema é que ele não pode garantir que a mensagem seja publicada com sucesso, pois a mensagem roteada para a fila pode ser perdida

2. Confirmação do remetente

A confirmação do remetente significa que após o produtor entregar a mensagem, se o Broker receber a mensagem, ele dará uma resposta ao produtor, e o produtor receberá a resposta para confirmar se a mensagem é enviada ao Broker normalmente. Este método também é confiável. Garantia central de entrega sexual

  • As mensagens são roteadas para a fila por meio do exchange exchange
  • Envie a mensagem para a corretora, ou seja, para a central de câmbio

Obs: A falha no envio da confirmação só ocorrerá se houver um erro interno no RabbitMQ que não possa ser entregue.

1 Não roteável: Depois que a mensagem atual chega ao switch, a confirmação do remetente é bem-sucedida.
Insira a descrição da imagem aqui
Em primeiro lugar, quando o switch RabbitMQ não é roteável, a mensagem não será entregue à fila, então aqui apenas o caminho para o switch. Quando a mensagem for enviada com sucesso Após o switch, uma operação de confirmação será realizada

Além disso, neste processo, após o produtor receber a mensagem de confirmação, porque a mensagem não pode ser roteada, a mensagem também é inválida e não pode ser entregue na fila, portanto, em circunstâncias normais, ela será usada junto com a notificação de falha , e geralmente será definido aqui. Modo obrigatório, se ocorrer falha, o ouvinte addReturnListener será chamado para processamento.

2. Pode ser roteada; contanto que a mensagem possa chegar à fila, ela pode ser confirmada. Geralmente,
Insira a descrição da imagem aqui
as mensagens que não podem ser roteadas aparecerão quando ocorrer um erro interno no RabbitMQ. Depois que a mensagem for entregue a todas as filas correspondentes, o O broker enviará uma confirmação ao produtor (contendo o ID exclusivo da mensagem), isso permite ao produtor saber que a mensagem chegou corretamente à fila de destino.

Se a mensagem e a fila forem duráveis, a mensagem de confirmação será enviada depois que a mensagem for gravada no disco, e o campo delivery-tag na mensagem de confirmação enviada de volta ao produtor pelo corretor contém o número de série da mensagem de confirmação

3. Método de implementação

Configuração na primavera:

spring:
  rabbitmq:    
    # 开启消息确认机制
    publisher-confirm-type: correlated

No código java, o remetente precisa implementar a interface ConfirmCallback para implementar a notificação de falha.

public class sendToMessage implements RabbitTemplate.ConfirmCallback {
    
    


    @Override
    public void confirm(CorrelationData correlationData, boolean b, String s) {
    
    
        
    }
}

3. Corretor perde mensagem

Habilite a persistência do RabbitMQ, ou seja, após a gravação da mensagem, ela será persistida no disco, mesmo que o mq desligue neste momento, os dados armazenados anteriormente serão lidos automaticamente após a reinicialização.

1. Fila de persistência

@Bean
public Queue queue(){
    
    
    return new Queue(queueName,true);
}

2. Trocador persistente

@Bean
DirectExchange directExchange() {
    
    
    return new DirectExchange(exchangeName,true,false);
}

3.Enviar mensagens persistentes

Ao enviar uma mensagem, defina o deliveryMode=2 da mensagem

Nota: Se você usar SpringBoot, deliveryMode=2 será definido automaticamente ao enviar uma mensagem e não há necessidade de configurá-lo manualmente.

2. Confiabilidade da mensagem do consumidor (confirmação manual do consumidor)

1. O padrão do RabbitMQ é confirmação automática, que precisa ser modificada para confirmação manual, ou seja, após seu próprio programa determinar que a mensagem foi processada, você pode enviar a confirmação manualmente. Neste momento, se você encontrar uma situação em que o o processo trava sem processar a mensagem, devido a Sem enviar a confirmação, o RabbitMQ não excluirá a mensagem, mas a enviará a outros consumidores para processamento, mas a mensagem não será perdida.

2.arquivo de configuração do spring

spring:
  rabbitmq:
    listener:
      simple:
        acknowledge-mode: manual  # 手动ack

3. Introdução de parâmetros

reconhecimento-modo: manual significa ativar a confirmação manual. Os outros dois valores deste item de configuração são nenhum e automático.

  • auto: O consumidor decide se deseja enviar ack ou nack com base no fato de o programa ser executado normalmente ou lançar uma exceção. Não confunda none com auto.
  • manual: confirmação manual, o usuário deve enviar manualmente a confirmação ou nack
  • nenhum: nenhum mecanismo de confirmação

4. Realização do consumidor

public class sendToMessage {
    
    

    @RabbitHandler
    public void processOrder(Message massage, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long tag) throws IOException {
    
    
        channel.basicAck(tag, false);
    }
    
}

3. Análise de confiabilidade empresarial

Insira a descrição da imagem aqui
1. Perda de mensagem: Neste cenário de negócios, o usuário inicia uma solicitação de táxi. Se a mensagem do usuário for perdida, não haverá impacto no negócio geral. O usuário pode iniciar a operação de táxi novamente. A probabilidade deste problema de perda de mensagem é muito baixo, e um design simplificado pode ser realizado., se houver falha no envio, basta reverter a operação no redis.

2. Verificação de idempotência: Devido ao uso da fila de atraso, não há necessidade de verificação de idempotência para este negócio, pois se a chave de classificação do usuário redis existir no primeiro tempo limite, ela será excluída. Próximo Um valor que não está disponível no redis é excluído uma vez.Esta operação é idempotente, portanto não há necessidade de considerar a idempotência.

3. Reversão de dados: Embora não seja necessário garantir que a mensagem não seja perdida e que a mensagem seja idempotente, é necessário considerar que se ocorrer um problema, o valor-chave inserido no Redis precisa ser revertido para evitar o julgamento normal do negócio seja afetado

Acho que você gosta

Origin blog.csdn.net/weixin_44702984/article/details/131634539
Recomendado
Clasificación