消息队列 MQ 入门

MQ 的概念

MQ 全称 Message Queue(消息队列),是在消息的传输过程中保存消息的容器。用于分布式系统之间进行通信。

MQ 的优势

解耦

系统的耦合性越高,容错性就越低,可维护性就越低。使用 MQ 使得应用间解耦,提升容错性和可维护性。

具体而言

在一个复杂的系统中,不同的模块或服务之间可能需要相互依赖,如果是直接使用函数调用或者 API 调用的方式会造成模块之间的耦合。当一个模块发生改变时,调用方和被调用方的代码要同时修改。而使用消息队列作为中间件,不同的模块就可以将消息发送到消息队列中, 也不需要知道具体的接收方是谁。接收方可以独立的消费消息,实现了模块之间的解耦。

异步

一次请求可能会涉及多个系统的多次服务调用,服务与服务之间响应时间不断叠加,如果使用同步的方式处理,会阻塞主线程或者进程,导致系统性能下降。而使用 MQ 可以将这些操作封装成消息,放入消息队列中,异步地处理这些操作,不影响主流程的执行,提高了系统的性能和响应速度。

削峰填谷

削峰填谷是一种在高并发场景下平衡系统压力的技术,通常用于平衡系统在高峰期和低谷期的资源利用率提高系统的吞吐量和响应速度在削峰填谷的过程中,通常使用消息队列作为缓冲区,将请求放入消息队列中,然后在系统负载低的时候进行处理这种方式可以将系统的峰值压力分散到较长的时间段内减少瞬时压力对系统的影响,从而提高系统的稳定性和可靠性。

MQ 的劣势

使用 MQ 中间件将面临以下两个问题:

  • 系统可用性降低系统引入的外部依赖越多,系统稳定性越差。一旦 MQ 宕机,就会对业务造成影响。如何保证 MQ 的高可用成为了新的挑战。
  • 系统复杂度提高。MQ 的加入大大增加了系统的复杂度,以前系统间是同步的远程调用,现在是通过 MQ 进行异步调用。如何保证消息不被丢失等情况?

RabbitMQ官网:www.rabbitmq.com/

安装RabbitMQ

首先安装了Homebrew,并且确保是最新:

sql 复制代码
brew update

使用一下命令安装 RabbitMQ 服务器:

复制代码
brew rabbitmq

安装路径:

Intel Mac,应该在:/usr/local/opt/rabbitmq/sbin

Apple Mac ,应该在:/opt/homebrew/Cellar/rabbitmq

也可以使用 brew info rabbitmq 命令来查找:

vbnet 复制代码
# liulvhua @ MacBookPro in / [19:04:39] 
$ brew info rabbitmq
==> rabbitmq: stable 3.12.9 (bottled)
Messaging broker
https://www.rabbitmq.com
/opt/homebrew/Cellar/rabbitmq/3.12.9 (1,442 files, 34.4MB) *
  Poured from bottle using the formulae.brew.sh API on 2023-11-19 at 19:03:51
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/r/rabbitmq.rb
License: MPL-2.0
==> Dependencies
Required: erlang ✔
==> Caveats
Management Plugin enabled by default at http://localhost:15672

To start rabbitmq now and restart at login:
  brew services start rabbitmq
Or, if you don't want/need a background service you can just run:
  CONF_ENV_FILE="/opt/homebrew/etc/rabbitmq/rabbitmq-env.conf" /opt/homebrew/opt/rabbitmq/sbin/rabbitmq-server
==> Analytics
install: 6,952 (30 days), 21,352 (90 days), 57,247 (365 days)
install-on-request: 6,949 (30 days), 21,350 (90 days), 57,235 (365 days)
build-error: 0 (30 days)

# liulvhua @ MacBookPro in / [19:35:59]

RabbitMQ 服务器脚本和CLI工具

Intel Mac 位于:/usr/local/Cellar/rabbitmq/{version}/sbin

Apple Mac 位于:/opt/homebrew/Cellar/rabbitmq/{version}/

登录管理端(需先启动):默认账户是(guest/guest)

http://localhost:15672

启动 RabbitMQ Server

前台启动:

ini 复制代码
CONF_ENV_FILE="/opt/homebrew/etc/rabbitmq/rabbitmq-env.conf" /opt/homebrew/opt/rabbitmq/sbin/rabbitmq-server

后台启动:

sql 复制代码
brew services start rabbitmq

停止服务:

arduino 复制代码
brew services stop rabbitmq

或者直接使用 CLI 工具:

arduino 复制代码
/opt/homebrew/sbin/rabbitmqctl shutdown

配置环境变量:

ruby 复制代码
# for macOS Intel
export PATH=$PATH:/usr/local/sbin
# for Apple Silicon
export PATH=$PATH:/opt/homebrew/sbin

社区插件下载安装

