实现了高级队列协议(AMQP),erlang语言编写,通过队列通信,无需专用连接保持链接
1.运用:
数据传输
非阻塞操作,异步执行
推送通知
发布/订阅机制
工作队列
好处:应用解耦,异步处理,消息分发,流量削峰,监控
2.特性
可靠性,通过数据持久化,传输ack获取信息确认,传输确认,发布确认
可集群,多个RabbitMQ服务器形成集群,组成逻辑broker
灵活路由,进入消息队列前,使用Exchange路有消息,提供了多种路由,也可以将多个Exchange绑在一起,也可以实现自己的路由
高可用,在集群机器上进行镜像,部分节点出问题仍可用
多协议,支持多种协议,如STOMP、MQTT等
多语言,支持多种语言的客户端
管理界面
跟踪机制,提供了消息跟踪机制
插件机制,提供许多插件,也可以自己编写
3.基本概念
Message,消息,由消息体和消息头组成,消息体不透明,消息头由可选属性组成:routing-key路由键,priority优先级,delivery-mode是否持久化
publisher,消息生产者
exchange,路由器,接受生产者的消息发送给服务器的消息队列
routing key,路邮键,根据此关键字进行投递
binding,绑定消息队列与路由器,基于路邮键将消息队列与路由器绑定起来
queue,消息队列,一个消息可投入一个或者多个队列,基于虚拟机,每个虚拟机都有独立的
connection,网络连接
consumer,消费者
virtual host,虚拟主机,具有相同的身份认证和加密环境的独立服务器域,迷你版RabbitMQ
broker,消息队列在物理机上的实体,保障了从生产者到消费者的路线
4.confirm机制
保障了服务消息已经被路由正确的加入队列,加入正确队列后会返回给服务器一个confirm(包含消息ID),如果开启持久化,则持久化完成之后才会confirm
5.事务
txSelect()开启事务,txCommit()提交事务,txRollback()回滚事务
6.消息恢复
消费者从queue取到消息后会返回ack,服务端则将其标记并且回收,如果一条持久化的消息没有被消费者取走,则重建exchange与queue
7.持久化
设置delivery-mode=2,同时echange和queue(durable=true)也需要持久化
8.消息状态
ready,等待消息被消费 unacked等待被确认,如果没有确认则重新进入ready
9.三种模式:
单机模式
普通集群模式:多个机器启用rabbitMQ实例,但是queue只会放在其中一个实例中,其他的都同步这个(一主多从)
镜像集群模式:queue存在于多个实例,每次写消息到queue,自动同步到多个queue
10.Exchange三种类型
direct、fanout、topic、headers 。headers 匹配 AMQP 消息的 header 而不是路由键,此外 headers 交换器和 direct 交换器完全一致,但性能差很多,目前几乎用不到了
direct,根据routing key全词匹配binding key,分发到对应队列
fanout,将消息分发到与路由器绑定的所有队列,类似于广播
topic,通过类型匹配,单词之间用 . 隔开,匹配通识符#和""
11.RPC
在特殊情况下,需要处理同步信息,需要等服务端回执。消息属性( MessageProperties )设置 replyTo (一个 Queue 名称,用于告诉服务器处理完成后将通知我的消息发送到这个 Queue 中)和 correlationId (此次请求的标识号,服务器处理完成后需要将此属性返还,客户端将根据这个id了解哪条请求被成功执行了或执行失败)
服务端回复应答消息到Reply置顶的queue,同时带上 correlationId
12.集群搭建
各节点使用“--link”连接
各节点使用的erlang cookie值必须相同,相当于秘钥功能,用于节点认证
最少包含一个磁盘节点
13.集群中唯一的磁盘节点崩溃了
不能进行以下操作:
不能创建队列
不能创建交换器
不能创建绑定
不能添加用户
不能更改权限
不能添加和删除集群节点
集群停止顺序,先关闭内存节点,最后关闭磁盘节点
14.Spring简单实现
@Configuration
public class RabbitmqConfig {
//创建一个立即消费队列
@Bean
public Queue immediateQueue(){
// 第一个参数是创建的queue的名字,第二个参数是是否支持持久化
return new Queue("immediate_queue_test1", true);
}
@Bean
public DirectExchange immediateExchange() {
// 一共有三种构造方法,可以只传exchange的名字, 第二种,可以传exchange名字,是否支持持久化,是否可以自动删除,
//第三种在第二种参数上可以增加Map,Map中可以存放自定义exchange中的参数
return new DirectExchange("immediate_exchange_test1", true, false);
}
@Bean
//把立即消费的队列和立即消费的exchange绑定在一起
public Binding immediateBinding() {
return BindingBuilder.bind(immediateQueue()).to(immediateExchange()).with("immediate_routing_key_test1");
}
}
@Component
public class Sender {
@Autowired
RabbitTemplate rabbitTemplate;
public void send() {
String message = "message" + new Date();
System.out.println("Sender " + message);
rabbitTemplate.convertAndSend("immediate_exchange_test1", "immediate_routing_key_test1", message);
}
}
@Component
public class Receiver {
@RabbitHandler
@RabbitListener(queues = "immediate_queue_test1")
public void immediateProcess(String message) {
System.out.println("Receiver" + message);
}
}