[RabbitMQ--->消息队列]

一、MQ

MQ,中文是消息队列(MessageQueue),字面来看就是存放消息的队列。也就是事件驱动架构中的Broker。

比较常见的MQ实现:

- ActiveMQ
- RabbitMQ
- RocketMQ
- Kafka

二、RabbitMQ

异步通讯带来的优缺点

好处:
- 吞吐量提升:无需等待订阅者处理完成,响应更快速
- 故障隔离:服务没有直接调用,不存在级联失败问题
- 调用间没有阻塞,不会造成无效的资源占用
- 耦合度极低,每个服务都可以灵活插拔,可替换
- 流量削峰:不管发布事件的流量波动多大,都由Broker接收,订阅者可以按照自己的速度去处理事件

缺点:
- 架构复杂了,业务没有明显的流程线,不好管理
- 需要依赖于Broker的可靠、安全、性能

三、前置工作

导入依赖

<!--AMQP依赖,包含RabbitMQ-->
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

配置信息

spring:
 rabbitmq:
   host:  # 主机名
   port: 5672 # 端口
   virtual-host: / # 虚拟主机
   username: # 用户名
   password: # 密码

四、五种模式及代码实现

1.Basic Queue 简单队列模型

在这里插入图片描述
代码实现:

发送消息:
rabbitTemplate.convertAndSend("mySimple.queue",message.getBytes(StandardCharsets.UTF_8));

监听消费消息:
    @RabbitListener(queues = "mySimple.queue")
    public void handleSimple(String message) throws InterruptedException {
        Thread.sleep(300);
        log.info("消费者收到消息:{}",message);
    }

2.WorkQueue 工作队列

在这里插入图片描述

发送消息
  /**
     * workQueueTest模式测试
     */
    @Test
    void workQueueTest() {
        for (int i = 1; i <= 50; i++) {
            String message = "Hello,WorkQueue!!!"+i;
            rabbitTemplate.convertAndSend("mySimple.queue",message.getBytes(StandardCharsets.UTF_8));
        }
        System.out.println("消息发送成功");
    }

消费消息:
    @RabbitListener(queues = "mySimple.queue")
    public void handleSimple(String message) throws InterruptedException {
        Thread.sleep(300);
        log.info("消费者收到消息:{}",message);
    }

可以配置以下信息,实现能者多劳:

spring:
rabbitmq:
  listener:
    simple:
      prefetch: 1 # 每次只能获取一条消息,处理完成才能获取下一个消息

3.Fanout 发布订阅

在这里插入图片描述
代码实现:

 发送消息:
 @Test
    void fanoutTest() {
        String message = "Hello,Fanout!!!";
        rabbitTemplate.convertAndSend("itcast.fanout","",message);
        System.out.println("消息发送成功");
    }
    
监听消费消息:
 //===================fanout模式
    @RabbitListener(queues = "fanout.queue1")
    public void handleQueueFirst(String message) throws InterruptedException {
        log.info("fanout.queue1消息:{}",message);
    }

    @RabbitListener(queues = "fanout.queue2")
    public void handleQueueSecond(String message) throws InterruptedException {
        log.info("fanout.queue2消息:{}",message);
    }
    
以上需要配置文件声明交换机并绑定队列到交换机:
      /**
     * 声明交换机名称
     * @return
     */
    @Bean
    public FanoutExchange fanoutExchange(){
        return new FanoutExchange("itcast.fanout");
    }

    /**
     * 声明队列一名称
     * @return
     */
    @Bean
    public Queue queueFirst(){
        return new Queue("fanout.queue1");
    }

    /**
     * 声明队列二名称
     * @return
     */
    @Bean
    public Queue queueSecond(){
        return new Queue("fanout.queue2");
    }

    /**
     * 绑定队列一到交换机
     * @param queueFirst
     * @param fanoutExchange
     * @return
     */
    @Bean
    public Binding bindingQueueFirst(Queue queueFirst,FanoutExchange fanoutExchange){
        return BindingBuilder.bind(queueFirst).to(fanoutExchange);
    }

    /**
     * 绑定队列二到交换机
     * @param queueSecond
     * @param fanoutExchange
     * @return
     */
    @Bean
    public Binding bindingQueueSecond(Queue queueSecond,FanoutExchange fanoutExchange){
        return BindingBuilder.bind(queueSecond).to(fanoutExchange);
    }

