概述

  • RabbitMQ是一个开源的消息代理和队列服务器,用来通过普通协议在完全不同的应用之间共享数据,或者简单地将作业队列以便让分布式服务器进行处理。

  • 它现实了AMQP协议,并且遵循Mozilla Public License开源协议,它支持多种语言,可以方便的和spring集成。

  • 消息队列使用消息将应用程序连接起来,这些消息通过像RabbitMQ这样的消息代理服务器在应用程序之间路由。

基本概念

  • Broker

    用来处理数据的消息队列服务器实体

  • vhost

    由RabbitMQ服务器创建的虚拟消息主机,拥有自己的权限机制,一个broker里可以开设多个vhost,用于不同用户的权限隔离,vhost之间是也完全隔离的。

  • productor

    产生用于消息通信的数据

  • channel

    消息通道,在AMQP中可以建立多个channel,每个channel代表一个会话任务。

  • exchange

    1. direct

      转发消息到routing-key指定的队列

    2. fanout

      转发消息到所有绑定的队列,类似于一种广播发送的方式。

    3. topic

      按照规则转发消息,这种规则多为模式匹配,也显得更加灵活

  • queue

    1. 队列是RabbitMQ的内部对象,存储消息
    2. 以动态的增加消费者,队列将接受到的消息以轮询(round-robin)的方式均匀的分配给多个消费者。
  • binding

    表示交换机和队列之间的关系,在进行绑定时,带有一个额外的参数binding-key,来和routing-key相匹配。

  • consumer

    监听消息队列来进行消息数据的读取

springboot下三种Exchange模式(fanout,direct,topic)实现

pom.xml中引用spring-boot-starter-amqp

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

增加rabbitmq配置

spring:
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest

direct

direct模式一般情况下只需要定义queue 使用自带交换机(defaultExchange)无需绑定交换机

    @Configuration
public class RabbitP2PConfigure { public static final String QUEUE_NAME = "p2p-queue"; @Bean
public Queue queue() {
return new Queue(QUEUE_NAME, true);
} }
@RunWith(SpringRunner.class)
@SpringBootTest(classes = BootCoreTestApplication.class)
@Slf4j
public class RabbitTest { @Autowired
private AmqpTemplate amqpTemplate; /**
* 发送
*/
@Test
public void sendLazy() throws InterruptedException {
City city = new City(234556666L, "direct_name", "direct_code");
amqpTemplate.convertAndSend(RabbitLazyConfigure.QUEUE_NAME, city);
} /**
* 领取
*/
@Test
public void receive() throws InterruptedException {
Object obj = amqpTemplate.receiveAndConvert(RabbitLazyConfigure.QUEUE_NAME);
Assert.notNull(obj, "");
log.debug(obj.toString());
}
}

适用场景:点对点

fanout

fanout则模式需要将多个queue绑定在同一个交换机上

@Configuration
public class RabbitFanoutConfigure { public static final String EXCHANGE_NAME = "fanout-exchange"; public static final String FANOUT_A = "fanout.A";
public static final String FANOUT_B = "fanout.B";
public static final String FANOUT_C = "fanout.C"; @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
public FanoutExchange fanoutExchange() {
return new FanoutExchange(EXCHANGE_NAME);
} @Bean
public Binding bindingExchangeA(Queue AMessage, FanoutExchange fanoutExchange) {
return BindingBuilder.bind(AMessage).to(fanoutExchange);
} @Bean
public Binding bindingExchangeB(Queue BMessage, FanoutExchange fanoutExchange) {
return BindingBuilder.bind(BMessage).to(fanoutExchange);
} @Bean
public Binding bindingExchangeC(Queue CMessage, FanoutExchange fanoutExchange) {
return BindingBuilder.bind(CMessage).to(fanoutExchange);
} }

发送者

@Slf4j
public class Sender { @Autowired
private AmqpTemplate rabbitTemplate; public void sendFanout(Object message) {
log.debug("begin send fanout message<" + message + ">");
rabbitTemplate.convertAndSend(RabbitFanoutConfigure.EXCHANGE_NAME, "", message);
} }

