Problemas de confiabilidade de mensagem RabbitMQ, opções de mensagens mortas, mensagens atrasadas, filas preguiçosas

confiabilidade da mensagem

Se for coleta de log, então se a mensagem for perdida no processo MQ (falha de processamento de mensagem, falha de rede, falha de servidor, etc.), essas mensagens são insignificantes comparadas com a visão geral, não tão importantes, e a perda é perdida . Se a confiabilidade da mensagem for considerada, o desempenho será degradado e a perda será maior do que o ganho.
Se for um serviço de pedido, envie uma mensagem para o MQ, pois é assíncrono, e o pedido foi notificado que o pedido foi feito com sucesso, então deve-se garantir que a mensagem não será perdida. Isso deve garantir a confiabilidade da mensagem. Embora seja uma chamada assíncrona, é necessário garantir que as chamadas assíncronas para cada serviço sejam processadas com sucesso.
Questões a serem consideradas para a confiabilidade da mensagem:

  • A mensagem deve ser entregue com sucesso ao consumidor
    • O produtor é responsável pela peça e não haverá problemas
    • Os consumidores são responsáveis ​​pela parte não vai dar errado
    • problema de persistência de mensagem
  • O consumidor deve processar a mensagem com sucesso

O produtor garante que as mensagens sejam enfileiradas com sucesso

A confiabilidade da mensagem para o produtor é responsável por saber se a mensagem foi enviada com sucesso para a fila correspondente. Esse processo é dividido em duas partes. A primeira parte é se o processo de envio da mensagem para o switch foi bem-sucedido e se o switch é roteado para a fila com sucesso. correspondente 消息确认a e消费回执

mensagem de confirmação

A seção de confirmação da mensagem é dividida em três casos possíveis:

  1. O produtor não conseguiu enviar a mensagem para a troca
  2. Se o interruptor estiver com defeito, como: não há interruptor correspondente, ele retornaránack
  3. Envie com sucesso a mensagem para a troca especificada, retorneack

Por padrão, o RabbitMQ não habilita a confirmação de mensagem. As etapas de configuração são as seguintes:
4. Ative o mecanismo de confirmação de mensagem no arquivo de configuração

spring:
  rabbitmq:
    publisher-confirm-type: correlated
  1. Mensagem de configuração, especificada como o método de retorno de chamada de falha correspondente
  CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());// 消息的唯一性
        correlationData.getFuture().addCallback(
            result->{
    
    
                if(result.isAck()){
    
    
                // 成功回调
                    System.out.println("消息成功投递到交换机");
                }
                else{
    
    
                // 失败回调 这里可以进行重试
                    System.out.println("消息未成功投递到交换机");
                }
            },
            ex->{
    
    
                System.out.println("发送消息失败");
            }
        );

Ao enviar uma mensagem, passe correlationData o objeto como parâmetro.

rabbitTemplate.convertAndSend("e1","",user,correlationData);

recebimento de mensagem

O recebimento da mensagem é retornado quando ocorre um erro no roteamento do switch para a fila.
As etapas de configuração são as seguintes:

  1. no arquivo de configuração
spring:
  rabbitmq:
    publisher-returns: true # 开启消息回执
    template:
      mandatory: true # true 为自定义消息回执回调  false为直接丢弃掉消息
  1. Configure o callback do recebimento de mensagem.
    Um objeto rabbitMQ só pode ser configurado com um recebimento de mensagem. Portanto, na classe, o recebimento de mensagem só será executado quando o switch falhar em rotear para a fila de mensagens.
@Configuration
public class CommonConfig implements ApplicationContextAware {
    
    
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    
    
        // 获取RabbitTemplate 
        RabbitTemplate rabbitTemplate = applicationContext.getBean(RabbitTemplate.class);
        // 设置ReturnCallback 
        rabbitTemplate.setReturnCallback((message, replyCode, replyText, exchange, routingKey) -> {
            // 投递失败,记录日志
            log.info("消息发送失败,应答码{},原因{},交换机{},路由键{},消息{}",
                     replyCode, replyText, exchange, routingKey, message.toString());
            // 如果有业务需要,可以重发消息
        });
    }
}

