Caso de código de tarifa de consumidor de productor de RabbitMQ (Demo super detallada)

Hola, soy Chenxi. Me alegra que puedas leerlo. Este artículo sigue compartiendo los casos prácticos de las colas de mensajes, compartiéndolos con principiantes y progresando juntos.


1. Prefacio

La intención original de organizar algunos artículos en cola de mensajes es que muchos casos en Internet están muy fragmentados cuando aprendes, y el código también. Para facilitar el aprendizaje de los principiantes, organizaremos un caso completo. El código es completamente real y utilizable. ¡Practica tú mismo!

cola de mensajes

Por primera vez que aprendamos sobre la cola de mensajes, debemos comprender sus escenarios de aplicación, ¿por qué usarlo? ¿Y cómo usarlo? Organice este artículo para compartirlo con principiantes y proporcione un caso detallado, ¡el siguiente código se puede practicar directamente!
Inserte la descripción de la imagen aquí

Los tres puntos centrales de la cola de mensajes: desacoplamiento, asíncrono y recorte de picos.

Artículo de referencia: explicación detallada de la función de cola de mensajes (desacoplamiento, asíncrono, recorte de picos)

La cola de mensajes también está diseñada para el productor, el principio del consumidor se puede entender simplemente

Artículo de referencia: Código detallado del problema del consumidor productor (Java multiproceso)


En segundo lugar, los detalles del código

Código relacionado con el productor

/**
 * 编写消息的生产者
 */
@Component
public class MsgProducer implements RabbitTemplate.ConfirmCallback {
    
    

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    //由于rabbitTemplate的scope属性设置为ConfigurableBeanFactory.SCOPE_PROTOTYPE,所以不能自动注入
    private RabbitTemplate rabbitTemplate;
    /**
     * 构造方法注入rabbitTemplate
     */
    @Autowired
    public MsgProducer(RabbitTemplate rabbitTemplate) {
    
    
        this.rabbitTemplate = rabbitTemplate;
        rabbitTemplate.setConfirmCallback(this); //rabbitTemplate如果为单例的话,那回调就是最后设置的内容
    }
     /**
     * 发送消息方法一个交换机配一个路由配一个队列
     * @param content
     */
    public void sendMsg(String content) {
    
    
        CorrelationData correlationId = new CorrelationData(UUID.randomUUID().toString());
        //把消息放入ROUTINGKEY_A对应的队列当中去,对应的是队列A
        rabbitTemplate.convertAndSend(RabbitConfig.EXCHANGE_A, RabbitConfig.ROUTINGKEY_A, content, correlationId);
        rabbitTemplate.convertAndSend(RabbitConfig.EXCHANGE_B, RabbitConfig.ROUTINGKEY_B, content, correlationId);
    }

    /**
     * 广播模式
     * @param content
     */
    public void sendAll(String content) {
    
    
        rabbitTemplate.convertAndSend("fanoutExchange","", content);
    }

    /**
     * 回调
     */
    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
    
    
        //logger.info(" 回调id:" + correlationData);
        if (ack) {
    
    
            logger.info("消息成功消费");
        } else {
    
    
            logger.info("消息消费失败:" + cause);
        }
    }
}

Código relacionado sobre la capa del controlador

@RestController
public class SendController {
    
    

    @Autowired
    private MsgProducer msgProducer;

    @RequestMapping(value = "/send",method = RequestMethod.GET)
    public void send(int length){
    
    
        for (int i=1;i<=length;i++){
    
    
            msgProducer.sendMsg("这是我发送的第"+i+"个信息");
        }
    }

    @RequestMapping(value = "/sendAll",method = RequestMethod.GET)
    public void sendAll(int length){
    
    
        for (int i=1;i<=length;i++){
    
    
            msgProducer.sendAll("这是我发送的第"+i+"个信息");
        }
    }
}

Código de consumidor

@Component
@RabbitListener(queues = RabbitConfig.QUEUE_A)
public class MsgReceiver_one {
    
    

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @RabbitHandler
    public void process(String content) {
    
    
        logger.info("消费者one接收处理队列A当中的消息: " + content);
    }
}

Estos dos escuchan la cola A y la cola B respectivamente

@Component
@RabbitListener(queues = RabbitConfig.QUEUE_B)
public class MsgReceiver_two {
    
    

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @RabbitHandler
    public void process(String content) {
    
    
        logger.info("消费者two接收处理队列A当中的消息: " + content);
    }
}

Prueba: ingrese la primera ruta de acceso en el navegador e ingrese los parámetros relevantes

La primera ruta aquí es que el productor envía a las colas A y B respectivamente
Inserte la descripción de la imagen aquí

Consulte la información relacionada con la impresión de la consola
Inserte la descripción de la imagen aquí


Prueba: ingrese la segunda ruta e ingrese los parámetros relacionados en el navegador

La segunda ruta aquí es publicar en forma de transmisión, puede consumir y
Inserte la descripción de la imagen aquí
ver la información relacionada con la impresión de la consola