我们可以通过@RabbitListener监听多个queue来进行消费

@Slf4j
@RabbitListener(queues = {
RabbitFanoutConfigure.FANOUT_A,
RabbitFanoutConfigure.FANOUT_B,
RabbitFanoutConfigure.FANOUT_C
})
public class Receiver { @RabbitHandler
public void receiveMessage(String message) {
log.debug("Received <" + message + ">");
}
}

适用场景

- 大规模多用户在线(MMO)游戏可以使用它来处理排行榜更新等全局事件
- 体育新闻网站可以用它来近乎实时地将比分更新分发给移动客户端
- 分发系统使用它来广播各种状态和配置更新
- 在群聊的时候,它被用来分发消息给参与群聊的用户

topic

这种模式较为复杂,简单来说,就是每个队列都有其关心的主题,所有的消息都带有一个“标题”,Exchange会将消息转发到所有关注主题能与RouteKey模糊匹配的队列。

在进行绑定时,要提供一个该队列关心的主题,如“topic.# (“#”表示0个或若干个关键字,“*”表示一个关键字。 )

@Configuration
public class RabbitTopicConfigure { public static final String EXCHANGE_NAME = "topic-exchange"; public static final String TOPIC = "topic";
public static final String TOPIC_A = "topic.A";
public static final String TOPIC_B = "topic.B"; @Bean
public Queue queueTopic() {
return new Queue(RabbitTopicConfigure.TOPIC);
} @Bean
public Queue queueTopicA() {
return new Queue(RabbitTopicConfigure.TOPIC_A);
} @Bean
public Queue queueTopicB() {
return new Queue(RabbitTopicConfigure.TOPIC_B);
} @Bean
public TopicExchange exchange() {
TopicExchange topicExchange = new TopicExchange(EXCHANGE_NAME);
topicExchange.setDelayed(true);
return new TopicExchange(EXCHANGE_NAME);
} @Bean
public Binding bindingExchangeTopic(Queue queueTopic, TopicExchange exchange) {
return BindingBuilder.bind(queueTopic).to(exchange).with(RabbitTopicConfigure.TOPIC);
} @Bean
public Binding bindingExchangeTopics(Queue queueTopicA, TopicExchange exchange) {
return BindingBuilder.bind(queueTopicA).to(exchange).with("topic.#");
}
}

同时去监听三个queue

@Slf4j
@RabbitListener(queues = {
RabbitTopicConfigure.TOPIC,
RabbitTopicConfigure.TOPIC_A,
RabbitTopicConfigure.TOPIC_B
})
public class Receiver { @RabbitHandler
public void receiveMessage(String message) {
log.debug("Received <" + message + ">");
}
}

通过测试我们可以发现

@RunWith(SpringRunner.class)
@SpringBootTest(classes = BootCoreTestApplication.class)
public class RabbitTest { @Autowired
private AmqpTemplate rabbitTemplate; @Test
public void sendAll() {
rabbitTemplate.convertAndSend(RabbitTopicConfigure.EXCHANGE_NAME, "topic.test", "send All");
} @Test
public void sendTopic() {
rabbitTemplate.convertAndSend(RabbitTopicConfigure.EXCHANGE_NAME, RabbitTopicConfigure.TOPIC, "send Topic");
} @Test
public void sendTopicA() {
rabbitTemplate.convertAndSend(RabbitTopicConfigure.EXCHANGE_NAME, RabbitTopicConfigure.TOPIC_A, "send TopicA");
} }

适用场景

- 分发有关于特定地理位置的数据,例如销售点
- 由多个工作者(workers)完成的后台任务,每个工作者负责处理某些特定的任务
- 股票价格更新(以及其他类型的金融数据更新)
- 涉及到分类或者标签的新闻更新(例如,针对特定的运动项目或者队伍)
- 云端的不同种类服务的协调
- 分布式架构/基于系统的软件封装,其中每个构建者仅能处理一个特定的架构或者系统。