Teste :
O switch de teste falha : envie uma mensagem para um switch inexistente, porque a mensagem não é enviada para o switch, então o método nack será chamado na confirmação da mensagem para testar
insira a descrição da imagem aqui
se o switch não está roteado para a fila , e o switch está vinculado a uma fila, em seguida, exclua esta fila por meio do console da página
insira a descrição da imagem aqui

O consumidor garante que as mensagens sejam desenfileiradas e consumidas com sucesso

Quando o produtor tiver enviado com sucesso a mensagem para a fila, a missão do produtor estará concluída. A parte restante é enviada ao consumidor pela fila e, em seguida, o consumidor processa a mensagem
, mas há duas partes que podem dar errado:

  1. O consumidor falhou ao receber uma mensagem da fila
  2. O mensageiro recuperou com sucesso a mensagem da fila, mas não conseguiu processá-la

Mecanismo de Confirmação de Consumo

De qualquer forma, o consumidor não processou a mensagem com sucesso. A ideia do julgamento é: se o consumidor processar a mensagem com sucesso, ele retornará uma confirmação. Enquanto houver um acidente, a fila não será confirmada, e será considerado que o consumidor não a processou com sucesso na mensagem final, ela não será deletada da fila.
A confirmação de devolução é dividida em três tipos:

  • manual: retorne manualmente, você precisa chamar a api no código
  • auto: Retorne automaticamente, por meio do recurso Aop do spring, o código é aprimorado e a classe proxy enviará uma confirmação para ele após a execução do código
  • nenhum: Receba a mensagem e confirme imediatamente. Desde que o consumidor retire a mensagem da fila, ela será consumida com sucesso por padrão, e a mensagem na fila não existirá这种方式不能保证消息的可靠性

método de modificação

  • Modifique no arquivo de configuração
spring:
  rabbitmq:
    listener:
      simple:
        acknowledge-mode: 模式

Pensando : Quantos mecanismos de confirmação são enviados no processo desde o consumidor retirar a mensagem da fila até o consumo bem-sucedido do consumidor? O consumidor envia uma confirmação quando é retirado da fila, e depois envia outra confirmação após o consumo bem-sucedido, ou só envia uma confirmação após o consumo final bem-sucedido?
Quando a fila enviar uma mensagem para a fila, o status da mensagem será definido como unacked, e se o consumidor enviar uma confirmação, a mensagem será excluída.

Teste: primeiro, vamos dar uma olhada na situação padrão quando um consumidor retira uma mensagem da fila, mas não consegue consumi-la.
Após testes, constatou-se que os consumidores deixaram de consumir e continuariam a fazê-lo 重试. Quando a parada falhar ao tentar novamente, a mensagem será reenfileirada. (Este é o padrão)
insira a descrição da imagem aqui
informações do console, observe que o console aqui é a versão 3.9, se a versão for muito baixa, pode ser diferente
insira a descrição da imagem aqui

insira a descrição da imagem aqui
O maior problema com este método é: Uma vez que o consumo falha, as mensagens na fila são constantemente enviadas ao consumidor como chutar uma bola, e o estado é constantemente trocado do estado Unacked para o estado Ready, que consome muito MQ recursos. Conforme mostrado na figura acima, a barra de envio de mensagens MQ O número subiu para 1700 por segundo
. Se o modo for definido como não, desde que a mensagem seja retirada pelo consumidor, até mesmo a 消费失败mensagem do consumidor será descartada pela fila.
A repetição da mensagem também pode ser configurada . O padrão é continuar tentando enquanto falhar. constantemente 由队列向消费者发送. Ele pode ser configurado para tentar novamente localmente de acordo com as regras especificadas.

Mecanismo de repetição de falha de consumo

