RabbitMQ. Explicación del cambio

Tabla de contenido

1. Cambiar

1.Intercambio

2. Clave de enrutamiento

3. Clave de enlace (Bindi ngKey)

4. Resumen

2. Tipo de interruptor

1. Intercambio directo: Intercambio directo

2. Intercambio de temas: Intercambio de temas

3. Intercambio Fanout: Intercambio Fanout 

4. Intercambio de encabezados: intercambio de encabezados 

5. Interruptor predeterminado

3. Demostración de código

1. Conexión directa

①.Proveedor

②.consumidor

2. Tema

①.Proveedor

②.consumidor

3. Sector

①.proveedor

②.consumidor


1. Cambiar

1.Intercambio

En RabbitMQ, el productor no entrega el mensaje directamente a la cola cuando envía el mensaje, sino que primero lo entrega al conmutador y luego lo reenvía a la cola específica a través del conmutador, y luego la cola empuja o extrae el mensaje a el consumidor El

productor consumidor envía el mensaje a Exchange, que es enrutado a una o más colas por Exchange



2. Clave de enrutamiento (clave de enrutamiento)

Cuando el productor envía el mensaje al intercambio, especificará RoutingKey para especificar las reglas de enrutamiento.

3. Clave de enlace (Bindi ngKey)

Asocie un intercambio con una cola mediante una clave de enlace para que RabbitMQ sepa cómo enrutar correctamente los mensajes a la cola.

4. Resumen

RoutingKey debe determinar el Exchange al que el productor envía el mensaje, y BindingKey debe determinar la cola a la que el productor debe vincular el Exchange.

2. Tipo de interruptor

1. Intercambio directo: Intercambio directo

El algoritmo de enrutamiento del conmutador directo es muy simple: envía el mensaje a la cola cuya clave de enlace es la misma que la clave de enrutamiento del mensaje.

Dos colas están vinculadas al conmutador X conectado directamente. La primera cola está vinculada a la clave de vinculación naranja y la segunda cola tiene dos claves de vinculación: negra y verde.

En este escenario, un mensaje con una clave de enrutamiento naranja especificada durante la publicación solo se enrutará a la cola Q1, y los mensajes con claves de enrutamiento negra y verde se enrutarán a la cola Q2. Todos los demás mensajes se perderán.


La misma clave de enlace se puede vincular a diferentes colas. Puede agregar una clave de enlace para el conmutador X y la cola Q2. En este caso, el conmutador directo tendrá el mismo comportamiento que el conmutador de transmisión y enviará el mensaje a todas las colas coincidentes. Un mensaje con una clave de enrutamiento negra se enviará a las colas Q1 y Q2 al mismo tiempo.



2. Intercambio de temas: Intercambio de temas

Desventajas de los interruptores de conexión directa :

La solución de clave de enrutamiento para la conexión directa al conmutador es muy simple. Si queremos que un mensaje se envíe a varias colas, entonces este conmutador debe estar vinculado a muchas claves de enrutamiento. Supongamos que cada conmutador está vinculado a una clave de enrutamiento dimensional Buscar cada uno En la cola, la gestión de mensajes será extremadamente difícil.

Características del cambio de tema:

El mensaje enviado al topic switch no puede tener ninguna clave de enrutamiento y debe ser una cadena de palabras separadas por puntos, estas palabras pueden ser arbitrarias, pero generalmente son algunas características relacionadas con el mensaje.

Por ejemplo, las siguientes son varias válidas: clave de enrutamiento: " stock . usd . nyse ", " nyse . vmw ", " quick . orange . rabblt ". Puede haber muchas palabras en la clave de enrutamiento y el límite máximo es 255 bytes.

 Cambio de tema La lógica es algo similar al cambio directo. Los mensajes enviados utilizando una clave de enrutamiento específica se enviarán a todas las colas vinculadas con claves de enlace coincidentes. Sin embargo, hay dos casos especiales para las claves de enlace:

①Indica que coincide con cualquier palabra

②Indica que coincide con una o más palabras



Extensión
Cuando la clave de enlace de una cola es °#, recibirá todos los mensajes, independientemente de la clave de enrutamiento del mensaje recibido.

Cuando la clave de enlace de una cola no utiliza # y *, funciona como un intercambio directo.

3. Intercambio Fanout: Intercambio Fanout 

Un interruptor de ventilador es el tipo más básico de interruptor y lo que puede hacer es muy simple: transmitir mensajes.
El conmutador en forma de abanico enviará todos los mensajes que pueda recibir a la cola vinculada a sí mismo. Debido a que la transmisión no requiere "pensar", el conmutador en forma de abanico procesa los mensajes a la velocidad más rápida entre todos los tipos de conmutadores.

