RabbitMQ的Topic模式发送与接收消息

一、RabbitMQ的工作模式

rabbitMQ总共有六种工作模式:simple简单模式、work工作模式、publish/subscribe发布订阅模式、routing路由模式、topic主题模式

routing模式:

 topic主题模式:

 可以看出,topic模式为一种特殊的routing模式,通过图一可以看到,routing模式通过唯一的routingKey将交换机与队列绑定起来,只有当消息的路由键routing key 与队列的绑定键binging key匹配时,该消息才会进入该队列。topic模式也叫通配符模式,除了bindingkey 与routing key匹配规则不一样外,作用和topic模式一样,特殊匹配原则:

* 表示一个单词

# 表示任意个单词

简单使用方法如下:

application.properties:

spring.rabbitmq.host=xxx.xxx.xxx.xxx
spring.rabbitmq.username=liufuqiang
spring.rabbitmq.password=wapj1314
spring.rabbitmq.port=5672

RabbitmqConfig.java

新建队列

@Bean
    Queue customerQueue(){
       return new Queue("liufuqiang_customer");
    }

交换机:

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

将customerQueue与topicExchange绑定起来:

    @Bean
    Binding myTopicBinding(){
        Binding binding = BindingBuilder.bind(customerQueue()).to(topicExchange()).with("liufuqiang_rountingKey.*");
        return binding;
    }
package com.example.rabbitmqdemo.config;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.amqp.rabbit.annotation.RabbitListenerConfigurer;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.listener.RabbitListenerEndpointRegistrar;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.amqp.SimpleRabbitListenerContainerFactoryConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.converter.MappingJackson2MessageConverter;
import org.springframework.messaging.handler.annotation.support.DefaultMessageHandlerMethodFactory;
import org.springframework.messaging.handler.annotation.support.MessageHandlerMethodFactory;

@Configuration
public class RabbitmqConfig implements RabbitListenerConfigurer {

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

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

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

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

    @Override
    public void configureRabbitListeners(RabbitListenerEndpointRegistrar rabbitListenerEndpointRegistrar) {
        rabbitListenerEndpointRegistrar.setMessageHandlerMethodFactory(messageHandlerMethodFactory());
    }

    @Bean
    MessageHandlerMethodFactory messageHandlerMethodFactory(){
        DefaultMessageHandlerMethodFactory defaultMessageHandlerMethodFactory = new DefaultMessageHandlerMethodFactory();
        defaultMessageHandlerMethodFactory.setMessageConverter(consumerJackson2MessageConverter());
        return defaultMessageHandlerMethodFactory;
    }

    @Bean
    public MappingJackson2MessageConverter consumerJackson2MessageConverter() {
        return new MappingJackson2MessageConverter();
    }

    @Bean
    Queue customerQueue(){
       return new Queue("liufuqiang_customer");
    }

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


    @Bean
    Binding myTopicBinding(){
        Binding binding = BindingBuilder.bind(customerQueue()).to(topicExchange()).with("liufuqiang_rountingKey.*");
        return binding;
    }

    /***
     * 延迟队列
     * @return
     */
    @Bean
    Queue myDelayQueue() {
        return new Queue("liufuqiang_queue_delay");
    }

    @Bean
    TopicExchange topicExchangeDelay() {
        return new TopicExchange("liufuqiang_topic_exchange_delay");
    }

    @Bean
    Binding myTopicBindingDelay() {
        Binding binding = BindingBuilder.bind(myDelayQueue()).to(topicExchangeDelay()).with("liufuqiang_delay_routing");
        return binding;
    }

    @Bean
    public com.rabbitmq.client.ConnectionFactory rabbitConnectionFactory() {
        com.rabbitmq.client.ConnectionFactory connectionFactory = new com.rabbitmq.client.ConnectionFactory();
        connectionFactory.setAutomaticRecoveryEnabled(true);
        connectionFactory.setUsername(rabbitmqUsername);
        connectionFactory.setPassword(rabbitmqPassword);
        connectionFactory.setHost(rabbitmqHost);
        connectionFactory.setPort(rabbitmqPort);
        connectionFactory.setVirtualHost("/");
        return connectionFactory;
    }

    @Bean("rabbitListenerContainerFactory")
    public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(
            SimpleRabbitListenerContainerFactoryConfigurer configurer, ConnectionFactory connectionFactory) {
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        factory.setPrefetchCount(2);
        factory.setConcurrentConsumers(3);
//        factory.setRecoveryInterval(recoveryInterval);
        configurer.configure(factory,  connectionFactory);
        return factory;
    }



}

二、生成者发送消息:

RabbitProducer.java

    @Autowired
    private RabbitTemplate rabbitTemplate;

    public void firstMessage(){
        Map<String, Object> message = new HashMap<>();
        message.put("name", "liufuqiang");
        message.put("age", "23");
        rabbitTemplate.convertAndSend("liufuqiang_topic_exchange", "liufuqiang_rountingKey.random", JSONUtils.toJSONString(message));
    }

调用发送消息接口,开始发送消息

 可以在管理界面看到交换机已新建完成,模式为topic模式

 队列liufuqiang_customer与交换机通过liufuqiang_rountingKey.*绑定起来,

 可以看到,刚才我们发送消息的rounting Key为liufuqiang_rountingKey.random,通过*匹配到,并且将消息发送给队列。

三、消费消息

RabbitConsumer.java

@Component
public class RabbitmqConsumer {

    private static Logger logger = LoggerFactory.getLogger(RabbitmqConsumer.class);

    @RabbitListener(queues = "liufuqiang_customer")
    @RabbitHandler
    //@Payload
    public void getRabbitmqMessage(String message){
        System.out.println(message);
        logger.warn("获取消息{}", message);
    }
}

可以看到队列liufuqiang_customer里的消息已被消费

 

posted @ 2021-01-15 17:13  木马不是马  阅读(1558)  评论(0编辑  收藏  举报