//下载 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 的可视化界面

五种角色:
可以在可视化界面中添加角色,同时可以看到,我们启动容器时创建的角色是最高权限的 Administrator

AMQP全称:Advanced Message Queuing Protocol(高级消息队列协议)。是应用层协议的一个开发标准,为面向消息的中间件设计。
从简单案例里可以看出生产者实现的基本步骤有:


【面试题】为什么RabbitMQ是基于信道Channel处理而不是Connection?
一个应用有多个线程需要从rabbitmq中消费,或是生产消息,那么必然会建立很多个connection ,也就是多个tcp连接,对操作系统而言,建立和销毁tcp连接是很昂贵的开销,如果遇到使用高峰,性能瓶颈也随之显现,rabbitmq采用类似nio的做法,连接tcp连接复用,不仅可以减少性能开销,同时也便于管理。
每个线程都把持一个信道,所以信道复用了TCP连接。同时rabbitmq可以确保每个线程的私密性,就像拥有独立的连接一样。当每个信道的流量不是很大时,复用单一的connection可以再产生性能瓶颈的情况下有效地节省tcp连接资源,但是当信道本身的流量很大时,这时候多个信道复用一个connection就会产生性能瓶颈,进而是整体的流量被限制了。此时就需要开辟多个connection,将这些信道均摊到这些connection中,至于这些相关调优策略需要根据业务自身的实际情况进行调节。

核心概念:

不存在没有交换机的队列,这个设置交换机为空的队列,实际上是被默认的交换机绑定了。


java 中的对象在传输时需要序列化

消息在被消费者接收后,RabbitMQ 会将队列中的消息删除。RabbitMQ 怎么知道消息被接收了?
ACK机制:当消费者接收到消息后,会像RabbitMQ 发送回执 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。