4. Intercambio de encabezados: intercambio de encabezados 

Ni el conmutador de encabezado ni el conmutador de sector requieren una clave de enrutamiento. El conmutador routeKey asigna mensajes a la cola a través del encabezado Encabezados, que es un poco como los encabezados HTTP. Se requiere que la estructura Hash lleve una clave - coincidencia ", y el valor de esta clave puede
 ser cualquiera o al, esto significa si todos los hashes contenidos en el mensaje deben coincidir con al), o solo cuatro claves (cualquiera) son suficientes. En comparación con los conmutadores conectados directamente, la ventaja del conmutador de encabezado es que las reglas de coincidencia no se limitan a
caracteres Cadena (cadena) sino al tipo de Objeto. 

all: todas las entradas transportadas al publicar un mensaje deben coincidir exactamente con todas las entradas vinculadas a la cola
any: siempre que un par de encabezados clave-valor transportados al publicar un mensaje satisfaga uno de los múltiples parámetros definidos por la cola, puede coincidir Arriba, tenga en cuenta que esta es la coincidencia completa del par clave-valor, solo la clave coincide, pero el valor no es el mismo;

5. Interruptor predeterminado

De hecho, es un intercambio directo con un carácter nulo en el nombre predeclarado por RabbitMQ. Tiene
un atributo especial que lo hace particularmente útil para aplicaciones simples: es decir, cada nueva cola (cola) se vinculará automáticamente a la reconocida. switch, el nombre de la clave de enrutamiento vinculada (clave de enrutamiento) es el mismo que el nombre de la cola.

3. Demostración de código

Nota: Cuando el conmutador está vinculado a la cola, el nombre del método no se puede repetir con otros 

1. Conexión directa

①.Proveedor

(1).DirectConfig

package com.example.demo.mq;


import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@SuppressWarnings("all")

public class DirectConfig {

    /*
    * 创建队列
    * */
    @Bean
    public Queue directQueueA(){

        return  new Queue("directQueueA",true);
    }
    @Bean
    public Queue directQueueB(){

        return  new Queue("directQueueB",true);
    }
    @Bean
    public Queue directQueueC(){

        return  new Queue("directQueueC",true);
    }


    /**
     * 创建交换机
     */
    @Bean
public DirectExchange directExchange(){
    return  new DirectExchange("directExchange");
}

/**
 * 进行交换机和队列的绑定,设置bindingkey
 *
 */
@Bean
public Binding BindingA(){
    return BindingBuilder.bind(directQueueA()).to(directExchange()).with("AA");

}
    @Bean
    public Binding BindingB(){
        return BindingBuilder.bind(directQueueB()).to(directExchange()).with("BB");

    }
    @Bean
    public Binding BindingC(){
        return BindingBuilder.bind(directQueueC()).to(directExchange()).with("CC");

    }

}

(2).Controlador de proveedor

package com.example.demo;

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ProviderController {

    @Autowired
    private RabbitTemplate template;

    @RequestMapping("/directSend")
    public String directSend(String routingKey){
        template.convertAndSend("directExchange",routingKey,"nihao  word");
        return "yes";
    }
}

②.consumidor

(1).DirectReceiverA

package com.example.demo.mq;


import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
@SuppressWarnings("all")
@RabbitListener(queues = "directQueueA")
@Slf4j
public class DirectReceiverA {



    @RabbitHandler
public void process(String message){
log.info("A接到"+message);

}


}

(2).DirectReceiverB

package com.example.demo.mq;


import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
@SuppressWarnings("all")
@RabbitListener(queues = "directQueueB")
@Slf4j
public class DirectReceiverB {



    @RabbitHandler
public void process(String message){
log.info("B接到"+message);

}


}

(3).DirectReceiverC

package com.example.demo.mq;


import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
@SuppressWarnings("all")
@RabbitListener(queues = "directQueueC")
@Slf4j
public class DirectReceiverC {



    @RabbitHandler
public void process(String message){
log.info("C接到"+message);

}


}

2. Tema

①.Proveedor

(1) Configuración de tema

package com.example.demo.mq;


import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@SuppressWarnings("all")

public class TopicConfig {
    public final  static String KEY_A="*.orange.*";
    public final  static String KEY_B="*.*.rabbit";
    public final  static String KEY_C="lazy.#";


