RabbitMQ

目录

[1. MQ 是什么](#1. MQ 是什么)

[2. RabbitMQ 核心概念](#2. RabbitMQ 核心概念)

[2.1 Producer和Consumer](#2.1 Producer和Consumer)

[2.2 Connection和Channel](#2.2 Connection和Channel)

[2.3 Virtual host](#2.3 Virtual host)

[2.4 Queue](#2.4 Queue)

[2.5 Exchange](#2.5 Exchange)

[2.6 RabbitMQ工作流程](#2.6 RabbitMQ工作流程)

[3. AMQP](#3. AMQP)

[4. Web 界面操作](#4. Web 界面操作)

[4.1 用户相关操作](#4.1 用户相关操作)

[4.2 虚拟机相关操作](#4.2 虚拟机相关操作)

[​5. RabbitMQ入门](#5. RabbitMQ入门)

[5.1 引入依赖](#5.1 引入依赖)

[5.2 编写生产者代码](#5.2 编写生产者代码)

[5.3 编写消费者代码](#5.3 编写消费者代码)


1. MQ 是什么

MQ(Message queue)本质上是个队列,先进先出,只不过队列里面的内容是消息,而消息非常简单,比如可以是文本字符串,JSON 等,也可以很复杂,例如内嵌对象,MQ 多用于分布式系统之间进行通信,系统之间的调用通常由两种方式

1)同步通信

直接调用对方服务,数据从一端发出后立刻就能达到另一端

2)异步通信

数据从一端发出后,先进入一个容器进行临时存储,当达到某种条件后,再由这个容器发送给另一端,容器的一个具体实现就是 MQ

MQ 的作用

1)异步解耦

在业务流程中,一些操作可能非常耗时,但并不需要即时返回结果,可能借助 MQ 把这些操作异步化,比如用户注册后发送短信或邮件通知,可以作为异步任务处理,而不必等待这些操作完成后才告知用户注册成功

2)流量削峰

在访问量剧增的情况下,应用仍然需要继续发挥作用,但这样的突发流量并不常见,使用 MQ 能够使关键组件支撑突发访问压力,不会因为突发流量而崩溃,例如秒杀活动,可以使用 MQ 来控制流量,将请求排队,然后系统根据自己的处理能力逐步处理这些请求

3)消息分发

当多个系统需要对同⼀数据做出响应时,可以使用 MQ 进行消息分发,比如支付成功后,⽀

付系统可以向 MQ 发送消息,其他系统订阅该消息,而无需轮询数据库

4)延时通知

在需要特定实践后发送通知的场景,可以使用 MQ 的延迟消息功能,例如下单后未支付,可以使用延迟队列在超时后自动取消订单

2. RabbitMQ 核心概念

在 rabbitmq 的界面上有 6 部分导航栏,下面介绍这 6 部分

RabbitMQ 是一个消息中间件,也是一个生产者消费者模型,它负责接收,存储并转发消息

2.1 Producer和Consumer

Producer:生产者,是 RabbitMQ Server 的客户端,向 RabbitMQ 发送消息

生产者创建消息,发布到 RabbitMQ 中,在实习应用中,消息通常是一个带有一定业务逻辑结构的数据,消息可以带有一定的标签,RabbitMQ 会根据标签进行路由,把消息发送给感兴趣的消费者

Consumer:消费者,也是 RabbitMQ Server 的客户端,从 RabbitMQ 中接收消息

消费者连接到 RabbitMQ 服务器,就可以消费消息,标签会被丢掉,消费者只会收到消息,并不知道消息的生产者是谁

Broker:就是 RabbitMQ Server,主要是接收和收发消息

对于 RabbitMQ 来说,一个 RabbitMQ Broker 可以简单地看作一个 RabbitMQ 服务器节点,或者 RabbitMQ 服务实例

2.2 Connection和Channel

Connection:连接,是客户端和 RabbitMQ 服务器之间的一个 TCP 连接,这个连接是建立消息传递基础,它负责传输客户端和服务器之间的所有数据和控制信息

Channel:通信,信道,Channel是在 Connection 之上的一个抽象层,在 RabbitMQ 中,一个 TCP 连接可以有多个 Channel,每个 Channel 都是独立的虚拟连接,消息的发送和接收都是基于 Channel 的

2.3 Virtual host

Virtual host:虚拟主机,它为消息队列提供了一种逻辑上的隔离机制,对于 RabbitMQ 而言,一个BrokerServer 上可以存在多个 Virtual host,当多个不同用户使用同一个 RabbitMQ Server 提供的服务时,可以虚拟划分出多个 vhost,每个用户在自己的 vhost 创建 exchange / queue 等

2.4 Queue

Queue:队列,是 RabbitMQ 的内部对象,用于存储消息

多个消费者,可以同时订阅同一个队列

2.5 Exchange

Exchange:交换机,message 到达 broker 的第一站,它负责接收生产者发送的消息,并根据特定的规则把这些消息路由到一个或者多个 Queue 中

2.6 RabbitMQ工作流程

1) Producer 生产了一条消息

2)Producer 连接到了 RabbitMQBroker,建立一个连接(Connection),开启了一个信道(Channel)

3)Producer 声明了一个交换机(Exchange),路由消息

4)Producer 声明了一个队列(Queue),存放信息

5)Producer 发送消息到 RabbitMQBroker

6)RabbitMQBroker 接收消息,并存入响应的队列中,如果没有找到对应的队列,则根据生产者的配置,选择丢弃或者退回给生产者

3. AMQP

AMQP 是一种高级消息队列协议,AMQP 定义了一套确定的消息交换功能,包括交换机,队列等,这些组件共同工作,使得生产者能够将消息发送到交换机,然后由队列接收并等待消费者接收

RabbitMQ 是遵从 AMQP 协议的,RabbitMQ 就是 AMQP 协议的 Erlang 的实现,AMQP 的模型结构和 RabbitMQ 的模型结构是一样的

4. Web 界面操作

4.1 用户相关操作

添加用户

1)点击 Admin --- Add user

2)设置账号密码及权限

3)观察是否添加成功

用户相关操作

1)在用户详情页面,进行更新或删除操作

