Notas pessoais de Spring Boot de 0 a 8 - Mensagem RabbitMQ

1. Breve introdução

Na maioria dos aplicativos, o middleware de serviço de mensagem pode ser usado para melhorar a comunicação assíncrona do sistema e expandir os recursos de desacoplamento

  • Dois conceitos importantes em serviços de
    mensagem : intermediário de mensagem e destino. Quando o remetente da mensagem envia uma mensagem, ela será assumida pelo agente da mensagem, o que garante que a mensagem seja entregue ao destino especificado.
  • As filas de mensagens têm principalmente duas formas de destinos:
    fila: comunicação de mensagem ponto a ponto (ponto a ponto)
    tópico: comunicação de mensagem de publicação / assinatura

Dois, instalação

Abra a máquina virtual, execute o Linux, abra o SmarTTY, entre docker pull rabbitmq:3-managemente baixe
Insira a descrição da imagem aqui
docker run -d -p 5672:5672 -p 15672:15672 --name myrabbitmq d55229deb03e

  • -d executado em segundo plano
  • Ele tem mais duas portas, então apenas -p duas vezes
  • --O nome é myrabbitmq
  • A pilha de trás é o ID do meu coelho, verificado com as imagens do docker

Insira a descrição da imagem aqui
Então entre no navegador http://192.168.0.102:15672/, claro, esse IP é meu SmarTTY conectado ao Linux, o que é meu, veja o docker que escrevi antes

Entre, senha da conta de login, o padrão é convidado
Insira a descrição da imagem aqui

Três, RabbitMQ

O produtor publica a mensagem na central, a mensagem finalmente chega na fila e é recebida pelo consumidor, e o Binding determina para qual fila a mensagem da central deve ser enviada.
Quando o Exchange distribui mensagens, existem diferenças de acordo com as diferentes estratégias de distribuição. Atualmente, existem quatro tipos: direto, fanout, tópico e cabeçalhos .

1. Trocador de tópico

Insira a descrição da imagem aqui
O switch de tópico distribui o atributo de chave de roteamento da mensagem por meio de correspondência de padrões e combina a chave de roteamento com um padrão.Neste momento, a fila precisa ser vinculada a um padrão. Ele divide a string da chave de roteamento e da chave de ligação em palavras, que são separadas por pontos. Ele também reconhece dois caracteres curinga: o símbolo "#" e o símbolo "*". # Corresponder 0 ou mais palavras, * Corresponder a uma palavra.

2. Teste primeiro

Insira a descrição da imagem aqui
Diagrama do tutorial em vídeo

Siga o vídeo tutorial para fazer o teste, não sei porque isso está acontecendo. . . Faça algumas trocas e, em seguida, vincule a fila,

3. Crie 3exchange

Insira a descrição da imagem aqui
As principais são estas duas caixas.
Ou seja Durability: opção Duiable significa persistência. Depois de abri-la da próxima vez, a bolsa ainda está lá, e a outra significa que desaparece após o fechamento.
Insira a descrição da imagem aqui

4. Adicione 4 filas

Insira a descrição da imagem aqui
Insira a descrição da imagem aqui

5. Filas de ligação para todas as 3 trocas

Insira a descrição da imagem aqui
Escolha qual amarrar, clique em
Insira a descrição da imagem aqui

  • Mas ah, é um pouco diferente em exchange.topic, porque exchange.topic não está vinculado a todos, o nome da rota precisa ser alterado, conforme explicado mais tarde

Veja a imagem no início, exchange.direct e exchange.fanout estão vinculados às 4 filas, exchange.topic está atguigu.#vinculado (atguigu como a cabeça) e *.newsvinculado (o fim da notícia)
Insira a descrição da imagem aqui
exchange.direct e exchange.fanout são ambos vinculados Nisso

Em seguida, exchange.topic:
Insira a descrição da imagem aqui

  • O que isto significa? Disse depois

6. Teste

