RabbitMQ01:消息队列三种常用模式之fanout发布/订阅模式、direct路由模式、topic主题模式

本文介绍了RabbitMQ中的三种消息队列模式:fanout发布/订阅模式,允许消息一次性发布并被多个消费者接收;direct路由模式,基于路由键将消息分发至特定队列;以及topic主题模式,使用模糊匹配路由键进行消息过滤。通过代码演示阐述了每种模式的工作原理和应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、fanout发布/订阅模式

生产者可以将消息发送给不同类型的消费者。做到发布一次,消费多次。如下图:

在这里插入图片描述

  • 代码演示
    1、生产者模拟下订单
@Service
public class OrderService {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    //fanout模式模拟下单
    public void makeOrderFanout(String userId, String productId, int num) {
        //1、生成订单
        String orderId = UUID.randomUUID().toString();
        System.out.println("fanout生成订单:" + orderId);
        //2、通过MQ队列完成消息分发
        String exchangeName = "fanout-order-exchange";
        String routingKey = "";
        rabbitTemplate.convertAndSend(exchangeName, routingKey, orderId);
    }
    }

2、三个消费者绑定交换机

@Configuration
public class FanoutRabbitmqConfig {

    //1、声明注册fanout式交换机
    @Bean
    public FanoutExchange fanoutExchange() {
        return new FanoutExchange("fanout-order-exchange", true, false);
    }

    //2、声明三个队列
    @Bean
    public Queue smsQueue() {
        return new Queue("sms-fanout-queue", true);
    }

    @Bean
    public Queue dxQueue() {
        return new Queue("dx-fanout-queue", true);
    }

    @Bean
    public Queue emailQueue() {
        return new Queue("email-fanout-queue", true);
    }

    //3、完成交换机和队列的绑定关系
    @Bean
    public Binding smsBinding() {
        return BindingBuilder.bind(smsQueue()).to(fanoutExchange());
    }

    @Bean
    public Binding dxBinding() {
        return BindingBuilder.bind(dxQueue()).to(fanoutExchange());
    }

    @Bean
    public Binding emailBinding() {
        return BindingBuilder.bind(emailQueue()).to(fanoutExchange());
    }
}

3、三个消费者消费消息

@Component
@RabbitListener(queues = "sms-fanout-queue")
public class FanoutSmsService {

    @RabbitHandler
    public void recieveMesage(String msg) {
        System.out.println("fanout的sms队列接收到了消息:" + msg);
    }
}
@Component
@RabbitListener(queues = "email-fanout-queue")
public class FanoutEmailService {

    @RabbitHandler
    public void recieveMesage(String msg) {
        System.out.println("fanout邮件队列接收到了消息:" + msg);
    }
}
@Component
@RabbitListener(queues = "dx-fanout-queue")
public class FanoutDxService {

    @RabbitHandler
    public void recieveMesage(String msg) {
        System.out.println("fanout短信队列接收到了消息:" + msg);
    }
}

4、测试代码

@SpringBootTest
class SpringbootRabbitmqApplicationTests {

    @Autowired
    private OrderService orderService;

    @Test
    void contextLoads() {
        orderService.makeOrderFanout("1", "1", 12);
    }
      }

运行结果:
生产者:
在这里插入图片描述
消费者:
在这里插入图片描述

二、direct路由模式

路由模式跟发布订阅模式类似,路由模式是在订阅模式的基础上加上了路由键key,订阅模式是分发到所有绑定到交换机的队列,路由模式只分发到绑定在交换机上面指定路由键的队列,如下图:

在这里插入图片描述

  • 代码演示
    1、生产者模拟下单
@Service
public class OrderService {

    @Autowired
    private RabbitTemplate rabbitTemplate;
        
    //direct模式模拟下单
    public void makeOrderDirect(String userId, String productId, int num) {
        //1、生成订单
        String orderId = UUID.randomUUID().toString();
        System.out.println("direct模式生成订单:" + orderId);
        //2、通过MQ队列完成消息分发
        String exchangeName = "direct-order-exchange";
        rabbitTemplate.convertAndSend(exchangeName, "dx", orderId);
        rabbitTemplate.convertAndSend(exchangeName, "wx", orderId);
    }

}

2、给消费者根据路由键key绑定交换机(只给短信和微信指定路由键)

@Configuration
public class DirectRabbitmqConfig {

    //1、声明注册direct式交换机
    @Bean
    public DirectExchange directExchange() {
        return new DirectExchange("direct-order-exchange", true, false);
    }

    //2、声明三个队列
    @Bean
    public Queue wxDirectQueue() {
        return new Queue("wx-direct-queue", true);
    }

    @Bean
    public Queue dxDirectQueue() {
        return new Queue("dx-direct-queue", true);
    }

