RabbitMQ的用户详解以及maven导入
一.RabbitMQ的角色分类
1:none:
- 不能访问management plugin
2:management:查看自己相关节点信息
- 列出自己可以通过AMQP登入的虚拟机
- 查看自己的虚拟机节点 virtual hosts的queues,exchanges和bindings信息
- 查看和关闭自己的channels和connections
- 查看有关自己的虚拟机节点virtual hosts的统计信息。包括其他用户在这个节点virtual hosts中的活动信息。
3:Policymaker
- 包含management所有权限
- 查看和创建和删除自己的virtual hosts所属的policies和parameters信息。
4:Monitoring
- 包含management所有权限
- 罗列出所有的virtual hosts,包括不能登录的virtual hosts。
- 查看其他用户的connections和channels信息
- 查看节点级别的数据如clustering和memory使用情况
- 查看所有的virtual hosts的全局统计信息。
5:Administrator
- 最高权限
- 可以创建和删除virtual hosts
- 可以查看,创建和删除users
- 查看创建permisssions
- 关闭所有用户的connections
二.RabbitMQ入门案例 - Simple 简单模式
环境需要
1:jdk1.8
2:构建一个maven工程
3:导入rabbitmq的maven依赖
4:启动rabbitmq-server服务
5:定义生产者
6:定义消费者
7:观察消息的在rabbitmq-server服务中的过程
简单模式
在 RabbitMQ 中,Simple 模式(也称为简单模式或直接模式)是最基础的消息传递模式之一。它适用于一对一的消息传递场景,即一个生产者发送消息到队列,一个消费者从队列中接收并处理消息。生产者 (Producer):
生产者负责创建消息,并将消息发送到指定的队列。它不关心谁会消费这些消息,只是将消息推送到队列中。队列 (Queue):
队列是 RabbitMQ 中的核心组件,用于存储消息。在 Simple 模式下,通常只有一个队列,所有的消息都会被发送到这个队列中。消费者 (Consumer):
消费者从队列中拉取消息并进行处理。在 Simple 模式下,通常只有一个消费者,所有消息都会被这个消费者逐一处理。消息 (Message):
消息是由生产者生成的内容,可以是文本、JSON 数据、二进制数据等。消息会被发送到队列中,等待消费者消费。

简单入门案例
在Idea中新建一个maven项目

导入相关的依赖:Java原生依赖
<!-- https://mvnrepository.com/artifact/com.rabbitmq/amqp-client --> <dependency> <groupId>com.rabbitmq</groupId> <artifactId>amqp-client</artifactId> <version>5.25.0</version> </dependency>
rabbitmq和spring同属一个公司开放的产品,所以他们的支持也是非常完善,这也是为什么推荐使用rabbitmq的一个原因。
启动RabbitMQ服务:
systemctl start rabbitmq-server

