文章目录
二、docker 安装RabbitMQ
//下载 RabbitMQ
docker pull rabbitmq:management
//启动 RabbitMQ 并设置用户名密码
//15672是图形化界面的端口,5672是RabbitMQ真正的端口
docker run -di --name myrabbit -e RABBITMQ_DEFAULT_USER=[userName] -e RABBITMQ_DEFAULT_PASS=[password] -p 15672:15672 -p 5672:5672 -p 25672:25672 -p 61613:61613 -p 1883:1883 rabbitmq:management
服务器开放 15672 端口,访问
进入 RabbitMQ 的可视化界面
三、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
可以在可视化界面中添加角色,同时可以看到,我们启动容器时创建的角色是最高权限的 Administrator
四、AMQP
1.概念
AMQP全称:Advanced Message Queuing Protocol(高级消息队列协议)。是应用层协议的一个开发标准,为面向消息的中间件设计。
2.生产者实现
从简单案例里可以看出生产者实现的基本步骤有:
- 创建连接工程 并配置信息
- 创建连接Connection
- 通过连接获取通道Channel
- 通过通道创建交互机、声明队列、绑定关系、路由key、发送消息、接收消息
- 准备消息内容
- 发送消息给队列queue
- 关闭通道
- 关闭连接
3.消费者实现
- 创建连接工程 并配置信息
- 创建连接Connection
- 通过连接获取通道Channel
- 接收消息
- 关闭通道
- 关闭连接
4.面试题
【面试题】为什么RabbitMQ是基于信道Channel处理而不是Connection?
一个应用有多个线程需要从rabbitmq中消费,或是生产消息,那么必然会建立很多个connection ,也就是多个tcp连接,对操作系统而言,建立和销毁tcp连接是很昂贵的开销,如果遇到使用高峰,性能瓶颈也随之显现,rabbitmq采用类似nio的做法,连接tcp连接复用,不仅可以减少性能开销,同时也便于管理。
每个线程都把持一个信道,所以信道复用了TCP连接。同时rabbitmq可以确保每个线程的私密性,就像拥有独立的连接一样。当每个信道的流量不是很大时,复用单一的connection可以再产生性能瓶颈的情况下有效地节省tcp连接资源,但是当信道本身的流量很大时,这时候多个信道复用一个connection就会产生性能瓶颈,进而是整体的流量被限制了。此时就需要开辟多个connection,将这些信道均摊到这些connection中,至于这些相关调优策略需要根据业务自身的实际情况进行调节。
五、RabbitMQ的核心组成部分
1.核心组成部分
核心概念:
- Server:又称Broker ,接受客户端的连接,实现AMQP实体服务。 安装rabbitmq-server
- Connection:连接,应用程序与Broker的网络连接 TCP/IP/ 三次握手和四次挥手
- Channel:网络信道,几乎所有的操作都在Channel中进行,Channel是进行消息读写的通道,客户端可以建立对各Channel,每个Channel代表一个会话任务。
- Message :消息:服务与应用程序之间传送的数据,由Properties和body组成,Properties可是对消息进行修饰,比如消息的优先级,延迟等高级特性,Body则就是消息体的内容。
- Virtual Host 虚拟地址,用于进行逻辑隔离,最上层的消息路由,一个虚拟主机理由可以有若干个Exhange和Queueu,同一个虚拟主机里面不能有相同名字的Exchange
- Exchange:交换机,接受消息,根据路由键发送消息到绑定的队列。(不具备消息存储的能力)
- Bindings:Exchange和Queue之间的虚拟连接,binding中可以保护多个routing key.
- Routing key:是一个路由规则,虚拟机可以用它来确定如何路由一个特定消息。
- Queue:队列:也成为Message Queue,消息队列,保存消息并将它们转发给消费者。
不存在没有交换机的队列,这个设置交换机为空的队列,实际上是被默认的交换机绑定了。
2.RabbitMQ的运行流程
java 中的对象在传输时需要序列化
六、消息确认机制(ACK)
消息在被消费者接收后,RabbitMQ 会将队列中的消息删除。RabbitMQ 怎么知道消息被接收了?
ACK机制:当消费者接收到消息后,会像RabbitMQ 发送回执 ACK,告知消息已经被接收。
不过这种回执ACK 分两种情况:
- 自动ACK:消息一旦被接收,消费者自动发送ACK
- 手动ACK:消息接收后,不会发送ACK,需要手动调用
修改第二个参数即可修改ACK机制。
/**
* 参数明细:
* 1、queue 队列名称
* 2、autoAck 自动回复,当消费者接收到消息后要告诉mq消息已接收,如果将此参数设置为true表示会自动回复mq,如果设置为false要通过编程实现回复
* 3、callback,消费方法,当消费者接收到消息要执行的方法
*/
channel.basicConsume(QUEUE_NAME, true, consumer);
手动ACK:
channel.basicAck(envelope.getDeliveryTag(),false);//手动返回ack 一般在finally中
在低版本的 RabbitMQ 中,消费端即使爆出异常,消息没有被接收到但是会被消费。但是在 RabbitMQ 3.10.7 中已实测没有此 BUG。