O mecanismo de repetição de falha do consumidor é outro mecanismo confiável para o consumo. Ele não usa o mecanismo de retorno de confirmação após a confirmação do consumo e, em seguida, a fila recebe a mensagem de exclusão de confirmação. Em vez disso, a fila pensa que o consumidor terá sucesso, desde que envie uma mensagem para o consumidor e, em seguida, A mensagem é excluída da fila (equivalente ao modo nenhum), mas o consumidor não consegue consumir? A retentativa será feita localmente, lembrando que a retentativa é realizada localmente, ou seja, a fila é enviada ao consumidor apenas uma vez, o que não afetará a performance do MQ. Após o processamento bem-sucedido, o consumidor retornará automaticamente um ACK para a fila. Se falhar, tentará localmente. Após esgotar o número de vezes, tome as medidas correspondentes de acordo com a estratégia de falha correspondente

Etapa de configuração:
Altere a confirmação da mensagem do consumidor para

spring:
  rabbitmq:
    listener:
      simple:
        retry:
          enabled: true # 开启消费者失败重试
          initial-interval: 1000 # 初识的失败等待时长为1秒
          multiplier: 1 # 失败的等待时长倍数,下次等待时长 = multiplier * last-interval
          max-attempts: 3 # 最大重试次数
          stateless: true # true无状态;false有状态。如果业务中包含事务,这里改为false

Neste momento, teste :
Quando o consumidor retirar a mensagem, o MQ marca a mensagem como uma mensagem Unacked. Quando o processamento da mensagem falhar, ele tentará novamente localmente. Quando o número de novas tentativas exceder o limite superior configurado, o MQ ainda descartará a mensagem .
Você pode interromper o ponto para julgar quantas vezes você tentou novamente no final. Quando o consumo falha, se o limite superior de falha não for excedido, o método callback será chamado automaticamente novamente. Quando o número de tentativas exceder o limite
insira a descrição da imagem aqui
superior , um será enviado automaticamente reject, e a fila acabará删除掉消息

Então isso traz um problema: se as múltiplas tentativas locais ainda falharem, e a confiabilidade da mensagem ainda não for garantida,
então a estratégia de falha precisa ser modificada. O padrão é retornar quando o número de falhas atingir o limite superior reject, então que a mensagem é apagada da fila

estratégia de falha

Existem vários tipos de estratégias de falha

  • RejectAndDontRequeueRecoverer: direto após o esgotamento das novas tentativas reject,丢弃消息. Quando a tentativa local é selecionada, a falha atinge o limite superior, que é o padrão, conforme demonstrado acima

  • ImmediateRequeueMessageRecoverer: Após esgotadas as novas tentativas, retorne nack,消息重新入队e chute a bola novamente

  • RepublishMessageRecoverer: Depois que as tentativas forem esgotadas, entregue a mensagem de falha para a troca especificada

Aqui está o último método de processamento: , quando o consumidor não conseguir processar a mensagem e atingir o limite superior, ele atuará como produtor e enviará mensagens para outras centrais

Use o terceiro método: o consumidor especifica o switch que é encaminhado após a falha

insira a descrição da imagem aqui
Este método é como se eu fosse a Parte B, mas não consigo lidar com isso, então eu, como Parte A, encontro outra Parte B para lidar com o teste
: quando o produtor envia uma mensagem para o switch, o switch a encaminha para a fila , e o consumidor pega a mensagem da fila, Iniciar processamento local, falhar e processar novamente. Quando a falha de processamento atingir o limite superior, ela será encaminhada para a chave de processamento de falha configurada.

  1. O produtor envia uma mensagem para a troca
    insira a descrição da imagem aqui
  2. O consumidor retira a mensagem da fila e o processamento falha várias vezes, mas o limite superior não é atingido, então continue tentando novamente
    insira a descrição da imagem aqui
    insira a descrição da imagem aqui
  3. Quando o número de falhas de processamento do consumidor atingir o limite superior,
    insira a descrição da imagem aqui
    vamos verificar a mensagem encaminhada pelo consumidor na fila de erros. Podemos ver que não apenas o conteúdo da mensagem original, mas também o consumidor adicionou informações de erro à mensagem.
    insira a descrição da imagem aqui

Use um serviço para ouvir essa fila de erros, para que as mensagens de outras falhas de serviço possam ser processadas novamente de maneira uniforme

insira a descrição da imagem aqui

Use o primeiro método: especifique uma opção de letra morta na fila