www.rabbitmq.com/community-p...

安装rabbitmq_delayed_message_exchange


找到对应的版本 下载:


放到rabbitmq安装路径下的plugins目录下:

使用以下命令启用插件:

bash 复制代码
../sbin/rabbitmq-plugins enable rabbitmq_delayed_message_exchange

enable后面加插件名,复制前缀即可。若rabbitmq未启动,则不会生效,需要在命令后面再加上 --offline。

在 Spring 项目中使用 RabbitMQ

大体分为以下步骤:

  1. 添加RabbitMQ依赖:在pom.xml文件中添加以下Maven依赖项,以引入RabbitMQ的相关库:
xml 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
  1. 配置RabbitMQ连接:在application.properties(或application.yml)文件中添加RabbitMQ的连接配置,包括URL、端口、用户名和密码等信息。例如:
ini 复制代码
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=username
spring.rabbitmq.password=password
  1. 创建消息发送者和接收者:在Spring项目中,可以通过注解来定义消息发送者和接收者。
  • 消息发送者:使用RabbitTemplate类来发送消息。创建一个类,并使用@Component注解标记为组件,然后使用@Autowired注解将RabbitTemplate实例注入到该类中。你可以调用convertAndSend()方法来发送消息,指定交换机名称、路由键和消息内容。例如:
typescript 复制代码
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class MessageSender {

    private RabbitTemplate rabbitTemplate;

    @Autowired
    public MessageSender(RabbitTemplate rabbitTemplate) {
        this.rabbitTemplate = rabbitTemplate;
    }

    public void sendMessage(String exchange, String routingKey, Object message) {
        rabbitTemplate.convertAndSend(exchange, routingKey, message);
    }
}
  • 消息接收者:使用@RabbitListener注解来标记一个方法,该方法将用于处理接收到的消息。创建一个类,并使用@Component注解标记为组件,然后定义一个带有@RabbitListener注解的方法,指定监听的队列名称。例如:
kotlin 复制代码
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
public class MessageReceiver {

    @RabbitListener(queues = "myQueue")
    public void receiveMessage(String message) {
        System.out.println("Received message: " + message);
    }
}
  1. 配置交换机和队列:可以使用RabbitAdmin类来在Spring项目中自动声明交换机和队列。在你的配置类中,使用@Bean注解创建一个RabbitAdmin实例,并为交换机和队列设置属性。例如:
typescript 复制代码
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RabbitMQConfig {

    @Bean
    public Queue myQueue() {
        return new Queue("myQueue");
    }

    @Bean
    public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory) {
        return new RabbitAdmin(connectionFactory);
    }
}

这些是在Spring项目中使用RabbitMQ的基本步骤。实际还应根据实际需求进行进一步的配置和扩展,例如使用交换机和绑定、设置消息确认等功能。

RabbitMQ 的工作模式

RabbitMQ 一共有六种(工作模式消息分发方式)。

官网对应介绍:www.rabbitmq.com/getstarted....

  1. 简单模式(HelloWorld)一个生产者、一个消费者,不需要设置交换机(使用默认的交换机)。
  2. 工作队列模式(Work Queue)一个生产者、多个消费者(竞争关系),不需要设置交换机(使用默认的交换机)。
  3. 发布订阅模式(Publish/Subscribe) 需要设置类型为 fanout 的交换机,并且交换机和队列进行绑定,当发送消息到交换机后,交换机会将消息发送到绑定的队列。
  4. 路由模式(Routing) 需要设置类型为 fanout 的交换机,并且交换机和队列进行绑定,当发送消息到交换机后,交换机会将消息发送到绑定的队列。
  5. 主题模式(Topics) 需要设置类型为 fanout 的交换机,并且交换机和队列进行绑定,当发送消息到交换机后,交换机会将消息发送到绑定的队列。
  6. RPC模式(不太算MQ)
相关推荐
GoGeekBaird9 小时前
我开源了 BeeWeave,给 AI Agent 搭一个越用越懂你的知识创作台
后端·github
犀利豆12 小时前
AI in Harness(四)
人工智能·后端
Hui Baby13 小时前
Spring Security
java·后端·spring
逝水无殇13 小时前
C# 运算符重载详解
开发语言·后端·c#
苏三说技术14 小时前
2026编程圈很火的10个Skills
后端
用户83562907805114 小时前
使用 Python 自动化 Excel 公式和函数:完整指南
后端·python
编程(变成)小辣鸡15 小时前
Spring事务失效场景
java·后端·spring
PinkSun15 小时前
MySQL 建表报 1030,能查不能建,排查 1 小时发现是我自己改了一行权限
后端
无相求码15 小时前
为什么 printf 可以接受任意数量参数?变长参数的底层真相
后端
郡杰15 小时前
Boot:MP|测验|结果封装|异常处理|前后联调|拦截器
后端