Inserte la descripción de la imagen aquí
http: // localhost: 15672 / # / queues
Inserte la descripción de la imagen aquí


Información sobre el archivo de configuración del proyecto

@Configuration
public class RabbitConfig {
    
    

    @Value("${spring.rabbitmq.host}")
    private String host;

    @Value("${spring.rabbitmq.port}")
    private int port;

    @Value("${spring.rabbitmq.username}")
    private String username;

    @Value("${spring.rabbitmq.password}")
    private String password;

    public static final String FANOUT_EXCHANGE="fanoutExchange";

    //交换机
    public static final String EXCHANGE_A = "my-mq-exchange_A";
    public static final String EXCHANGE_B = "my-mq-exchange_B";
    public static final String EXCHANGE_C = "my-mq-exchange_C";
    //队列
    public static final String QUEUE_A = "QUEUE_A";
    public static final String QUEUE_B = "QUEUE_B";
    public static final String QUEUE_C = "QUEUE_C";
    //路由关键字 key
    public static final String ROUTINGKEY_A = "spring-boot-routingKey_A";
    public static final String ROUTINGKEY_B = "spring-boot-routingKey_B";
    public static final String ROUTINGKEY_C = "spring-boot-routingKey_C";

    @Bean
    public ConnectionFactory connectionFactory() {
    
    
        CachingConnectionFactory connectionFactory = new CachingConnectionFactory(host,port);
        connectionFactory.setUsername(username);
        connectionFactory.setPassword(password);
        //connectionFactory.setVirtualHost("/test");
        connectionFactory.setPublisherConfirms(true);
        return connectionFactory;
    }

    @Bean
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    //必须是prototype类型
    public RabbitTemplate rabbitTemplate() {
    
    
        RabbitTemplate template = new RabbitTemplate(connectionFactory());
        return template;
    }

    /**
     * 针对消费者配置
     * 1. 设置交换机类型
     * 2. 将队列绑定到交换机
     FanoutExchange: 将消息分发到所有的绑定队列,无routingkey的概念
     HeadersExchange :通过添加属性key-value匹配
     DirectExchange:按照routingkey分发到指定队列
     TopicExchange:多关键字匹配
     */
    @Bean
    public DirectExchange defaultExchangeA() {
    
    
        return new DirectExchange(EXCHANGE_A);
    }

    @Bean
    public DirectExchange defaultExchangeB() {
    
    
        return new DirectExchange(EXCHANGE_B);
    }

    @Bean
    public DirectExchange directExchangeC(){
    
    
        return new DirectExchange(EXCHANGE_C);
    }

    /**
     * 获取队列A
     * @return
     */
    @Bean
    public Queue queueA() {
    
    
        return new Queue(QUEUE_A, true); //队列持久
    }

    @Bean
    public Queue queueB() {
    
    
        return new Queue(QUEUE_B, true); //队列持久
    }

    @Bean
    public Queue queueC() {
    
    
        return new Queue(QUEUE_C, true); //队列持久
    }

    /**
     * 队列绑定交换机
     * @return
     */
    @Bean
    public Binding bindingA() {
    
    
        return BindingBuilder.bind(queueA()).to(defaultExchangeA()).with(RabbitConfig.ROUTINGKEY_A);
    }

    @Bean
    public Binding bindingB(){
    
    
        return BindingBuilder.bind(queueB()).to(defaultExchangeB()).with(RabbitConfig.ROUTINGKEY_B);
    }

    @Bean
    public Binding bindingC(){
    
    
        return BindingBuilder.bind(queueC()).to(directExchangeC()).with(RabbitConfig.ROUTINGKEY_C);
    }

    //配置fanout_exchange
    //fanout只能支持统一广播
    @Bean
    FanoutExchange fanoutExchange() {
    
    
        return new FanoutExchange(RabbitConfig.FANOUT_EXCHANGE);
    }

    //把所有的队列都绑定到这个交换机上去
    @Bean
    Binding bindingExchangeA(FanoutExchange fanoutExchange) {
    
    
        return BindingBuilder.bind(queueA()).to(fanoutExchange);
    }
    @Bean
    Binding bindingExchangeB(FanoutExchange fanoutExchange) {
    
    
        return BindingBuilder.bind(queueB()).to(fanoutExchange);
    }
    @Bean
    Binding bindingExchangeC(FanoutExchange fanoutExchange) {
    
    
        return BindingBuilder.bind(queueC()).to(fanoutExchange);
    }
}

resumen:

1. Primero cree una clase de configuración y luego cree una cola

2. Cree el objeto que el productor usa en la cola de mensajes y luego entregue el mensaje que desea entregar.

3. Cree la capa de control, complete la ruta, cree el objeto productor y luego envíe el mensaje

4. Consumidores, completar el nombre de la cola de consumo, monitorear y prepararse para iniciar el consumo


The best investment is to invest in yourself.

Inserte la descripción de la imagen aquí

2020.10.07 ¡Espero que te apresures a estar en tu amor!

Supongo que te gusta

Origin blog.csdn.net/weixin_45393094/article/details/108952693
Recomendado
Clasificación