Como o uso da opção de letra morta não está limitado a este cenário, para uma estrutura clara, apenas uma introdução geral é fornecida aqui. O follow-up apresentará em detalhes
que o dead letter switch está configurado na fila de mensagens. Quando o consumidor não consegue processar as mensagens localmente e atinge o limite superior, a primeira estratégia de falha é adotada para retornar a rejeição. A fila de mensagens original é a o mesmo que ACK após receber esta confirmação: enviar diretamente A mensagem é descartada, mas depois que o switch de mensagens mortas é configurado, ele será encaminhado para o switch de mensagens mortas e o switch de mensagens mortas será roteado para o dead-letter fila, e também há um consumidor dedicado ao processamento de mensagens com falha.

insira a descrição da imagem aqui
Este método é como se eu fosse a Parte B, mas não consigo lidar com isso, contarei diretamente à Parte A e a Parte A encontrará outra pessoa para ser a Parte B

problema de persistência de mensagem

Por meio do mecanismo de confirmação de consumo do produtor acima, o mecanismo de confirmação do consumidor foi realizado e a mensagem encaminhada pelo produtor deve ser processada com sucesso pelo consumidor. Mas se no meio do processo da mensagem o MQ travar, a mensagem chegou na fila, e foi confirmada para o produtor, mas o consumidor não sabe que existe uma mensagem para ela. não é persistente e toda a mensagem é perdida.
Para garantir que, após a queda de todo o link, ele ainda possa ser restaurado ao estado anterior ao tempo de inatividade, três problemas de persistência devem ser considerados

  • mudar a persistência
  • persistência de fila
  • Observe que o valor da persistência da mensagem
    é: use Spring AMQP para declarar ou criar 交换机e 队列enviar 消息o padrão 都是持久化.
    Teste :
    Quando eu estava testando o switch errado, o switch declarado, a fila e as mensagens na fila ainda estavam lá. Nesse momento, usei o docker para reiniciar o RabbitMQ para julgar se ele ainda estava lá.
    insira a descrição da imagem aqui

Claro, ao usar springAMQP, você também pode declarar explicitamente a persistência (também um método de configuração de não persistência)

mudar a persistência

@Bean
public DirectExchange simpleExchange(){
    
    
    // 三个参数:交换机名称、是否持久化、当没有queue与其绑定时是否自动删除
    return new DirectExchange("simple.direct", true, false);
}

insira a descrição da imagem aqui

persistência de fila

@Bean
   public Queue errorQueue(){
    
    
       return new Queue("error.queue",true);
   }

insira a descrição da imagem aqui

persistência de mensagem

insira a descrição da imagem aqui
Então, quais operações teremos quando colocarmos apenas uma String?
insira a descrição da imagem aqui
Resumo :
insira a descrição da imagem aqui
Conforme mencionado acima, as novas tentativas locais são usadas após a falha no processamento da mensagem do consumidor. Quando o número de novas tentativas excede o número especificado, o consumidor pode encaminhar a mensagem não processada para um determinado switch ou enviar uma rejeição à fila para permitir Torna-se uma mensagem morta e é tratada pela troca de mensagens mortas especificada pela fila. Veja como usar a opção de letra morta para a fila

troca de cartas mortas

Dead letter exchange, como o nome indica, é enviar as cartas mortas em cada fila para este 交换机, Dead Letter Exchange é a abreviação DLK
de So what is a dead letter? Existem três tipos de letras mortas

  1. 未被成功消费的消息: O consumidor adota o mecanismo de repetição local e a estratégia de falha é o envio final reject. Nesse momento, a mensagem na fila não é consumida com sucesso e se torna uma letra morta
  2. 超时的消息: Pode ser que a fila tenha definido ttl e o tempo limite da fila também pode ser que a mensagem tenha definido ttl e a mensagem tenha expirado. Quando a fila atinge o tempo limite, todas as mensagens na fila se tornam letras mortas e, quando a mensagem expira, apenas esta mensagem se torna uma letra morta
  3. 队列溢出的消息: Como o espaço da fila é limitado, quando as mensagens são colocadas na fila por um longo tempo até que a fila não tenha espaço para armazenar temporariamente essas mensagens, algumas das primeiras mensagens serão liberadas e se tornarão letras mortas e, em seguida, novas mensagens serão armazenado

