当前位置:

首页 > 编程开发 > SpringBoot如何集成RabbitMQ

SpringBoot如何集成RabbitMQ

一、RabbitMQ介绍RabbitMQ是实现AMQP(高级消息队列协议)的消息中间件的一种,最初起源于金融系统,用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。RabbitMQ主要是为了实现系统之间的双向解耦而实现的。当生产者大量产生数据时,消费者无法快速消费,那么需要一个中间层。保存这个数据。AMQP,即AdvancedMessageQueuingProtocol,高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。消息中间件主要用于组件之间的解耦,消息的发

本文目录

    一、RabbitMQ介绍

    RabbitMQ是实现AMQP(高级消息队列协议)的消息中间件的一种,最初起源于金融系统,用于在分布式系统中存储转发消息,在易用性、扩展性、 高可用性等方面表现不俗。RabbitMQ主要是为了实现系统之间的双向解耦而实现的。当生产者大量产生数据时,消费者无法快速消费,那么需要一个中间层。保存这个数据。

    AMQP,即Advanced Message Queuing Protocol,高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。消息中间件主要用于组件之间的解耦,消息的发送者无需知道消息使用者的存在,反之亦然。AMQP的主要特征是面向消息、队列、路由(包括点对点和发布/订阅)、可靠性、安全。

    RabbitMQ是一个开源的AMQP实现,服务器端用Erlang语言编写,支持多种客户端,如:Python、Ruby、.NET、Java、JMS、C、PHP、ActionScript、XMPP、STOMP等,支持AJAX。用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。

    SpringBoot如何集成RabbitMQ

    二、相关概念

    通常我们谈到队列服务, 会有三个概念: 发消息者、队列、收消息者,RabbitMQ 在这个基本概念之上, 多做了一层抽象, 在发消息者和 队列之间, 加入了交换器 (Exchange). 这样发消息者和队列就没有直接联系, 转而变成发消息者把消息给交换器, 交换器根据调度策略再把消息再给队列

    • 左侧 P 代表 生产者,也就是往 RabbitMQ 发消息的程序。

    • 中间即是 RabbitMQ,其中包括了 交换机 和 队列。

    • 右侧 C 代表 消费者,也就是往 RabbitMQ 拿消息的程序。

    其中比较重要概念有 4 个,分别为:虚拟主机,交换机,队列,和绑定。

    • 虚拟主机:一个虚拟主机持有一组交换机、队列和绑定。为什么需要多个虚拟主机呢?很简单,RabbitMQ当中,用户只能在虚拟主机的粒度进行权限控制。 因此,如果需要禁止A组访问B组的交换机/队列/绑定,必须为A和B分别创建一个虚拟主机。每一个RabbitMQ服务器都有一个默认的虚拟主机“/”。

    • 交换机:Exchange 用于转发消息,但是它不会做存储 ,如果没有 Queue bind 到 Exchange 的话,它会直接丢弃掉 Producer 发送过来的消息。

    这里有一个比较重要的概念:路由键 。消息到交换机的时候,交互机会转发到对应的队列中,那么究竟转发到哪个队列,就要根据该路由键。

    • 绑定:也就是交换机需要和队列相绑定,这其中如上图所示,是多对多的关系。

    SpringBoot集成RabbitMQ非常简单,如果只是简单的使用配置非常少,springboot提供了spring-boot-starter-amqp项目对消息各种支持。

    SpringBoot如何集成RabbitMQ

    SpringBoot如何集成RabbitMQ

    三、简单使用

    1.配置pom包

    主要是添加spring-boot-starter-amqp的支持

    
    org.springframework.boot
    spring-boot-starter-amqp
    

    2.配置文件

    配置rabbitmq的安装地址、端口以及账户信息.

    spring.application.name=spirng-boot-rabbitmq
    spring.rabbitmq.host=192.168.0.86
    spring.rabbitmq.port=5672
    spring.rabbitmq.username=admin
    spring.rabbitmq.password=123456

    3.队列配置

    @Configuration
    public class RabbitConfig {
    @Bean
    public Queue Queue() {
    return new Queue("hello");
    }
    }

    4.发送者

    rabbitTemplate是springboot 提供的默认实现
    public class HelloSender {
    @Autowired
    private AmqpTemplate rabbitTemplate;
    public void send() {
    String context = "hello " + new Date();
    System.out.println("Sender : " + context);
    this.rabbitTemplate.convertAndSend("hello", context);
    }
    }

    5.接收者

    @Component
    @RabbitListener(queues = "hello")
    public class HelloReceiver {
    @RabbitHandler
    public void process(String hello) {
    System.out.println("Receiver : " + hello);
    }
    }

    6.测试

    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class RabbitMqHelloTest {
    @Autowired
    private HelloSender helloSender;
    @Test
    public void hello() throws Exception {
    helloSender.send();
    }
    }

    注意:发送者和接收者的queue name必须一致,不然不能接收

    多对多使用

    一个发送者,N个接收者或者N个发送者和N个接收者会出现什么情况呢?

    一对多发送

      对上面的代码进行了小改造,接收端注册了两个Receiver,Receiver1和Receiver2,发送端加入参数计数,接收端打印接收到的参数,下面是测试代码,发送一百条消息,来观察两个接收端的执行效果.

    @Test
    public void oneToMany() throws Exception {
    for (int i=0;i<100;i++){
    neoSender.send(i);
    }
    }

    结果如下:

    Receiver 1: spirng boot neo queue ****** 11
    Receiver 2: spirng boot neo queue ****** 12
    Receiver 2: spirng boot neo queue ****** 14
    Receiver 1: spirng boot neo queue ****** 13
    Receiver 2: spirng boot neo queue ****** 15
    Receiver 1: spirng boot neo queue ****** 16
    Receiver 1: spirng boot neo queue ****** 18
    Receiver 2: spirng boot neo queue ****** 17
    Receiver 2: spirng boot neo queue ****** 19
    Receiver 1: spirng boot neo queue ****** 20

    根据返回结果得到以下结论

    一个发送者,N个接受者,经过测试会均匀的将消息发送到N个接收者中

    多对多发送

    复制了一份发送者,加入标记,在一百个循环中相互交替发送

    @Test
    public void manyToMany() throws Exception {
    for (int i=0;i<100;i++){
    neoSender.send(i);
    neoSender2.send(i);
    }
    }

    结果如下:

    Receiver 1: spirng boot neo queue ****** 20
    Receiver 2: spirng boot neo queue ****** 20
    Receiver 1: spirng boot neo queue ****** 21
    Receiver 2: spirng boot neo queue ****** 21
    Receiver 1: spirng boot neo queue ****** 22
    Receiver 2: spirng boot neo queue ****** 22
    Receiver 1: spirng boot neo queue ****** 23
    Receiver 2: spirng boot neo queue ****** 23
    Receiver 1: spirng boot neo queue ****** 24
    Receiver 2: spirng boot neo queue ****** 24
    Receiver 1: spirng boot neo queue ****** 25
    Receiver 2: spirng boot neo queue ****** 25

    结论:和一对多一样,接收端仍然会均匀接收到消息.

    四、高级使用

    //对象的支持
    //springboot以及完美的支持对象的发送和接收,不需要格外的配置。
    //发送者
    public void send(User user) {
    System.out.println("Sender object: " + user.toString());
    this.rabbitTemplate.convertAndSend("object", user);
    }
    ...
    //接受者
    @RabbitHandler
    public void process(User user) {
    System.out.println("Receiver object : " + user);
    }

    结果如下:

    Sender object: User{name='neo', pass='123456'}
    Receiver object : User{name='neo', pass='123456'}

    1.Topic Exchange

    topic 是RabbitMQ中最灵活的一种方式,可以根据routing_key自由的绑定不同的队列

    首先对topic规则配置,这里使用两个队列来测试

    SpringBoot如何集成RabbitMQ

    @Configuration
    public class TopicRabbitConfig {
    
    final static String message = "topic.message";
    final static String messages = "topic.messages";
    
    @Bean
    public Queue queueMessage() {
    return new Queue(TopicRabbitConfig.message);
    }
    
    @Bean
    public Queue queueMessages() {
    return new Queue(TopicRabbitConfig.messages);
    }
    
    @Bean
    TopicExchange exchange() {
    return new TopicExchange("exchange");
    }
    
    @Bean
    Binding bindingExchangeMessage(Queue queueMessage, TopicExchange exchange) {
    return BindingBuilder.bind(queueMessage).to(exchange).with("topic.message");
    }
    
    @Bean
    Binding bindingExchangeMessages(Queue queueMessages, TopicExchange exchange) {
    return BindingBuilder.bind(queueMessages).to(exchange).with("topic.#");
    }
    }

    使用queueMessages同时匹配两个队列,queueMessage只匹配"topic.message"队列

    public void send1() {
    String context = "hi, i am message 1";
    System.out.println("Sender : " + context);
    this.rabbitTemplate.convertAndSend("exchange", "topic.message", context);
    }
    
    public void send2() {
    String context = "hi, i am messages 2";
    System.out.println("Sender : " + context);
    this.rabbitTemplate.convertAndSend("exchange", "topic.messages", context);
    }

    发送send1会匹配到topic.#和topic.message 两个Receiver都可以收到消息,发送send2只有topic.#可以匹配所有只有Receiver2监听到消息

    2.Fanout Exchange

    Fanout 就是我们熟悉的广播模式或者订阅模式,给Fanout交换机发送消息,绑定了这个交换机的所有队列都收到这个消息。

    SpringBoot如何集成RabbitMQ

    Fanout 相关配置:

    @Configuration
    public class FanoutRabbitConfig {
    
    @Bean
    public Queue AMessage() {
    return new Queue("fanout.A");
    }
    
    @Bean
    public Queue BMessage() {
    return new Queue("fanout.B");
    }
    
    @Bean
    public Queue CMessage() {
    return new Queue("fanout.C");
    }
    @Bean
    FanoutExchange fanoutExchange() {
    return new FanoutExchange("fanoutExchange");
    }
    @Bean
    Binding bindingExchangeA(Queue AMessage,FanoutExchange fanoutExchange) {
    return BindingBuilder.bind(AMessage).to(fanoutExchange);
    }
    @Bean
    Binding bindingExchangeB(Queue BMessage, FanoutExchange fanoutExchange) {
    return BindingBuilder.bind(BMessage).to(fanoutExchange);
    }
    @Bean
    Binding bindingExchangeC(Queue CMessage, FanoutExchange fanoutExchange) {
    return BindingBuilder.bind(CMessage).to(fanoutExchange);
    }
    }

    这里使用了A、B、C三个队列绑定到Fanout交换机上面,发送端的routing_key写任何字符都会被忽略:

    public void send() {
    String context = "hi, fanout msg ";
    System.out.println("Sender : " + context);
    this.rabbitTemplate.convertAndSend("fanoutExchange","", context);
    }

    结果如下:

    Sender : hi, fanout msg
    ...
    fanout Receiver B: hi, fanout msg
    fanout Receiver A : hi, fanout msg
    fanout Receiver C: hi, fanout msg

    结果说明,绑定到fanout交换机上面的队列都收到了消息.

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发
    相关文章 更多
    RabbitMQ Fanout Exchange 多消费者正确实现指南
    RabbitMQ Fanout Exchange 多消费者正确实现指南

    在Go中使用RabbitMQFanoutExchange时,多个消费者需同时接收消息。正确做法是声明fanout类型交换器,并为每个消费者创建独立队列并绑定到该交换器,确保交换器类型正确、队列名唯一,RabbitMQ会将消息广播至所有绑定队列,实现一对多分发。

    Centos 6.4 安装erlang&rabbitmq的方法
    Centos 6.4 安装erlang&rabbitmq的方法

    在开始搭建消息队列服务之前,得先搞定两个核心组件:Erlang 和 RabbitMQ。Erlang 是 RabbitMQ 的运行时环境,所以顺序不能乱——先装 Erlang,再装 RabbitMQ。下面把整个过程拆开来讲,每一步都配了具体的命令,照着走基本不会出错。 1. 安装 Erlang 1.1

    Symfony 将RabbitMQ消息转为数组方法
    Symfony 将RabbitMQ消息转为数组方法

    答案:将Symfony中RabbitMQ消息转为数组需根据消息体格式选择反序列化方式,常见为JSON或PHP序列化;若为JSON,使用json_decode($messageBody,true)转换并校验错误;若为PHP序列化,使用unserialize()但需注意安全风险;其他格式则用对应解析器;若消息封装在对象中,需先提取消息体。

    Python RabbitMQ教程:消息队列入门指南
    Python RabbitMQ教程:消息队列入门指南

    Python操作RabbitMQ的关键在于理解其消息队列流程和工作机制,安装pika库后即可通过简单步骤实现消息发送与接收。首先需安装pika:pipinstallpika,并确保RabbitMQ服务运行;其次,发送消息时需建立连接、打开通道、声明队列并发送消息;接着,接收消息时需监听队列、定义回调函数处理消息,并注意确认机制与连接关闭;此外,实际应用中应关注异常处理、消息持久化、多消费者支持及死信队列等特性以提升系统健壮性。掌握这些步骤和注意事项后,Python结合RabbitMQ的基础操作便能快速上手

    PHP实战:RabbitMQ消息队列详解
    PHP实战:RabbitMQ消息队列详解

    PHP结合RabbitMQ构建异步处理系统需安装RabbitMQ和AMQP扩展1,通过AMQP类连接服务器2,声明交换机和队列并绑定路由键3,使用publish方法发布消息4,利用consume消费消息并调用ack确认5,为避免消息丢失应启用持久化、发布者确认或事务机制6,可通过RabbitMQManagementPlugin、命令行工具或Prometheus+Grafana监控性能7,配置死信队列处理无法消费的消息8,保证消息顺序可通过单消费者、单一队列或分组排序等策略实现9。

    springBoot项目常用目录有哪些
    springBoot项目常用目录有哪些

    springBoot项目常用目录springBoot项目的目录结构及名规范介绍基于SpringBoot开发时的目录结构及命名规范,通过介绍能够为你解决,在实际项目中如何规划目录结构?如何命名目录更规范?各个目录分别代表什么含义?等三个问题。目录说明servicex//项目名|-admin-ui//管理服务前端代码(一般将UI和SERVICE放到一个工程中,便于管理)|-servicex-auth//模块1|-servicex-common//模块2|-servicex-gateway//模块3|-serv

    学习如何安装、配置、部署和使用宝塔面板中的RabbitMQ可视化工具
    学习如何安装、配置、部署和使用宝塔面板中的RabbitMQ可视化工具

    RabbitMQ是一款开源的消息代理和队列服务器,旨在通过通用协议实现不同应用之间的数据共享,实现跨平台和跨语言的通信。该系统采用Erlang语言编写,并基于AMQP协议。其最显著的特点之一是在提供高度解耦的服务之间无需确保提供方的存在。接下来介绍关于如何在宝塔面板上可视化安装、配置、部署、使用RabbitMQ。一、RabbitMQ的特点1.可靠性RabbitMQ通过诸如持久化、传输确认和发布确认等机制来确保消息的可靠性。2.灵活的路由消息在进入队列之前通过交换器进行路由,可按照特定规则进行灵活分发。3.

    PHP开发中如何使用RabbitMQ实现消息传递
    PHP开发中如何使用RabbitMQ实现消息传递

    RabbitMQ是一种消息队列软件,可用于在应用程序之间进行消息传递。在PHP开发中,使用RabbitMQ可以实现异步处理任务、实现分布式系统等。本篇文章将介绍如何在PHP开发中使用RabbitMQ实现消息传递。一、安装RabbitMQ服务RabbitMQ是开源软件,可从其官网(https://www.rabbitmq.com/download.html)下

    PHP与RabbitMQ结合实现消息队列处理和分发的方法
    PHP与RabbitMQ结合实现消息队列处理和分发的方法

    随着互联网业务的不断发展,系统间的数据交换变得越来越频繁。在传统的请求响应式架构中,数据传递的方式往往是同步的,即等待请求响应结果后才能进行下一步操作,当数据量较大或者请求响应时间较长时,这种方式往往会导致系统性能下降。此时,消息队列就成为一种比较理想的解决方案,可以实现异步、解耦、扩展性好等优点。RabbitMQ作为一款消息队列中间件,提供了丰富的API,

    比较RabbitMQ和Kafka:如何选择高效的消息中间件
    比较RabbitMQ和Kafka:如何选择高效的消息中间件

    RabbitMQ和Kafka的比较:选择高效的消息中间件简介消息中间件是一种软件,它允许应用程序通过异步消息传递进行通信。消息中间件可以用于各种目的,包括:解耦应用程序:消息中间件可以将应用程序解耦,使它们能够独立于彼此开发和部署。提高可伸缩性:消息中间件可以帮助应用程序提高可伸缩性,使它们能够处理更多的并发请求。提高可靠性:消息中间件可以帮助应用程序提高可

    查看更多
    精品专题 更多
    装机必备
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows
    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程
    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    Mac软件 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    Aperty macOS版
    Aperty macOS版
    macOS

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    WINDOWS 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    PixTV 网页版
    PixTV 网页版
    Windows

    PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。