设置对虚拟机的操作权限

更新 / 删除用户

退出当前用户

4.2 虚拟机相关操作

创建虚拟机

在 Admin 标签页下,点击右侧 Virtual Hosts --- Add a new virtual host,设置虚拟机的名称

5. RabbitMQ入门

5.1 引入依赖

<dependency>

<groupId>com.rabbitmq</groupId>

<artifactId>amqp-client</artifactId>

<version>5.20.0</version>

</dependency>

5.2 编写生产者代码

建立连接

1)IP

2)端口号

3)账号

4)密码

5)虚拟主机

java 复制代码
public class Producer {
    public static void main(String[] args) throws IOException, TimeoutException {
        //1. 建立连接
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("44.34.51.65");
        connectionFactory.setPort(5672);//需要提前开放端口号
        connectionFactory.setUsername("lk");//账号
        connectionFactory.setPassword("lk");//密码
        connectionFactory.setVirtualHost("study");//虚拟主机
        Connection connection = connectionFactory.newConnection();
        //2. 开启信道
        Channel channel = connection.createChannel();
        //3. 声明交换机  使用内置的交换机
        //4. 声明队列
        /**
         *      参数说明:
         *      queue:队列名称
         *      durable:可持久化
         *      exclusive:是否独占
         *      autoDelete:是否自动删除
         *      arguments:参数
         *
         */
        channel.queueDeclare("hello",true,false,false,null);
        //5. 发送消息
        /**
         *      参数说明:
         *      exchange:交换机名称
         *      routingKey:内置交换机,routingKey 和 队列名称保持一致
         *      props:属性配置
         *      body:消息
         */
        String msg = "hello rabbitmq";
        channel.basicPublish("","hello",null,msg.getBytes());
        System.out.println("消息发送成功");
        //6. 释放资源
        channel.close();
        connection.close();
    }
}

执行生产者代码,观察结果

5.3 编写消费者代码

1)创建连接

2)创建 Channel

3)声明队列

4)消费消息

java 复制代码
public class Consumer {
    public static void main(String[] args) throws IOException, TimeoutException {
        //1. 创建连接
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("44.34.51.65");
        connectionFactory.setPort(5672);
        connectionFactory.setUsername("lk");
        connectionFactory.setPassword("lk");
        connectionFactory.setVirtualHost("study");
        Connection connection = connectionFactory.newConnection();
        //2. 创建 Channel
        Channel channel = connection.createChannel();
        //3. 声明队列(可以省略)
        channel.queueDeclare("hello",true,false,false,null);
        //4. 消费消息
        /**
         *      参数说明:
         *      queue:队列名称
         *      autoAck:是否自动确认
         *      callback:接收到消息后,执行的逻辑
         */
        DefaultConsumer consumer = new DefaultConsumer(channel) {
            //从队列中收到消息就会执行的方法
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                String s = new String(body);
                System.out.println("接收到的消息:" + s);
            }
        };
        channel.basicConsume("hello",true,consumer);
        //5. 释放资源
        channel.close();
        connection.close();
    }
}

执行消费者代码,观察结果

其中,消费者代码和生产者前 3 步都是一样的

basicConsume:消费当前队列

Consumer

Consumer 用于定义消费消费者的行为,当需要从 RabbitMQ 中接收消息时,需要提供一个实现了Consumer 接口对象

DefaultConsumer 是 RabbitMQ 提供的一个默认消费者,实现了 Consumer 接口

核心方法:

handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body):从队列中接收到消息时,会自动调用该方法,在这个方法中,可以定义如何处理接收到的消息,打印消息等

参数说明:

consumerTag:消费者标签,通常时消费者在丁页队列时指定的

envelope:包含消息的封包信息,如队列名称,交换机等

properties:一些配置信息

body:消息的具体内容

实际上消费者相当于时一个监听程序,所以不需要关闭资源

相关推荐
XiaoLeisj40 分钟前
【JavaEE初阶 — 多线程】单例模式 & 指令重排序问题
java·开发语言·java-ee
paopaokaka_luck41 分钟前
【360】基于springboot的志愿服务管理系统
java·spring boot·后端·spring·毕业设计
dayouziei41 分钟前
java的类加载机制的学习
java·学习
Yaml43 小时前
Spring Boot 与 Vue 共筑二手书籍交易卓越平台
java·spring boot·后端·mysql·spring·vue·二手书籍
P.H. Infinity3 小时前
【RabbitMQ】03-交换机
分布式·rabbitmq
小小小妮子~3 小时前
Spring Boot详解:从入门到精通
java·spring boot·后端
hong1616883 小时前
Spring Boot中实现多数据源连接和切换的方案
java·spring boot·后端
aloha_7893 小时前
从零记录搭建一个干净的mybatis环境
java·笔记·spring·spring cloud·maven·mybatis·springboot
记录成长java4 小时前
ServletContext,Cookie,HttpSession的使用
java·开发语言·servlet
睡觉谁叫~~~4 小时前
一文解秘Rust如何与Java互操作
java·开发语言·后端·rust