Como fazer uma troca uma troca de cartas mortas?
Uma troca de mensagens mortas é uma troca comum.Para uma troca de cartas mortas 生产者是队列, a fila enviada a ela especifica sua troca de cartas mortas e, em seguida, as cartas mortas na fila serão enviadas automaticamente para a troca de cartas mortas.


Falha ao configurar um comutador de mensagens mortas

planejamento

tipo nome
troca de cartas mortas dl.e2
fila de mensagens mortas dl.q2
interruptor comum e2
fila normal q2

Configuração: Quando o processamento do consumidor da fila q2 falha, ele é entregue ao consumidor da fila de mensagens mortas dlq2

  1. A configuração de uma dead letter queue é um conjunto comum de opções, filas e relacionamentos de vinculação. E especifique o consumidor para a fila
  @Bean
    public DirectExchange dle2(){
    
    
        return new DirectExchange("dle2");
    }
    @Bean
    public Queue dlq2(){
    
    
        return new Queue("dlq2");
    }
    @Bean
    public Binding dlbinding(){
    
    
        return BindingBuilder.bind(dlq2()).to(dle2()).with("a1");
    }
 @RabbitListener(queues = "dlq2")

 public void listenDirectQueue2(String msg) {
    
    

  System.out.println("死信队列中"+msg);
 }
  1. Configure comutadores e filas normais e vincule-os. A fila deve especificar a troca de mensagens mortas e, em seguida, especificar seus consumidores
@Bean
    public Queue q2(){
    
    
        return QueueBuilder.durable("q2")
                .deadLetterExchange("dle2")
                .build();
    }

    @Bean
    public DirectExchange e2(){
    
    
        return new DirectExchange("e2");
    }
    @Bean
    public Binding binding(){
    
    
        return BindingBuilder.bind(q2()).to(e2()).with("a1");
    }

Especifique o consumidor, o consumidor precisa configurar o mecanismo de repetição local e o consumidor lidará com a falha
insira a descrição da imagem aqui
insira a descrição da imagem aqui

  1. O produtor envia uma mensagem para a troca, que desconhece o produtor
    insira a descrição da imagem aqui

Resultado do teste:
a fila q2 falhou duas vezes e, em seguida, a fila dlq2 recebeu a mensagem
insira a descrição da imagem aqui


Configurando um switch TTL Dead Letter

Defina o prazo de validade da mensagem na fila, mas não há consumidor para a mensagem nesta fila, ou seja, a mensagem enviada para esta fila, por não poder ser consumida, ficará letra morta se ultrapassar o período de validade da fila e, em seguida, defina uma opção de letra morta para a fila. Em seguida, vincule uma fila para a opção de letra morta e um consumidor monitore a fila, para que as mensagens possam ser enviadas ao consumidor após o tempo.
Portanto, a fila de mensagens mortas TTL pode ser usada para enviar mensagens em intervalos regulares (a fila com um período de validade não possui consumidores e a mensagem deve se tornar uma mensagem morta) e processamento de mensagens com tempo limite (entrega de mensagens não processadas a outros consumidores) .
Obviamente, não apenas o período de validade pode ser definido para a fila, mas também o período de validade pode ser definido para a mensagem. O período de validade da fila equivale a definir o período de validade para todas as mensagens na fila, sendo que o período de validade da mensagem se refere a uma única mensagem. Se expirar, será usado como letra morta desta fila

Definir todas as mensagens na fila para atrasar a mensagem Etapas: Se a função do consumidor for especificada para a fila do período de validade, torna-se: a mensagem de tempo limite é processada por outras centrais
Planejamento

tipo nome
troca de cartas mortas dl.e1
fila de mensagens mortas dl.q1
interruptor comum e1
fila normal q1