延迟队列

  • 延迟消费:

    • 如用户生成订单之后,需要过一段时间校验订单的支付状态,如果订单仍未支付则需要及时地关闭订单。

    • 用户注册成功之后,需要过一段时间比如一周后校验用户的使用情况,如果发现用户活跃度较低,则发送邮件或者短信来提醒用户使用。

  • 延迟重试:

    • 如消费者从队列里消费消息时失败了,但是想要延迟一段时间后自动重试。

    • 如果不使用延迟队列,那么我们只能通过一个轮询扫描程序去完成。这种方案既不优雅,也不方便做成统一的服务便于开发人员使用。但是使用延迟队列的话,我们就可以轻而易举地完成。

设置交换机延迟属性为true

@Configuration
public class RabbitLazyConfigure { public static final String QUEUE_NAME = "lazy-queue-t";
public static final String EXCHANGE_NAME = "lazy-exchange-t"; @Bean
public Queue queue() {
return new Queue(QUEUE_NAME, true);
} @Bean
public DirectExchange defaultExchange() {
DirectExchange directExchange = new DirectExchange(EXCHANGE_NAME, true, false);
directExchange.setDelayed(true);
return directExchange;
} @Bean
public Binding binding() {
return BindingBuilder.bind(queue()).to(defaultExchange()).with(QUEUE_NAME);
} }

发送时设置延迟时间即可

@Slf4j
public class Sender { @Autowired
private AmqpTemplate rabbitTemplate; public void sendLazy(Object msg) {
log.debug("begin send lazy message<" + msg + ">"); rabbitTemplate.convertAndSend(RabbitLazyConfigure.EXCHANGE_NAME,
RabbitLazyConfigure.QUEUE_NAME, msg, message -> {
message.getMessageProperties().setHeader("x-delay", 10000);
return message;
}
);
}
}

结束

各种使用案例请直接查看官方文档

