RabbitMQ篇——RabbitMQ支持消息模式,涵盖Simple简单模式、Fanout发布与订阅模式、Dicect路由模式、Topics主题模式、Headers参数模式以及Work模式,超全面!

Simple简单模式

介绍

简单模式就是,消息生产者将消息生产出来发送到交换机上,交换机再指定相关的队列,消费者只会绑定队列,通过队列来消费消息,专业上讲叫做订阅。

Fanout发布与订阅模式

详细介绍

一、发布于订阅模式架构图

二、图形化界面中操作发布与订阅模式
1、首先在docker上启动rabbitmq服务

[root@test /]# docker rm 5d7108ebc294
5d7108ebc294
[root@test /]# docker run -di --name myRabbitmq -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=admin -p 15672:15672 -p 5672:5672 -p 25672:25672 -p 61613:61613 -p 1883:1883 rabbitmq:3.8-management
3b2c7e9d42d9921711db71e391028c5d668e2a7db11a2170d592de58d87caa36
[root@test /]# docker ps 
CONTAINER ID        IMAGE                     COMMAND                  CREATED             STATUS              PORTS                                                                                                                                                                          NAMES
3b2c7e9d42d9        rabbitmq:3.8-management   "docker-entrypoint..."   7 seconds ago       Up 5 seconds        4369/tcp, 0.0.0.0:1883->1883/tcp, 5671/tcp, 0.0.0.0:5672->5672/tcp, 15671/tcp, 0.0.0.0:15672->15672/tcp, 0.0.0.0:25672->25672/tcp, 0.0.0.0:61613->61613/tcp, 15691-15692/tcp   myRabbitmq
688394b612e3        mysql:5.7.24              "docker-entrypoint..."   27 hours ago        Up 27 hours         33060/tcp, 0.0.0.0:3308->3306/tcp                                                                                                                                              mysql_3308
3a6793c964e0        mysql:latest              "docker-entrypoint..."   27 hours ago        Up 27 hours         33060/tcp, 0.0.0.0:3307->3306/tcp                                                                                                                                              mysql_3307
0e7d9e5a5143        docker_test-mycat         "/usr/local/mycat/..."   45 hours ago        Up 20 hours         0/tcp, 1984/tcp, 8066/tcp, 9066/tcp                                                                                                                                            test-mycat
[root@test /]# docker  start  3b2c7e9d42d9

2、在http://120.53.9.55:15672/中的交换机界面,建立发布与订阅模式的交换机

3、点击这个交换机 ,绑定 两个队列

4、通过Public message来模拟生产者 生产消息

5、我们进入 其中一个队列中,点击getmessage,就能成功直接订阅到生产者发布的消息

SpringBoot实现发布与订阅模式

1、创建一个SpringBoot项目,添加框架支持

2、观察pom中是否导入了关于MQ的依赖

3、在application.yaml中配置MQ
注意:如果不是在本地安装的MQ,那么一定记得修改对应的IP和开启对应的端口号安全组

# 服务端口
server:
  port: 8080
# 配置rabbitmq服务
spring:
  rabbitmq:
    username: admin
    password: admin
    virtual-host: /
    host: 120.53.9.55
    port: 5672

4、编写派发订单生产者的服务
 

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.UUID;
/**
* @Author xgh
* @Description 派发订单的服务
* @Date 2023/6/23 11:15
* @Return 
**/
@Service
public class OrderService {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    // 1: 定义交换机
    private String exchangeName = "fanout_order_exchange";
    // 2: 路由key
    private String routeKey = "";
    /**
    * @Author xgh
    * @Description 派发订单单服务
    * @Date 2023/6/23 10:46
    * @Return
    **/
    public void makeOrder(Long userId, Long productId, int num){
        // 1.模拟用户下单
        String orderId = UUID.randomUUID().toString();

        //2. 保存订单

        //3. 通过MQ来完成消息的分发
        rabbitTemplate.convertAndSend(exchangeName,routeKey,orderId);
    }
}

5、创建MQ的配置类,创建交换机、队列,并且绑定交换机和队列

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
 * @Author : JCccc
 * @CreateTime : 2019/9/3
 * @Description :
 **/