insira a descrição da imagem aqui

  1. Primeiro, crie uma opção de letra morta, depois vincule a fila e haverá consumidores ouvindo do outro lado da fila (a opção de letra morta é a mesma que a normal)()

  2. Crie um switch e uma fila de temporização e especifique seu switch de letra morta como o valor do switch configurado anteriormente.
    insira a descrição da imagem aqui
    Observe que: a fila de atraso não pode ter consumidores, porque se houver consumidores, a mensagem não será bloqueada na fila e não não exceda o prazo de validade. Será consumido quando se tornar letra morta

  3. O produtor envia uma mensagem para o comutador, e o comutador definirá
    insira a descrição da imagem aqui
    um único atraso de mensagem para a fila do período de validade . Aqui, em vez de especificar TTL para a fila, o TTL é especificado para a mensagem no lado do produtor. Quanto à letra morta fila, é o mesmo que acima

Por exemplo: coloque a mensagem no objeto Message, especifique no objetoTTL

Message message = MessageBuilder
        .withBody("hello, ttl message".getBytes(StandardCharsets.UTF_8))
        .setExpiration("5000")
        .build();

Pensando: 共有几种方式设置消息有效期?
Existem dois tipos, um é para especificar o período de validade para todas as mensagens na fila e o outro é para especificar o período de validade para uma única mensagem. Coloque as informações do
如何实现订单15分钟有效?
pedido em uma fila de atraso, que define o período de validade para 15 minutos, mas não define o pedido do consumidor A informação é bloqueada nesta fila por 15 minutos e depois entregue ao comutador de devoluções, e os consumidores da fila de devoluções correspondente ao comutador de devoluções cancelam o ordem de acordo com as informações após a obtenção da mensagem.


Obviamente, para obter o envio atrasado de mensagens, você pode não apenas usar o método de definir o período de validade da fila e consumi-la na fila de mensagens mortas, mas o RabbitMQ também fornece um plug-in dedicado 延迟消息. Quanto ao fato da fila de mensagens estar cheia, quando uma nova mensagem é inserida, a mensagem mais antiga da fila torna-se uma mensagem morta, o que não será demonstrado aqui. A seguir, apresentaremos a implementação de mensagens atrasadas usando plug-ins

mensagem atrasada

Cenários de aplicação de mensagens atrasadas : as mensagens atrasadas podem ser usadas para definir o período de validade, horário, compromisso, etc.
O funcionário fornece um DelayExchangeplug-in para implementar mensagens atrasadas, que é implementado com base em interruptores em vez de filas. Embora as trocas não possam armazenar mensagens, os plug-ins são usados

Instalação do plug-in DelayExchange

  1. Primeiro, baixe o plug-in primeiro. Observe que a versão do plug-in deve ser consistente com a versão do MQ. O endereço de download é https://github.com/rabbitmq/rabbitmq-delayed-message-exchange/releases
    insira a descrição da imagem aqui
  2. Em seguida, coloque o plug-in no diretório de plug-in MQ.
    Aqui RabbitMQ é iniciado usando Dokcer e o diretório de plug-in foi montado fora na inicialização.
    Comandos quando o RabbitMQ inicia
docker run \
 -e RABBITMQ_DEFAULT_USER=yan\
 -e RABBITMQ_DEFAULT_PASS=1234 \
 -v mq-plugins:/plugins \
 --name mq \
 --hostname mq \
 -p 15672:15672 \
 -p 5672:5672 \
 -d \
 3.9.27-management-alpine

No comando, o diretório do plug-in MQ é montado no mq-pluginsvolume lógico nomeado. Use o comando docker volume inspect mq-pluginspara visualizar o diretório host correspondente ao volume lógico.
insira a descrição da imagem aqui
Coloque .ezo plug-in final neste diretório
insira a descrição da imagem aqui
. Por que nosso plug-in parece fora de lugar, pois precisa ser instalado

  1. Instale o plug-in
    A instalação do plug-in precisa entrar no contêiner para instalação, use o comando docker exec -it mq bashe, em seguida, use o comando rabbitmq-plugins enable rabbitmq_delayed_message_exchangepara concluir a instalação

