Spring Boot项目集成RabbitMQ实战以及坑点讲解(2)
Spring

RabbitMQ 是一个非常强大和灵活的消息中间件,它可以应用于多种场景和需求。
以下是一些常见的 RabbitMQ 应用场景和实战经验:
- 异步处理:当系统需要执行一些耗时或者不重要的任务时,可以使用 RabbitMQ 将任务封装成消息发送到队列中,然后由专门的消费者来异步地执行这些任务。这样可以提高系统的响应速度和用户体验,同时也可以避免因为任务失败或超时而影响主流程的执行。例如在 waynboot-mall 项目中,用户下单后需要发送邮件通知,这个任务就可以使用 RabbitMQ 异步处理。
- 流量削峰:当系统面临突发的高并发请求时,如果直接让所有请求打到后端服务器上,可能会导致服务器崩溃或者响应缓慢。这时可以使用 RabbitMQ 作为一个缓冲层,将请求先发送到队列中,然后由后端服务器按照自己的处理能力从队列中拉取请求进行处理。这样可以平滑地分摊请求压力,避免系统崩溃或者服务降级。例如,在 waynboot-mall 项目中,每天晚上八点有秒杀活动,这时可以使用 RabbitMQ 来削峰限流,保证系统的稳定运行。
- 消息广播:当系统需要将消息发送到多个接收方时,可以使用 RabbitMQ 的发布/订阅模式,将消息发送到一个 fanout 类型的交换器上,然后由多个队列绑定到这个交换器上,从而实现消息的广播功能。这样可以实现一对多的消息通信,同时也可以根据不同的业务需求,订阅不同的消息内容。例如,在 waynboot-mall 项目中,当商品信息发生变化时,需要通知搜索系统、推荐系统、缓存系统等多个系统,这时可以使用 RabbitMQ 的消息广播功能。
- 消息路由:当系统需要根据不同的条件将消息发送到不同的接收方时,可以使用 RabbitMQ 的路由模式,将消息发送到一个 direct 或者 topic 类型的交换器上,然后由多个队列绑定到这个交换器上,并指定不同的路由键或者模式匹配规则,从而实现消息的路由功能。这样可以实现多对多的消息通信,同时也可以灵活地控制消息的分发和消费。例如,在 waynboot-mall 项目中,当订单状态发生变化时,需要通知不同的系统进行不同的处理,这时可以使用 RabbitMQ 的消息路由功能。
坑点解析

在使用 RabbitMQ 的过程中,有一些常见的问题需要注意:
- 消息确认:消息确认是 RabbitMQ 保证消息可靠传递的机制。消息确认分为生产者确认和消费者确认。生产者确认是指生产者发送消息后,等待 RabbitMQ 返回一个确认消息,表明消息已经被正确接收和存储。消费者确认是指消费者接收消息后,向 RabbitMQ 发送一个确认消息,表明消息已经被正确处理和消费。在 waynboot-mall 项目中,消费者开启了手动消息确认。
- 消息持久化:消息持久化是指将消息存储到磁盘上,以防止 RabbitMQ 重启或者崩溃时丢失消息。消息持久化需要满足以下三个条件:交换器、队列和消息都需要设置为持久化。持久化会影响 RabbitMQ 的性能,因为需要进行磁盘 IO 操作。建议根据业务需求选择是否需要持久化消息,并合理地配置磁盘空间和清理策略。在 waynboot-mall 项目中,交换器、队列设置了持久化,消息没有设置持久化(消息设置持久化会对 RabbitMQ 的性能造成较大影响)。
- 死信队列:死信队列是指存储那些因为某些原因无法被正常消费的消息的队列。死信队列可以用来处理一些异常或者失败的情况,如消息过期、队列达到最大长度、消费者拒绝等。建议使用死信队列来监控和处理这些情况,并根据业务需求选择合适的重试或者补偿策略。在 waynboot-mall 项目中,当订单消费者处理消息失败重试三次后,会将订单消息发送到死信队列。
- 集群和镜像:集群和镜像是 RabbitMQ 实现高可用和高扩展的两种方式。集群是指将多个 RabbitMQ 实例组成一个逻辑单元,共享元数据和负载均衡。镜像是指将同一个队列在多个节点上创建副本,实现数据冗余和容错。建议根据业务需求选择合适的集群模式和镜像类型,并注意集群中的网络分区、脑裂等问题。
代码实战
在 waynboot-mall 项目中,消息层包含两个模块 waynboot-message-core 以及 waynboot-message-consumer,目录结构如下,
|-- waynboot-message-core // 核心消息配置,供其他服务集成使用
| |-- config
| |-- constant
| |-- dto
|-- waynboot-message-consumer // 消息消费服务,订阅队列接收消息,调用其他服务执行一些具体的业务逻辑
| |-- api
| |-- config
| |-- consumer
waynboot-message-core 包目录说明如下,
- config:核心消息配置目录,包含业务上使用的订单消息、邮件消息、死信消息、延迟消息的交换机、队列、路由绑定配置以及 RabbitTemplate 配置。
- constants:核心消息配置的相关常量目录,包含 MQ 的常量类,这里面会定义订单、邮件、死信、延迟消息的交换机名称、队列名称、路由键名称等。
- dto:核心消息配置的数据转换实体目录,包含 OrderDTO 等。
waynboot-message-consumer 包目录说明如下,
- api:消息消费服务调用其他服务定义的 api 包目录,包含 MobileApi 类用来调用 moibile-api。
- config:消息消费服务的核心配置目录,包含 RestTemplate 配置类。
- consumer:消息消费服务的消费者包目录,包含下单、发送邮件、未支付订单超时取消等消费者。
添加 POM 依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
<version>${spring-boot.version}</version>
</dependency>
指定虚拟主机