@Configuration
public class RabbitMqConfiguration {
    //1、声明创建队列
    @Bean
    public Queue emailQueue() {
        // durable:是否持久化,默认是false,持久化队列:会被存储在磁盘上,当消息代理重启时仍然存在,暂存队列:当前连接有效
        // exclusive:默认也是false,只能被当前创建的连接使用,而且当连接关闭后队列即被删除。此参考优先级高于durable
        // autoDelete:是否自动删除,当没有生产者或者消费者使用此队列,该队列会自动删除。
        //   return new Queue("TestDirectQueue",true,true,false);
        //一般设置一下队列的持久化就好,其余两个就是默认false
        return new Queue("email.fanout.queue", true);
    }
    @Bean
    public Queue smsQueue() {
        return new Queue("sms.fanout.queue", true);
    }
    @Bean
    public Queue weixinQueue() {
        return new Queue("weixin.fanout.queue", true);
    }
    //2、注册创建fanout交换机
    @Bean
    public FanoutExchange fanoutOrderExchange() {
        //  return new DirectExchange("TestDirectExchange",true,true);
        return new FanoutExchange("fanout_order_exchange", true, false);
    }
    //3、绑定  将队列和交换机绑定,用到了建造者模式BindingBuilder
    @Bean
    public Binding bindingDirect1() {
        return BindingBuilder.bind(weixinQueue()).to(fanoutOrderExchange());
    }
    @Bean
    public Binding bindingDirect2() {
        return BindingBuilder.bind(smsQueue()).to(fanoutOrderExchange());
    }
    @Bean
    public Binding bindingDirect3() {
        return BindingBuilder.bind(emailQueue()).to(fanoutOrderExchange());
    }
}

6、编写测试类,模拟派派发订单

@SpringBootTest
class SpringbootRabbitmqApplicationTests {

    @Autowired
    private OrderService orderService;

    @Test
    void contextLoads() {
        orderService.makeOrder(1L,123L,12);
    }

}

7、发现在可视化界面上,成功创建出了队列和交换机,并且队列中都有一条消息

8、在IDEA中新建一个模块,起名为Consumer消费者,上面我们可以通过生产者生产消息,下面我们就要创建消费者来消费消息

9、创建三个类型的消费服务

这里只列举其中一个服务内容

10、启动消费者模块的服务,观察控制台打印

当我启动消费者的测试代码往队列里创建消息,这里因为我们的消费者服务通过@RabbitListener对队列进行了监听绑定,所以直接就能订阅到生产者发布的消息!

Dicect路由模式

详细介绍

一、架构图

二、操作路由模式
1、在交换机位置创建路由模式的交换机

2、点进这个direct-exchange交换机,给三个队列绑定路由key,注意一个队列可以绑定多个不同 的路由key

3、我给email这个key发送消息,此时应该是queue1和queue3能够收到消息

4、点击队列查看,确实这两个队列多了两条消息

三、结论
路由模式,就是将队列进行一个分类,我们可以选择给某一类的队列发送消息!消费消息变得更加灵活!

SpringBoot实现路由模式

1、前面的依赖的引入就不赘述

2、编写配置类
这个配置类尽量写到消费者的服务中,因为我们首先都会先启动消费者的服务,但是 消费者的服务中绑定的队列如果还没被加载创建,那么系统就会报错!

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @Author : JCccc
 * @CreateTime : 2019/9/3
 * @Description :
 **/
@Configuration
public class RabbitMqConfiguration {
    //1、声明创建队列
    @Bean
    public Queue emailQueue() {
        // durable:是否持久化,默认是false,持久化队列:会被存储在磁盘上,当消息代理重启时仍然存在,暂存队列:当前连接有效
        // exclusive:默认也是false,只能被当前创建的连接使用,而且当连接关闭后队列即被删除。此参考优先级高于durable
        // autoDelete:是否自动删除,当没有生产者或者消费者使用此队列,该队列会自动删除。
        //   return new Queue("TestDirectQueue",true,true,false);
        //一般设置一下队列的持久化就好,其余两个就是默认false
        return new Queue("email.direct.queue", true);
    }

    @Bean
    public Queue smsQueue() {
        return new Queue("sms.direct.queue", true);
    }

    @Bean
    public Queue weixinQueue() {
        return new Queue("weixin.direct.queue", true);
    }

    //2、注册创建direct交换机
    @Bean
    public DirectExchange directExchange() {
        //  return new DirectExchange("TestDirectExchange",true,true);
        //后面两个参数是持久化和自动删除
        return new DirectExchange("direct_order_exchange", true, false);
    }

    //3、绑定  将队列和交换机绑定,路由模式的区别在于后面还有一个参数with,是绑定路由key的功能!
    @Bean
    public Binding bindingDirect1() {
        return BindingBuilder.bind(weixinQueue()).to(directExchange()).with("weixin");
    }

    @Bean
    public Binding bindingDirect2() {
        return BindingBuilder.bind(smsQueue()).to(directExchange()).with("sms");
    }

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

3、编写生产者生产消息的service层
这里只是给sms和email发送消息!