insira a descrição da imagem aqui
Após a conclusão da instalação
, como o interruptor de atraso é usado? A generalização é especificar o switch para delayed类型definir o tempo de atraso da mensagem.
O switch de atraso é declarado como um tipo com base no switch comum. delayedEntão, ao enviar uma mensagem, se a mensagem for enviada para este switch, ele deve ser adicionado no cabeçalho da mensagem. Atributo x-delay, o valor é o tempo que você deseja atrasar. Ao enviar uma mensagem, o switch de atraso saberá x-delayo tempo de atraso de acordo com o valor do atributo do cabeçalho da mensagem, persistirá a mensagem no disco e a reenviará para a fila vinculada a ela quando chegar a hora.
Ou seja, embora o switch seja declarado como switch 延迟交换机, ele é um aprimoramento com base em um switch normal e ainda possui as funções de um switch normal.
Vamos usar o código para demonstrar esse processo:
Declare o switch como um switch de atraso , usando o mesmo método de @Bean e anotação

  • Usar anotações
    insira a descrição da imagem aqui
  • A maneira de usar @Bean
    insira a descrição da imagem aqui

Quando o produtor envia uma mensagem, ele precisa adicionar um atributo ao cabeçalho da solicitação da mensagem x-delay. O valor é o número de milissegundos de atraso.
insira a descrição da imagem aqui
Durante o teste, verificou-se que quando a mensagem foi enviada para o switch de atraso, porque o switch não roteou a mensagem para a fila a tempo, a confiabilidade da mensagem seria acionada. O método de recebimento da mensagem pode ser julgado de acordo com as informações retornadas e esta situação é ignorada


Usar o plug-in de mensagens atrasadas pode substituir o uso da fila de mensagens mortas. Há outro ponto no problema de mensagens mortas que a mensagem mais antiga na fila se torna uma carta morta devido ao espaço insuficiente na fila. Você pode usar a chave para receber letra morta para processamento, mas como evitá-la?

  1. Aumente o poder de processamento do consumidor
  2. Melhorando a capacidade da fila
    Melhorar a capacidade de processamento dos consumidores não está dentro do escopo do MQ.Aqui discutimos o segundo método de melhorar a fila de mensagens.

filas preguiçosas filas preguiçosas

O que é uma fila preguiçosa? Um entendimento simples é armazenar a mensagem diretamente no disco e, em seguida, lê-la no disco quando ela for usada.
Por que é chamada de fila lenta? Portanto, o disco é mais lento que a memória
, então por que usar a fila lenta? A fila lenta existe no disco. Embora o disco seja lento, ele possui um grande espaço, o que efetivamente resolve o problema de acúmulo de mensagens! E a velocidade é estável. Quando a fila inerte não é utilizada, as mensagens na memória serão transferidas para o disco após atingir um determinado valor. No entanto, a simultaneidade do MQ neste processo de IO diminuirá, apresentando um fenômeno de flutuação. Em vez disso, uma fila inerte é usada e as mensagens são colocadas diretamente no disco, sem intermitência page-out, e a velocidade é relativamente estável.
Quais são as desvantagens das filas lentas? A desvantagem da fila lenta é a desvantagem de armazenar dados no disco: tanto o armazenamento quanto a recuperação devem passar pelo disco e a pontualidade é ruim! Disk IO será pior do que o desempenho da memória!

O uso de filas lentas
As filas lentas são um tipo de filas que foram MQ3.6lançadas após a versão.
O uso de filas lentas também é usado ao declarar filas, e também há duas formas de @Bean e anotações. Observe que mensagens atrasadas são para configurar switches e filas lentas são para configurar filas.

  • @Bean way
    insira a descrição da imagem aqui
  • A forma de anotação
    insira a descrição da imagem aqui
    de envio de mensagens permanece inalterada, basta modificar as propriedades da fila para que as mensagens sejam armazenadas diretamente no disco, e depois recuperadas do disco quando necessário. Além disso, você também pode usar comandos para modificar as filas existentes
    para filas lentas
    . Por exemplo: desejo modificar uma fila comum chamada q4 em uma fila lenta
    insira a descrição da imagem aqui
    dentro do contêiner MQ usando o comandorabbitmqctl set_policy Lazy "^q4$" '{"queue-mode":"lazy"}' --apply-to queues
    insira a descrição da imagem aqui

Acho que você gosta

Origin blog.csdn.net/m0_52889702/article/details/128613119
Recomendado
Clasificación