消息中间件系列二:RabbitMQ入门(基本概念RabbitMQ的安装和运行)
Posted leesmall
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了消息中间件系列二:RabbitMQ入门(基本概念RabbitMQ的安装和运行)相关的知识,希望对你有一定的参考价值。
一、基本概念
1. AMQP
AMQP,即Advanced Message Queuing Protocol,一个提供统一消息服务的应用层标准高级消息队列协议。支持不同语言和不同的产品
2. 生产者
消息的创建者,发送到AMQP的消息中间件
3. 消费者
连接到AMQP的消息中间件,订阅到队列上,进行消息的消费。分为持续订阅(basicConsumer)和单条订阅(basicGet)
说明:
持续订阅:只要有消息就不断消费
单条订阅:消费过一条消息以后就不再消费了,要想继续消费消息,就得重新订阅到队列上
4. 消息
包括有效载荷和标签。有效载荷就是要传输的数据,标签描述有效载荷的属性,RabbitMQ用标签来决定谁获得当前消息。消费者只能拿到有效载荷。
5. 信道
信道的概念:
虚拟的连接,建立在真实的TCP/IP连接之上的。信道的创建是没有限制的。AMQP所有的消息和命令都是通过信道来传输的。
使用信道的好处:
建立在TCP/IP连接上性能更高,TCP/IP的连接数是有上限的,并且还要频繁的创建连接和关闭连接,节约宝贵的TCP/IP连接资源
6.队列、路由键、绑定、交换器之间的关系
队列通过路由键(routing key,某种确定的规则)绑定到交换器,生产者把消息发送到了交换器,交换器根据绑定的路由键将消息路由到特定的队列,订阅了队列的消费者进行接收。
问题:
1)如果消息达到无人订阅的队列会怎么办?
消息会一直在队列中等待,直到内存溢出。RabbitMQ会默认队列是无限长度的。
2)多个消费者订阅到同一队列怎么办?
消息会轮询的方式发送给消费者,每个消息只会发送给一个消费者
3)消息路由到了不存在的队列怎么办?
会忽略,当消息不存在,消息丢失了。
7. 消息的确认机制
消费者收到的每一条消息都必须进行确认,分为自动确认和消费者自行确认。
消费者在声明队列时,指定autoAck参数(true:自动确认,false:自行确认),false时RabbitMQ会等到消费者显示的发回一个ack信号才会删除消息。
消息确认机制的好处:
autoAck=false时,有足够时间让消费者处理消息,直到消费者显示调用basicAck为止。
autoAck=false时,Rabbitmq中消息分为了两部分:1、等待投递的消息;2、已经投递,但是还没有收到ack信号的。如果消费者断连了,服务器会把消息重新入队,投递给下一个消费者。
未ack的消息是没有超时时间的
8. 如何明确拒绝消息
1)消费者断连
2)消费者使用reject命令(requeue=true,重新分发消息到其他消费者,requeue=false移除消息)
3)nack命令(批量的拒绝,requeue=true,重新分发消息,requeue=false移除消息)
Nack命令是rabbitmq单独实现的命令,其他消息组件没有
拒绝消息是为了处理一些特殊的异常
9. 创建队列
生产者和消费者都可以创建队列(declareQueue)。消费者订阅了队列,不能再声明队列了。
相关参数(exclusive:队列是应用程序私有的,auto-delete:最后一个消费者取消订阅时,队列会自动删除,durable:当前队列是否持久化)
检测队列是否存在:Declare 时的passive参数
10. 四种交换器
direct,fanout,topic,headers
direct: 路由键完全匹配时,消息才投放到对应队列。AMQP实现都必须有一个direct交换器(默认交换器),名称为空白字符。队列不声明交换器,会自动绑定到默认交换器,队列的名称作为路由键。
fanout:可以理解为广播,会把交换器上的所有消息投放到绑定到这个交换机上的队列上,无论这个队列是通过哪个路由键绑定到这个交换器上的
topic:主题,使来自不同源头的消息到达同一个队列
headers: 匹配消息头,其余与direct一样,实用性不大
topic使用场景举例:
日志处理场景:
1)有交换器(topic)log_exchange,日志级别有 error,info,warning,应用模块有 user,order,email,路由键的规则是日志级别+“.”+应用模块名(例如info.user)
2)发送邮件失败,报告一个email的error,basicPublic(message,’log-exchange’,’error.email’)
队列的绑定:queueBind(“email-error-queue”,’log-exchange’,’error.email’)
要监听email所有的日志怎么办?
queueBind(“email-log-queue”,’log-exchange’,’*.email’)
监听所有模块所有级别日志?
queuebind(“all-log-queue”,’log-exchange’,’#’)
“.”会把路由键分为好几个标识符,“*”匹配一个标识符,“#”匹配一个或者多个(xxx.yyy.zzzz 可以: xxx.*. zzzz , xxx.# , #.zzzz)。
11. 虚拟主机
Vhost类比在物理机上装虚拟机
Vhost,真实RabbitMQ服务器上的mini型虚拟的MQ服务器。有自己的权限机制。
Vhost提供了一个逻辑上的分离,可以区分不同客户端、避免队列的名称冲突、交换器的名称冲突。
RabbitMq包含了一个缺省的vhost :"/",用户名guest,口令 guest(guest用户只能在本机访问)。
12. 消息持久化
1)队列必须持久化
2)交换器也必须持久化
3)消息的投递模式参数(int型)的值必须为2
以上条件全部满足,消息才能持久化,写入持久化日志
持久化后带来的问题:性能下降10倍
13. AMQP和JMS区别
|
JMS |
AMQP |
定义 |
Java api |
协议 |
Model |
P2P Pub/Sub |
Direct Fanout Topic headers |
支持消息类型 |
5种 |
Byte[] 自行消息序列化,Json化 |
综合评价 |
Java系统,模型满足要求,跨平台较差 |
协议,天然跨平台,跨语言 |
二、RabbitMQ的安装和运行
安装和运行教程:
以上是关于消息中间件系列二:RabbitMQ入门(基本概念RabbitMQ的安装和运行)的主要内容,如果未能解决你的问题,请参考以下文章
消息中间件系列三:使用RabbitMq原生Java客户端进行消息通信(消费者(接收方)自动确认模式消费者(接收方)自行确认模式生产者(发送方)确认模式)