 /**
     * @Author xgh
     * @Description 路由模式派发订单服务
     * @Date 2023/6/23 10:46
     * @Return
     **/
    public void makeOrderDirect(Long userId, Long productId, int num) {

        // 1: 定义交换机
         String exchangeName = "direct_order_exchange";
        // 2: 路由key
         String routeKey1 = "sms";
         String routeKey2 = "email";
        // 1.模拟用户下单
        String orderId = UUID.randomUUID().toString();

        //2. 保存订单

        //3. 通过MQ来完成消息的分发
        //通过路由key完成对sms和email的消息发送
        rabbitTemplate.convertAndSend(exchangeName, routeKey1, orderId);
        rabbitTemplate.convertAndSend(exchangeName, routeKey2, orderId);
    }

4、编写消费者服务
三个消费者绑定好对应的队列

import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;

//@RabbitListener指定方法作为消息消费的方法,例如监听email.fanout.queue里面的消息
@RabbitListener(queues = "email.direct.queue")
@Service
public class DirectEmailConsumer {

    //定义接收消息的方法,@RabbitHandler作用是@RabbitListener监听到消息,它会将消息拿到并交给方法来处理
    @RabbitHandler
    public void reviceMessage(String message){
        System.out.println("Email direct--接收到了订单信息是:->" + message);
    }
}


@RabbitListener(queues = "sms.direct.queue")
@Service
public class DirectSmsConsumer {
    //定义接收消息的方法,@RabbitHandler作用是@RabbitListener监听到消息,它会将消息拿到并交给方法来处理
    @RabbitHandler
    public void reviceMessage(String message){
        System.out.println("Sms direct--接收到了订单信息是:->" + message);
    }
}


@RabbitListener(queues = "weixin.direct.queue")
@Service
public class DirectWeixinConsumer {
    //定义接收消息的方法,@RabbitHandler作用是@RabbitListener监听到消息,它会将消息拿到并交给方法来处理
    @RabbitHandler
    public void reviceMessage(String message){
        System.out.println("Weixin direct--接收到了订单信息是:->" + message);
    }

}

5、先启动消费者服务,在启动生产者的测试类,最后就能在消费者的控制台中看到对应的队列接收到了消息!
生产者的测试类

消费者服务控制台

Topics主题模式(常用)

详细介绍

一、主题模式架构图
区别于路由模式,这个支持的是模糊发送消息

二、使用方法
1、在可视化界面上创建主题模式的交换机

2、模糊绑定队列
规则是:
(以下所说的级别,通俗的讲就是单词!)
#:代表在某个级别后面可以有一个或者多个级别,都会符合条件
*:代表必须有且只有1级,才能符合条件

3、通过输入特定的路由key来指定特定的队列接收消息

使用主机绑定队列

在消费者的服务中,使用注解对相关的队列和交换机进行绑定

1. package com.xuexiangban.rabbitmq.springbootrabbitmqfanoutconsumer.consumer;
2. 
3. import org.springframework.amqp.core.ExchangeTypes;
4. import org.springframework.amqp.rabbit.annotation.*;
5. import org.springframework.stereotype.Component;
6. 
7. // bindings其实就是用来确定队列和交换机绑定关系
8. @RabbitListener(bindings =@QueueBinding(
9.  // email.fanout.queue 是队列名字,这个名字你可以自定随便定义。
10.  value = @Queue(value = "email.fanout.queue",autoDelete = "false"),
11.  // order.fanout 交换机的名字 必须和生产者保持一致
12.  exchange = @Exchange(value = "fanout_order_exchange",
13.  // 这里是确定的rabbitmq模式是:fanout 是以广播模式 、 发布订阅模式
14.  type = ExchangeTypes.FANOUT)
15. ))
16. @Component
17. public class EmailService {
18.  // @RabbitHandler 代表此方法是一个消息接收的方法。该不要有返回值
19.  @RabbitHandler
20.  public void messagerevice(String message){
21.  // 此处省略发邮件的逻辑
22.  System.out.println("email-------------->" + message);
23.  }
24. }

Headers参数模式

详细介绍

发送消息的时候,输入对应的参数

该模式就是给某一个队列绑定到交换机上的时候,绑定一个参数,当我们想发送消息的时候,输入对应的参数,之前绑定的队列就能接收到消息

Work模式

详细介绍

该模式存在两种细分的模式,如下:
当有多个消费者时,我们的消息会被哪个消费者消费呢,我们又该如何均衡消费者消费信息的多少呢?
主要有两种模式:
1、轮询模式的分发:一个消费者一条,按均分配;
2、公平分发:根据消费者的消费能力进行公平分发,处理快的处理的多,处理慢的处理的少;按劳分配;

当存在多个消费者的时候,如果不指定消息模式,并且默认就是轮询模式

至此,关于RabbitMQ支持的消息模式已经介绍完毕,模式类型比较多,建议大家能够反复学习!

后续还会持续更新关于消息队列的技术点,敬请期待~

  • 25
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Be explorer

若认可笔者文章,手头富裕望支持

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

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

打赏作者

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

抵扣说明:

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

余额充值