定义生产者:也就是产生消息的对象,需要把生成的消息交给RabbitMQ的队列中
import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import com.rabbitmq.client.ConnectionFactory; public class Producer { public static void main(String[] args) { //创建连接工厂 ConnectionFactory factory = new ConnectionFactory(); //设置连接参数 factory.setHost("8.137.76.12"); factory.setPort(5672); factory.setVirtualHost("/"); factory.setUsername("admin"); factory.setPassword("admin"); //声明连接和通道 Connection connection = null; Channel channel = null; try { //创建连接 connection = factory.newConnection("生产者"); //创建通道 channel = connection.createChannel(); //声明队列 // 5: 申明队列queue存储消息 /* * 如果队列不存在,则会创建 * Rabbitmq不允许创建两个相同的队列名称,否则会报错。 * * @params1: queue 队列的名称 * @params2: durable 队列是否持久化 * @params3: exclusive 是否排他,即是否私有的,如果为true,会对当前队列加锁,其他的通道不能访问,并且连接自动关闭 * @params4: autoDelete 是否自动删除,当最后一个消费者断开连接之后是否自动删除消息。 * @params5: arguments 可以设置队列附加参数,设置队列的有效期,消息的最大长度,队列的消息生命周期等等。 * */ channel.queueDeclare("queue1",false,false,false,null); //发送消息 // 7: 发送消息给中间件rabbitmq-server // @params1: 交换机exchange // @params2: 队列名称/routing // @params3: 属性配置 // @params4: 发送消息的内容 channel.basicPublish("","queue1",null,"hello,i am ok".getBytes()); System.out.println("信息发送成功"); }catch (Exception e){ e.printStackTrace(); System.out.println("发送消息异常"); }finally { //关闭连接--通道 if (channel !=null && channel.isOpen()){ try { channel.close(); }catch (Exception e){ System.out.println("关闭通道异常"); } } //关闭连接 if (connection != null){ try { connection.close(); }catch (Exception e){ System.out.println("关闭连接失败"); } } } } }
执行发送之后,可以使用RabbitMQ的web管理查看通道是否接收到消息:

定义消费者从通道中拿取信息:
import com.rabbitmq.client.*; import java.io.IOException; public class Consumer { public static void main(String[] args) { //创建连接工厂 ConnectionFactory factory = new ConnectionFactory(); //设置连接参数 factory.setHost("8.137.76.12"); factory.setPort(5672); factory.setVirtualHost("/"); factory.setUsername("admin"); factory.setPassword("admin"); //声明连接和通道 Connection connection = null; Channel channel = null; try { //创建连接 connection = factory.newConnection("消费者"); //创建通道 channel = connection.createChannel(); //接收信息 // 监听队列,当有消息到达时,执行回调函数 channel.basicConsume("queue1", true, new DeliverCallback() { // 当有消息到达时,执行回调函数 @Override public void handle(String s, Delivery delivery) throws IOException { // 打印接收到的消息 System.out.println("接收到的消息是:" + new String(delivery.getBody(), "UTF8")); } }, new CancelCallback() { // 当接收失败时,执行回调函数 @Override public void handle(String s) throws IOException { // 打印接收失败的信息 System.out.println("接收失败了"); } }); System.out.println("开始接收消息"); System.in.read(); }catch (Exception e){ e.printStackTrace(); System.out.println("发送消息异常"); }finally { //关闭连接--通道 if (channel !=null && channel.isOpen()){ try { channel.close(); }catch (Exception e){ System.out.println("关闭通道异常"); } } //关闭连接 if (connection != null){ try { connection.close(); }catch (Exception e){ System.out.println("关闭连接失败"); } } } } }
当消息接收之后,我们暂停程序,也就是不释放连接:

我们发现消息队列中就没有消息了
然后释放连接:

没有持久化的队列消失了
三.什么是AMQP
AMQP,全称为高级消息队列协议(Advanced Message Queuing Protocol),是一种开放的、面向消息中间件的线级协议。它由JPMorgan Chase和iMatix公司设计开发,并于2008年首次发布。AMQP旨在提供一种统一的消息传递协议,使得不同的消息中间件产品之间能够实现互操作性。
AMQP的核心概念
- 
Exchange(交换机):接收生产者发送的消息,并根据一定的路由规则将这些消息分发到一个或多个队列中。 
- 
Queue(队列):存储消息的地方,消费者从这里获取并处理消息。 
- 
Binding(绑定):定义了Exchange与Queue之间的关系,即通过何种规则将消息从Exchange路由到特定的Queue。 
- 
Routing Key(路由键):一个虚拟地址,通常是一个简单的字符串,用于Exchange决定如何路由消息。 
- 
Message(消息):应用程序之间需要通过消息代理(如RabbitMQ)进行传递的数据内容。 
AMQP的工作流程
- 生产者(Producer)连接到RabbitMQ服务器,并声明一个交换机(Exchange)。
- 生产者发送消息给交换机,同时指定一个路由键(Routing Key)。
- 交换机根据其类型和绑定规则(Bindings)将消息路由到一个或多个队列(Queue)。
- 消费者(Consumer)监听特定的队列,并处理传入的消息。
生产者:

消费者:

RabbitMQ 使用**管道(Channel)而不是直接基于连接(Connection)
1. 连接(Connection)是重量级的什么是连接?
连接是指客户端与 RabbitMQ 服务器之间的网络连接(通常是 TCP 连接)。每个连接都需要维护一个独立的网络套接字,并且需要经过三次握手建立连接,四次挥手关闭连接。为什么连接是重量级的?
建立和销毁连接的成本较高,尤其是对于高并发场景。每个连接会占用一定的系统资源(如文件描述符、内存等),过多的连接可能导致系统资源耗尽。2. 管道(Channel)是轻量级的
什么是管道?
管道是基于连接的一个虚拟通信通道,允许多个逻辑操作共享同一个物理连接。多个管道可以在同一个连接上并发运行,每个管道可以独立发送和接收消息。为什么管道是轻量级的?
管道的创建和销毁成本非常低,因为它只是在现有连接的基础上分配一些逻辑资源。管道之间相互隔离,允许在一个连接中同时执行多个任务(例如,发布消息、消费消息、声明队列等)。3. 提高资源利用率
如果每个操作都直接使用独立的连接,那么每个连接都需要单独的网络套接字和资源分配。这会导致:系统资源的大量浪费。网络带宽和 CPU 的额外开销。通过引入管道机制,多个操作可以复用同一个连接,从而显著减少资源消耗。4. 支持并发操作
在实际应用中,客户端通常需要同时执行多种操作,例如:发布消息到不同的队列。消费来自不同队列的消息。声明交换机和队列。如果这些操作都必须通过独立的连接完成,就会导致大量的连接被创建,增加了管理复杂性。管道允许多个并发操作在同一连接上运行,从而简化了客户端的设计。

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号