    /*
    * 创建队列
    * */
    @Bean
    public Queue topicQueueA(){

        return  new Queue("topicQueueA",true);
    }
    @Bean
    public Queue topicQueueB(){

        return  new Queue("topicQueueB",true);
    }
    @Bean
    public Queue topicQueueC(){

        return  new Queue("topicQueueC",true);
    }


    /**
     * 创建交换机
     */

    @Bean
public TopicExchange topicExchange(){
    return  new TopicExchange("topicExchange");
}

/**
 * 进行交换机和队列的绑定,设置bindingkey
 *
 */
@Bean
public Binding topicBindingA(){
    return BindingBuilder.bind(topicQueueA()).to(topicExchange()).with(KEY_A);

}
    @Bean
    public Binding topicBindingB(){
        return BindingBuilder.bind(topicQueueB()).to(topicExchange()).with(KEY_B);

    }
    @Bean
    public Binding topicBindingC(){
        return BindingBuilder.bind(topicQueueC()).to(topicExchange()).with(KEY_C);

    }

}

(2).Controlador de proveedor


    @RequestMapping("/topicSend")
    public String topicSend(String routingKey){
        template.convertAndSend("topicExchange",routingKey," word");
        return "yes";
    }

②.consumidor

(1).TemaReceptorA

package com.example.demo.mq;


import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
@SuppressWarnings("all")
@RabbitListener(queues = "topicQueueA")
@Slf4j
public class TopicReceiverA {



    @RabbitHandler
    public void process(String message){
        log.warn("A接到L"+message);

    }


}

(2).TemaReceptorB

package com.example.demo.mq;


import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
@SuppressWarnings("all")
@RabbitListener(queues = "topicQueueB")
@Slf4j
public class TopicReceiverB {



    @RabbitHandler
    public void process(String message){
        log.warn("B接到L"+message);

    }


}

(3).TemaReceptorC

package com.example.demo.mq;


import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
@SuppressWarnings("all")
@RabbitListener(queues = "topicQueueC")
@Slf4j
public class TopicReceiverC {



    @RabbitHandler
    public void process(String message){
        log.warn("C接到L"+message);

    }


}

3. Sector

①.proveedor

(1).Configuración de distribución en abanico

package com.example.demo.mq;


import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.FanoutExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@SuppressWarnings("all")

public class FanoutConfig {

    /*
     * 创建队列
     * */
    @Bean
    public Queue fanoutQueueA(){

        return  new Queue("fanoutQueueA",true);
    }
    @Bean
    public Queue fanoutQueueB(){

        return  new Queue("fanoutQueueB",true);
    }
    @Bean
    public Queue fanoutQueueC(){

        return  new Queue("fanoutQueueC",true);
    }


    /**
     * 创建交换机
     */
    @Bean
    public FanoutExchange fanoutExchange(){
        return  new FanoutExchange("fanoutExchange");
    }

    /**
     * 进行交换机和队列的绑定,设置bindingkey
     *
     */
    @Bean
    public Binding fanoutBindingA(){
        return BindingBuilder.bind(fanoutQueueA()).to(fanoutExchange());

    }
    @Bean
    public Binding fanoutBindingB(){
        return BindingBuilder.bind(fanoutQueueB()).to(fanoutExchange());

    }
    @Bean
    public Binding fanoutBindingC(){
        return BindingBuilder.bind(fanoutQueueC()).to(fanoutExchange());

    }

}

(2).Controlador de proveedor

@RequestMapping("/fanoutSend")
    public String fanoutSend(){
        template.convertAndSend("topicExchange","null"," word me");
        return "yes";
    }

②.consumidor

(1).FanoutReceiverA

package com.example.demo.mq;


import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
@SuppressWarnings("all")
@RabbitListener(queues = "fanoutQueueA")
@Slf4j
public class FanoutReceiverA {



    @RabbitHandler
    public void process(String message){
        log.info("C接到"+message);

    }


}

(2).FanoutReceiverB

package com.example.demo.mq;


import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
@SuppressWarnings("all")
@RabbitListener(queues = "fanoutQueueB")
@Slf4j
public class FanoutReceiverB {



    @RabbitHandler
    public void process(String message){
        log.info("C接到"+message);

    }


}

(3).FanoutReceiverC

package com.example.demo.mq;


import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
@SuppressWarnings("all")
@RabbitListener(queues = "directQueueC")
@Slf4j
public class FanoutReceiverC {



    @RabbitHandler
    public void process(String message){
        log.info("C接到"+message);

    }


}

Guess you like

Origin blog.csdn.net/m0_54546762/article/details/123136211