在 waynboot-mall 项目中,通过 yml 文件的 spring.rabbitmq.virtual-host=“/” 属性来指定虚拟主机名称。
建议大家在使用 RabbitMQ 时都配置好自己项目的虚拟主机名称,来达到各系统资源隔离的目的。
当然如果 RabbitMQ 服务只有一个项目在用,那就用默认的 / 作为虚拟主机名称也是可以的。
小知识:出于多租户和安全因素设计的,vhost 把 AMQP 的基本组件划分到一个虚拟的分组中。每个 vhost 本质上就是一个 mini 版的 RabbitMQ 服务器,拥有自己的队列、交换机、绑定和权限机制。当多个不同的用户使用同一个 RabbitMQ 服务器时,可以划分出多个虚拟主机。RabbitMQ 默认的虚拟主机路径是 /。
生产者发送消息
在 waynboot-mall 项目中,用订单消息来举例,生产者发送消息需要经过三个步骤
1. 创建订单消息的交换机、队列以及路由绑定
public class MQConstants {
public static final String ORDER_DIRECT_QUEUE = "order_direct_queue";
public static final String ORDER_DIRECT_EXCHANGE = "order_direct_exchange";
public static final String ORDER_DIRECT_ROUTING = "order_direct_routing";
}
@Configuration
public class BusinessRabbitConfig {
@Bean
public Queue orderDirectQueue() {
return new Queue(MQConstants.ORDER_DIRECT_QUEUE);
}
@Bean
DirectExchange orderDirectExchange() {
return new DirectExchange(MQConstants.ORDER_DIRECT_EXCHANGE);
}
@Bean
Binding bindingOrderDirect() {
return BindingBuilder.bind(orderDirectQueue()).to(orderDirectExchange()).with(MQConstants.ORDER_DIRECT_ROUTING);
}
}
public class MQConstants {
public static final String ORDER_DIRECT_QUEUE = "order_direct_queue";
public static final String ORDER_DIRECT_EXCHANGE = "order_direct_exchange";
public static final String ORDER_DIRECT_ROUTING = "order_direct_routing";
}
@Configuration
public class BusinessRabbitConfig {
@Bean
public Queue orderDirectQueue() {
return new Queue(MQConstants.ORDER_DIRECT_QUEUE);
}
@Bean
DirectExchange orderDirectExchange() {
return new DirectExchange(MQConstants.ORDER_DIRECT_EXCHANGE);
}
@Bean
Binding bindingOrderDirect() {
return BindingBuilder.bind(orderDirectQueue()).to(orderDirectExchange()).with(MQConstants.ORDER_DIRECT_ROUTING);
}
}在 BusinessRabbitConfig 中,我们创建了订单交换机、队列以及路由绑定关系。
在 Spring 项目中,项目启动时,就会自动在 RabbitMQ 服务器上创建好这些东西。
相关阅读
-
服务器查询网站入口在哪 查询网站服务器的办法
小编为你讲解服务器查询网站入口在哪和查询网站服务器的办法的介绍,接下来分享详细内容。 随着科学技术的飞速发展,越来越多的用户接触到服务器,对服务器有了一定的了解。服务器配
-
如何通过 Nebula Exchange 导入数据
小编带来的是及Nebula的相关话题,接下来IT袋网小编为大家介绍。 Nebula Exchange 是一款 Apache Spark 应用,用于在分布式环境中将集群中的数据批量迁移到 Nebula Graph 中,能支持多种不同格式(CS
-
内网ftp服务器搭建教程 简述ftp服务器搭建过程
今天带来的IT技巧小经验内网ftp服务器搭建教程和简述ftp服务器搭建过程的方法内容,接下来一起来看看吧。 1 文件传输协议 一般来讲,人们将计算机联网的首要目的就是获取资料,而文件传
-
香港BGP服务器丢包率高与什么有关? 服务器丢包的原因有哪些
相对于大多数人香港BGP服务器丢包率高与什么有关的内容,接下来一起来看看吧。 当前,BGP线的香港机房比较普及,假设用户所在机房不是BGP机房,而是联通或电信等其他机房,这时当用户通