1) `exchange.direct

Por exemplo, quando exchange.directenviamos uma solicitação atguigu na China, apenas a fila atguigu pode aceitá-la, porque a troca usa direct e o nome da rota é atguigu . O nome da rota é especificado para enviar informações. Outras filas têm nomes diferentes e não podem ser recebido.

  • Se o tipo for direto, especifique para quem enviar
    Insira a descrição da imagem aqui
    Insira a descrição da imagem aqui

2) exchange.fanout

O tipo é fanoutque não importa o que seja especificado, a fila em exchange.fanout irá recebê-lo. Por exemplo, envie uma solicitação em exchange.fanout
Insira a descrição da imagem aqui
Insira a descrição da imagem aqui

  • Apenas atguigu's ready é 2 porque o exemplo acima é um pedido atguigu

3) exchange.topic

Enviando em exchange.topic hello.news, parece que isso não existe, mas preste atenção
Insira a descrição da imagem aqui
porque o topictipo é utilizado, então a tecnologia pode ser fuzzy matching. (Isso deve ser entendido como vinculação, porque a fila é escrita no início, e então a troca tem alguma vinculação com cada fila) Então a fila atguigu.news aceita * .news e pode aceitá-lo. A fila gulixueyuan.news aceita * .news e também pode aceitá-lo.

Insira a descrição da imagem aqui
Insira a descrição da imagem aqui

Quatro, teste de projeto

Insira a descrição da imagem aqui

1. Configuração

application.yml:

spring:
  rabbitmq:
    host: 192.168.0.102
    username: guest
    password: guest

2. Envie uma mensagem

Pode ser importado automaticamente com @Autowired

@SpringBootTest
class SpringBootAmqpApplicationTests {
    
    

    @Autowired
    RabbitTemplate rabbitTemplate;

    @Test
    void contextLoads() {
    
    
//        rabbitTemplate.send(String exchange, String routeKey, Message var3)
//        Message(byte[] body, MessageProperties messageProperties)  Message为一个数组和一个头消息

//        convertAndSend(String var1, String var2, Object var3)
//        其中,Object var3默认为消息体,会自动序列化发送过去的
        Map<String,Object> map = new HashMap<>();
        map.put("msg","这是一个信息");
        rabbitTemplate.convertAndSend("exchange.direct","atguigu.news",map);

    }
  • send(String exchange, String routeKey, Message var3): Nome da troca, nome da rota e mensagem. A mensagem consiste no conteúdo da mensagem e no cabeçalho da mensagem
  • convertAndSend(String var1, String var2, Object var3), O envio é muito problemático, existe este método, o objeto var3 será automaticamente convertido para serialização para enviar mensagens

Insira a descrição da imagem aqui
Insira a descrição da imagem aqui

3. Aceite a mensagem

    @Test
    public void test(){
    
    
        Message receive = rabbitTemplate.receive("atguigu.news");
        System.out.println(receive);
    }

(Corpo: '{msg = 这 是 一个 信息}' MessageProperties [headers = {}, contentType = application / x-java-serialized-object, contentLength = 0, receivedDeliveryMode = PERSISTENT, priority = 0, redelivered = true, receivedExchange = exchange.direct, receivedRoutingKey = atguigu.news, deliveryTag = 1, messageCount = 0])

Insira a descrição da imagem aqui

4. A mensagem enviada torna-se do tipo JSON

Como você pode ver, tanto o envio quanto o recebimento são serializados e desserializados, é melhor converter para JSON, basta adicionar uma classe de configuração.

@Configuration
public class MyAMQPConfig {
    
    

	@Bean
    public MessageConverter messageConverter(){
    
    
//        把消息转化为JSON格式
        return new Jackson2JsonMessageConverter();
    }
}

Envie
Insira a descrição da imagem aqui
novamente e aceite novamente

class org.springframework.amqp.core.Message
(Body: '{“msg”: “这 是 一个 信息”}' MessageProperties [headers = { ContentTypeId = java.lang.Object, KeyTypeId = java.lang.Object, TypeId = java.util.HashMap}, contentType = application / json, contentEncoding = UTF-8, contentLength = 0, receivedDeliveryMode = PERSISTENT, priority = 0, redelivered = true, receivedExchange = exchange.direct, receivedRoutingKey = atguigu.news, deliveryTag = 1 , messageCount = 0])

exchange.directÉ assim que ele é enviado , e o mesmo se aplica a outros tipos de trocas.

5. Aceitar mensagens automaticamente

Para mostrar melhor, criamos uma classe com o método toString escrito nela,

public class Person {
    
    
    String name;
    int age;
    //xxx
}

Crie uma camada de serviço para receber mensagens automaticamente de uma determinada fila

@Service
public class PersonService {
    
    

    @RabbitListener(queues = "atguigu.news")
    public void receive(Person person){
    
    
        System.out.println("收到消息"+person);
    }
}

  • @RabbitListener: Você pode colocar várias filas para aceitar automaticamente as coisas na fila. Se o parâmetro for usado, escreva Pessoa, ou seja, se o JSON enviado for Pessoa, pode ser recebido, caso contrário, é do tipo Mensagem

Ative a anotação de aceitação automática de mensagens no programa principal

@EnableRabbit
@SpringBootApplication
public class SpringBootAmqpApplication {
    
    

    public static void main(String[] args) {
    
    
        SpringApplication.run(SpringBootAmqpApplication.class, args);
    }

}

  • @EnableRabbit: Ativa o comentário de aceitação automática de mensagens

Aula de teste


@SpringBootTest
class SpringBootAmqpApplicationTests {
    
    

    @Autowired
    RabbitTemplate rabbitTemplate;

    @Test
    void contextLoads() {
    
    
        rabbitTemplate.convertAndSend("exchange.direct","atguigu.news",new Person("小强",22));

    }

Uma mensagem de uma classe personalizada é enviada aqui

Recebeu a mensagem Pessoa {nome = 'Xiaoqiang', idade = 22}

Por aceitar a saída de algo, é escrito pela camada de serviço

6. Se for aceito automaticamente como tipo de mensagem

Um método da camada de serviço

    @RabbitListener(queues = "atguigu")
    public void receive2(Message message){
    
    
        System.out.println(message.getBody());
        System.out.println(message.getMessageProperties());
    }

Ainda envia o objeto Person, mas a fila está atguigu, e o acima também aceita atguigu, mas o tipo de aceitação é Message

    @Test
    void contextLoads() {
    
    
        rabbitTemplate.convertAndSend("exchange.direct","atguigu",new Person("小强",22));

    }

[B @ 5e012317
MessageProperties [headers = { TypeId = com.qiang.Bean.Person}, contentType = application / json, contentEncoding = UTF-8, contentLength = 0, receivedDeliveryMode = PERSISTENT, priority = 0, redelivered = false, receivedExchange = exchange.direct, receivedRoutingKey = atguigu, deliveryTag = 1, consumerTag = amq.ctag-Ws2bRFLJ6Y3d7JXvrKVCTQ, consumerQueue = atguigu]

Quinto, o código substitui as operações de interface

A criação de troca, fila e vinculação que fizemos antes pode ser implementada em Java.
Continue fazendo isso na classe de teste

@Test
public void create(){
    
    

    amqpAdmin.declareExchange(new DirectExchange("amqpadmin.exchange"));

    amqpAdmin.declareQueue(new Queue("amqpadmin.queue",true));

    amqpAdmin.declareBinding(new Binding("amqpadmin.queue",Binding.DestinationType.QUEUE,"amqpadmin.exchange","amqp.test",null));

}
  • DirectExchange: Existe no máximo este container DirectExchange(String name, boolean durable, boolean autoDelete, Map<String, Object> arguments), mas também existe um container, basta escrever o primeiro. Durável é se é persistente e se o autoDelete booleano é excluído automaticamente, o Map não sabe. . .
  • Queueo mesmo
  • BindingBinding(String destination, Binding.DestinationType destinationType, String exchange, String routingKey, @Nullable Map<String, Object> arguments)
    • destino: destino, a qual fila ligar
    • Binding.DestinationType destinationType: basta acompanhar. . .
    • troca: qual troca
    • routingKey: Qual é o nome de roteamento?
    • @Nullable Map: não sei. . . .

O código até agora: spring-boot-AMQP

Acho que você gosta

Origin blog.csdn.net/yi742891270/article/details/107767914
Recomendado
Clasificación