    @Bean
    public Queue emailDirectQueue() {
        return new Queue("email-direct-queue", true);
    }

    //3、完成交换机和队列的饿绑定关系
    @Bean
    public Binding wxDirectBinding() {
        return BindingBuilder.bind(wxDirectQueue()).to(directExchange()).with("wx");
    }

    @Bean
    public Binding dxDirectBinding() {
        return BindingBuilder.bind(dxDirectQueue()).to(directExchange()).with("dx");
    }

    @Bean
    public Binding emailDirectBinding() {
        return BindingBuilder.bind(emailDirectQueue()).to(directExchange()).with("email");
    }

}

3、消费者消费消息

@Component
public class DirectDXService {

    @RabbitListener(queues = "dx-direct-queue")
    public void recieveMesage(String msg) {
        System.out.println("direct短信队列接消费了消息:" + msg);
    }
}
@Component
public class DirectEmailService {

    @RabbitListener(queues = "email-direct-queue")
    public void recieveMesage(String msg) {
        System.out.println("direct邮件队列接消费了消息:" + msg);
    }
}

@Component
public class DirectWXService {


    @RabbitListener(queues = "sms-direct-queue")
    public void recieveMesage(String msg) {
        System.out.println("direct的微信队列接收到了消息:" + msg);
    }
}

4、测试代码

@SpringBootTest
class RabbitmqProducerApplicationTests {

    @Autowired
    private OrderService orderService;

    @Test
    void contextLoadsDirect() {
        orderService.makeOrderDirect("1", "1", 12);
    }

}

运行结果:
生产者:
在这里插入图片描述

消费者:
在这里插入图片描述

三、topic主题模式

topics 主题模式跟 routing 路由模式类似,只不过路由模式是指定固定的路由键 routingKey,而主题模式是可以模糊匹配路由键 routingKey,可以类比为mysql中的like模糊查询,如下图

在这里插入图片描述

  • 代码演示
    1、模拟生产者下单
@Service
public class OrderService {

     @Autowired
     private RabbitTemplate rabbitTemplate;

    //topic模式模拟下单
    public void makeOrderTopic(String userId, String productId, int num) {
        //1、生成订单
        String orderId = UUID.randomUUID().toString();
        System.out.println("topic生成订单:" + orderId);
        //2、通过MQ队列完成消息分发
        String exchangeName = "topic-order-exchange";
        String routingKey = "haha.dx.email";
        rabbitTemplate.convertAndSend(exchangeName, routingKey, orderId);
    }
}

2、消费者队列绑定路由器(设置路由键之匹配短信和邮件)

@Configuration
public class TopicRabbitmqConfig {

    //1、声明注册topic式交换机
    @Bean
    public TopicExchange topicExchange() {
        return new TopicExchange("topic-order-exchange", true, false);
    }

    //2、声明三个队列
    @Bean
    public Queue wxtopicQueue() {
        return new Queue("wx-topic-queue", true);
    }

    @Bean
    public Queue dxtopicQueue() {
        return new Queue("dx-topic-queue", true);
    }

    @Bean
    public Queue emailtopicQueue() {
        return new Queue("email-topic-queue", true);
    }

    //3、完成交换机和队列的绑定关系
    @Bean
    public Binding wxtopicBinding() {
        return BindingBuilder.bind(wxtopicQueue()).to(topicExchange()).with("com.#");
    }

    @Bean
    public Binding dxtopicBinding() {
        return BindingBuilder.bind(dxtopicQueue()).to(topicExchange()).with("*.dx.*");
    }

    @Bean
    public Binding emailtopicBinding() {
        return BindingBuilder.bind(emailtopicQueue()).to(topicExchange()).with("*.#.email");
    }

}

3、短信和邮件队列消费生产者消息

@Component
@RabbitListener(queues = "dx-topic-queue")
public class TopicDXService {

    @RabbitHandler
    public void recieveMesage(String msg) {
        System.out.println("topic短信队列接消费了消息:" + msg);
    }
}
@Component
@RabbitListener(queues = "email-topic-queue")
public class TopicEmailService {

    @RabbitHandler
    public void recieveMesage(String msg) {
        System.out.println("topic邮件队列接消费了消息:" + msg);
    }
}
@Component
@RabbitListener(queues = "wx-topic-queue")
public class TopicWXService {

    @RabbitHandler
    public void recieveMesage(String msg) {
        System.out.println("topic的sms队列接消费了消息:" + msg);
    }
}

4、测试代码

@SpringBootTest
class RabbitmqProducerApplicationTests {

    @Autowired
    private OrderService orderService;

    @Test
    void contextLoadsTopic() {
        orderService.makeOrderTopic("1", "1", 12);
    }

}

运行结果:
生产者:
在这里插入图片描述
消费者:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

微笑AJJD

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值