4. Direct 路由模式

在这里插入图片描述
代码实现:

发送消息:
   /**
     * direct模式测试
     */
    @Test
    void directTest() {
        rabbitTemplate.convertAndSend("itheima.direct","spring","direct spring message");
        rabbitTemplate.convertAndSend("itheima.direct","summer","direct summer message");
        rabbitTemplate.convertAndSend("itheima.direct","winter","direct winter message");
        rabbitTemplate.convertAndSend("itheima.direct","autumn","direct autumn message");
        System.out.println("消息发送成功");
    }
    
监听消费消息:
    //===================direct模式
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(name = "itheima.direct.queue1"),
            exchange = @Exchange(name = "itheima.direct",type = ExchangeTypes.DIRECT),
            key={"spring","summer"}
    ))
    public void handleDircetQueueFirst(String message)
    {
        log.info("direct.queue1:{}",message);
    }

    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(name = "itheima.direct.queue2"),
            exchange = @Exchange(name = "itheima.direct",type = ExchangeTypes.DIRECT),
            key={"summer","winter"}
    ))
    public void handleDircetQueueSecond(String message){
        log.info("direct.queue2:{}",message);
    }

5. Topic 主题模式

在这里插入图片描述
代码实现:

发送消息:
   /**
     * topic模式测试
     */
    @Test
    void topicTest() {
        rabbitTemplate.convertAndSend("itcast.topic","china.Number.One","chinaNumberOne");
        rabbitTemplate.convertAndSend("itcast.topic","china.NumberOne.news","chinaNumberOnenews");
        rabbitTemplate.convertAndSend("itcast.topic","NumberOne","NumberOne");
        rabbitTemplate.convertAndSend("itcast.topic","my.news","mynews");
        System.out.println("消息发送成功");
    }
    
监听消费消息:
    //===================topic模式
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(name = "topic.queue1"),
            exchange = @Exchange(name = "itcast.topic",type = ExchangeTypes.TOPIC),
            key="china.#"
    ))
    public void handleTopicQueueFirst(String message){
        log.info("topic.queue1:{}",message);
    }

    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(name = "topic.queue2"),
            exchange = @Exchange(name = "itcast.topic",type = ExchangeTypes.TOPIC),
            key="#.news"
    ))
    public void handleTopicQueueSecond(String message){
        log.info("topic.queue2:{}",message);
    }

6. 消息转换器

所需依赖:

可以使用JSON方式来做序列化和反序列化。
<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
    <version>2.9.5</version>
</dependency>

需要配置消息转换器:

/**
 * 消息转换器配置类
 * @Description
 * @Author Wcmy.m
 * @Date 2023-05-17 17:46:42
 */
@Configuration
public class MessageConverterConfig {

    @Bean
    public MessageConverter jsonMessageConverter(){
        return new Jackson2JsonMessageConverter();
    }
}

实例:
发送消息:
   /**
     * 消息转换器测试
     */
    @Test
    void simpleTest() {

        User user = User.builder()
                .id(11L)
                .name("张三")
                .gender(1).build();
            rabbitTemplate.convertAndSend("mySimple.queue",user);
        System.out.println("消息发送成功");
    }

消费者监听消费消息:
    /**
     * 消息转换器
     */
    @RabbitListener(queues = "mySimple.queue")
    public void handleSimpleObject(User user) throws InterruptedException {
        //Thread.sleep(300);
        log.info("消费者收到实体:{}",user);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值