springboot整合rabbitmq的更多相关文章

  1. springboot学习笔记-6 springboot整合RabbitMQ

    一 RabbitMQ的介绍 RabbitMQ是消息中间件的一种,消息中间件即分布式系统中完成消息的发送和接收的基础软件.这些软件有很多,包括ActiveMQ(apache公司的),RocketMQ(阿 ...

  2. 【SpringBoot系列5】SpringBoot整合RabbitMQ

    前言: 因为项目需要用到RabbitMQ,前几天就看了看RabbitMQ的知识,记录下SpringBoot整合RabbitMQ的过程. 给出两个网址: RabbitMQ官方教程:http://www. ...

  3. SpringBoot系列八:SpringBoot整合消息服务(SpringBoot 整合 ActiveMQ、SpringBoot 整合 RabbitMQ、SpringBoot 整合 Kafka)

    声明:本文来源于MLDN培训视频的课堂笔记,写在这里只是为了方便查阅. 1.概念:SpringBoot 整合消息服务 2.具体内容 对于异步消息组件在实际的应用之中会有两类: · JMS:代表作就是 ...

  4. 一篇学习完rabbitmq基础知识,springboot整合rabbitmq

    一   rabbitmq 介绍 MQ全称为Message Queue,即消息队列, RabbitMQ是由erlang语言开发,基于AMQP(Advanced MessageQueue 高级消息队列协议 ...

  5. 【MQ中间件】RabbitMQ -- SpringBoot整合RabbitMQ(3)

    1.前言说明 前面一篇博客中提到了使用原生java代码进行测试RabbitMQ实现多种交换机类型的队列场景.但是在项目中我们一般使用SpringBoot项目,而且RabbitMQ天生对于Spring的 ...

  6. 功能:SpringBoot整合rabbitmq,长篇幅超详细

    SpringBoot整合rabbitMq 一.介绍 消息队列(Message Queue)简称mq,本文将介绍SpringBoot整合rabbitmq的功能使用 队列是一种数据结构,就像排队一样,遵循 ...

  7. springboot整合rabbitmq实现生产者消息确认、死信交换器、未路由到队列的消息

    在上篇文章  springboot 整合 rabbitmq 中,我们实现了springboot 和rabbitmq的简单整合,这篇文章主要是对上篇文章功能的增强,主要完成如下功能. 需求: 生产者在启 ...

  8. Springboot 整合RabbitMq ,用心看完这一篇就够了

    该篇文章内容较多,包括有rabbitMq相关的一些简单理论介绍,provider消息推送实例,consumer消息消费实例,Direct.Topic.Fanout的使用,消息回调.手动确认等. (但是 ...

  9. RabbitMQ入门到进阶(Spring整合RabbitMQ&SpringBoot整合RabbitMQ)

    1.MQ简介 MQ 全称为 Message Queue,是在消息的传输过程中保存消息的容器.多用于分布式系统 之间进行通信. 2.为什么要用 MQ 1.流量消峰 没使用MQ 使用了MQ 2.应用解耦 ...

  10. SpringBoot 整合 RabbitMQ 实现消息可靠传输

    消息的可靠传输是面试必问的问题之一,保证消息的可靠传输主要在生产端开启 comfirm 模式,RabbitMQ 开启持久化,消费端关闭自动 ack 模式. 环境配置 SpringBoot 整合 Rab ...

随机推荐

  1. UWP Popup 弹出

    一:需求 做一个类似于安卓的弹出消息框,如图.当用户点击下载或者选择时,能够从底部弹出一个提示框,用于提示用户. 二:Popup 类 不需要我们自己额外去写一个弹窗类,微软自己有一个Popup 弹窗类 ...

  2. Chrome 62 的大坑:修改密码后始终使用保存的旧密码登录

    最近有用户向我们反馈,修改密码后,怎么也登录不了我们网站,总是提示密码错误.用户确认密码肯定没错,通过用户发给我们的操作截图看,用户修改密码的操作也没问题. 开始我们没能重现出这个问题,我们检查了相关 ...

  3. 在 ASP.NET Core 中使用 SignalR

    https://weblogs.asp.net/ricardoperes/signalr-in-asp-net-core 作者:Ricardo Peres 译者:oopsguy.com 介绍 Sign ...

  4. mongo+mongoose+express

    直接上指令: //*代表自定义名字 //使用数据库 use * //检查当前数据库 db //查询数据库列表 show dbs //查询当前数据库集合 show collections //插入文档自 ...

  5. HBase数据备份及恢复(导入导出)的常用方法

    一.说明 随着HBase在重要的商业系统中应用的大量增加,许多企业需要通过对它们的HBase集群建立健壮的备份和故障恢复机制来保证它们的企业(数据)资产.备份Hbase时的难点是其待备份的数据集可能非 ...

  6. Problem J

    Problem Description 有一楼梯共M级,刚开始时你在第一级,若每次只能跨上一级或二级,要走上第M级,共有多少种走法? Input 输入数据首先包含一个整数N,表示测试实例的个数,然后是 ...

  7. arrow functions 箭头函数

    ES6里新增加的,与普通方法不同的地方 1.this 的对象在定义函数的时候确定了,而不是在使用的时候才决定 2.不可以使用 new  ,也就不能当构造函数 3.this 的值一旦确定无法修改     ...

  8. robotframework自动化系列:新增流程

    刚接手项目的时候,要求所有流程在上线之前必须确保正向操作是正确的:这个时候又有新的模块需要测试,所以引入自动化测试是非常有必要的!通过对比,尝试使用RF进行自动化的回归测试. 测试中最常见的操作就是增 ...

  9. java面试题及答案

    JAVA相关基础知识1.面向对象的特征有哪些方面 1.抽象:抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面.抽象并不打算了解全部问题,而只是选择其中的一部分,暂时 ...

  10. ASP.NET没有魔法——ASP.NET MVC Controller的实例化与执行

    上一章节中对路由的注册和匹配过程进行了介绍,知道了MVC的Http请求最终是交由MvcHandler处理的,而其处理过程就是对Controller的创建.执行和释放. 本章将从以下几点进一步对上面提到 ...