RabbitMQ之Fanout(扇形) Exchange解读

目录

基本介绍

适用场景

springboot代码演示

演示架构

工程概述

RabbitConfig配置类:创建队列及交换机并进行绑定

MessageService业务类:发送消息及接收消息

主启动类RabbitMq01Application:实现ApplicationRunner接口


基本介绍

Fanout Exchange交换机:当一个Msg发送到扇形交换机X上时,则扇形交换机X会将消息分别发送给所有绑定到X上的消息队列。扇形交换机将消息路由给绑定到自身的所有消息队列,也就是说路由键在扇形交换机里没有作用,故消息队列绑定扇形交换机时,路由键可为空。

  • 扇形交换机将消息路由给绑定到他身上的所有队列,给不理会绑定的路由键。
  • 某个扇形交换机上,当有消息发送到该扇形交换机上时,交换机会将消息的拷贝分别发送给这所有与之绑定的队列中。

Fanout交换机转发消息是最快的,Fanout Exchange交换机可以简单的理解为广播站。

适用场景

  • 适用于广播消息的场景
  • 群聊功能,广播消息给当前群聊中的所有人
  • 大型多人在线游戏的游戏积分排行榜更新
  • 体育新闻客户端实时更新分数
  • 分布式系统可以广播各种状态和配置更新

springboot代码演示

演示架构

生产者发送消息道fanout交换机上面,队列A和队列B绑定一个fanout交换机,消费则对队列A和队列B进行消费

工程概述

工程采用springboot架构,主要用到的依赖为:

<!--        rabbit的依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

application.yml配置文件如下:

server:
  port: 8080
spring:
  rabbitmq:
    host: 123.249.70.148
    port: 5673
    username: admin
    password: 123456
    virtual-host: /

RabbitConfig配置类:创建队列及交换机并进行绑定

创建 RabbitConfig类,这是一个配置类

java 复制代码
@Configuration
public class RabbitConfig {
 
 
}

定义交换机

java 复制代码
    @Bean
    public FanoutExchange fanoutExchange(){
        return new FanoutExchange("exchange.fanout");
    }

定义队列

java 复制代码
    @Bean
    public Queue queueA(){
        return new Queue("queue.fanout.a");
    }

    @Bean
    public Queue queueB(){
        return new Queue("queue.fanout.b");
    }

绑定交换机和队列

java 复制代码
    @Bean
    public Binding bindingA(FanoutExchange fanoutExchange,Queue queueA){
        return BindingBuilder.bind(queueA).to(fanoutExchange);
    }


    @Bean
    public Binding bindingB(FanoutExchange fanoutExchange,Queue queueB){
        return BindingBuilder.bind(queueB).to(fanoutExchange);
    }

MessageService业务类:发送消息及接收消息

java 复制代码
@Component
@Slf4j
public class MessageService {
    @Resource
    private RabbitTemplate rabbitTemplate;

}

发送消息方法

java 复制代码
   @Resource
    private RabbitTemplate rabbitTemplate;

    public void sendMsg(){
        String msg="hello world";
        Message message=new Message(msg.getBytes(StandardCharsets.UTF_8));
        rabbitTemplate.convertAndSend("exchange.fanout","",message);
        log.info("消息发送完毕....");
    }

MessageConvert

  • 涉及网络传输的应用序列化不可避免,发送端以某种规则将消息转成 byte 数组进行发送,接收端则以约定的规则进行 byte[] 数组的解析
  • RabbitMQ 的序列化是指 Messagebody 属性,即我们真正需要传输的内容,RabbitMQ 抽象出一个 MessageConvert 接口处理消息的序列化 ,其实现有 SimpleMessageConverter默认 )、Jackson2JsonMessageConverter

接受消息

java 复制代码
    @RabbitListener(queues = {"queue.fanout.a","queue.fanout.b"})
    public void receiveMsg(Message message){
        byte[] body = message.getBody();
        String msg=new String(body);
        log.info("接收到消息:"+msg);
    }

Message

在消息传递的过程中,实际上传递的对象为 org.springframework.amqp.core.Message ,它主要由两部分组成:

  1. MessageProperties // 消息属性

  2. byte[] body // 消息内容

@RabbitListener

使用 @RabbitListener 注解标记方法,当监听到队列 debug 中有消息时则会进行接收并处理

  • 消息处理方法参数是由 MessageConverter 转化,若使用自定义 MessageConverter 则需要在 RabbitListenerContainerFactory 实例中去设置(默认 Spring 使用的实现是 SimpleRabbitListenerContainerFactory)

  • 消息的 content_type 属性表示消息 body 数据以什么数据格式存储,接收消息除了使用 Message 对象接收消息(包含消息属性等信息)之外,还可直接使用对应类型接收消息 body 内容,但若方法参数类型不正确会抛异常:

    • application/octet-stream:二进制字节数组存储,使用 byte[]
    • application/x-java-serialized-object:java 对象序列化格式存储,使用 Object、相应类型(反序列化时类型应该同包同名,否者会抛出找不到类异常)
    • text/plain:文本数据类型存储,使用 String
    • application/json:JSON 格式,使用 Object、相应类型

主启动类RabbitMq01Application:实现ApplicationRunner接口

java 复制代码
/**
 * @author 风轻云淡
 */
@SpringBootApplication
public class RabbitMq01Application implements ApplicationRunner {

    public static void main(String[] args) {
        SpringApplication.run(RabbitMq01Application.class, args);
    }

    @Resource
    private MessageService messageService;

    /**
     * 程序一启动就会调用该方法
     * @param args
     * @throws Exception
     */
    @Override
    public void run(ApplicationArguments args) throws Exception {
        messageService.sendMsg();

    }
}

在SpringBoot中,提供了一个接口:ApplicationRunner。 该接口中,只有一个run方法,他执行的时机是:spring容器启动完成之后,就会紧接着执行这个接口实现类的run方法。

由于该方法是在容器启动完成之后,才执行的,所以,这里可以从spring容器中拿到其他已经注入的bean。

启动主启动类后查看控制台:

java 复制代码
2023-09-26 10:46:35.975  INFO 24900 --- [           main] 
c.e.rabbitmq01.service.MessageService    : 消息发送完毕....
2023-09-26 10:46:36.020  INFO 24900 --- [ntContainer#0-1] 
c.e.rabbitmq01.service.MessageService    : 接收到消息:hello world
2023-09-26 10:46:36.020  INFO 24900 --- [ntContainer#0-1] 
c.e.rabbitmq01.service.MessageService    : 接收到消息:hello world
相关推荐
冰淇淋烤布蕾11 分钟前
EasyExcel使用
java·开发语言·excel
Leo.yuan12 分钟前
数据量大Excel卡顿严重?选对报表工具提高10倍效率
数据库·数据分析·数据可视化·powerbi
拾荒的小海螺17 分钟前
JAVA:探索 EasyExcel 的技术指南
java·开发语言
Runing_WoNiu21 分钟前
MySQL与Oracle对比及区别
数据库·mysql·oracle
Jakarta EE33 分钟前
正确使用primefaces的process和update
java·primefaces·jakarta ee
马剑威(威哥爱编程)42 分钟前
哇喔!20种单例模式的实现与变异总结
java·开发语言·单例模式
天道有情战天下42 分钟前
mysql锁机制详解
数据库·mysql
看山还是山,看水还是。44 分钟前
Redis 配置
运维·数据库·redis·安全·缓存·测试覆盖率
谷新龙0011 小时前
Redis运行时的10大重要指标
数据库·redis·缓存
CodingBrother1 小时前
MySQL 中单列索引与联合索引分析
数据库·mysql