1.RabbitMq的消息是如何到达队列的?
当你想要将消息投递到队列时,你通过把消息发送给交换器来完成。然后,根据确定的规则,RabbitMQ将会决定消息该投递到哪个队列。这些规则被称作路由键(routing key)。队列通过路由键绑定到指定交换器。当你把消息发送到代理服务器时,消息将拥有一个路由键---即便是空的---RabbitMQ也会将其和绑定使用的路由键进行匹配。如果相匹配的话,那么消息将会投递到该队列。如果路由的消息不匹配任何绑定模式的话,消息将进入“黑洞”。
2.协议中定义了几种不同类型的交换器?
一共有四种类型:direct、fanout、topic和headers。每一种类型实现了不同的路由算法。
basic_publish($msg,' ' , 'queue-name'),第一个参数是你想要发送的消息内容;第二个参数指定交换器;第三个参数是路由键。
queue_bind(‘msg-inbox-errores’,‘log-exchange’,‘error.msg-inbox’)第一个参数队列名称;第二个参数交换器名称;第三个参数路由键。
direct交换器非常简单:如果路由键匹配的话,消息就被投递到对应的队列。
fanout:这种类型的交换器会将收到的消息广播到绑定的队列上。消息通信模式很简单:当你发送一条消息到fanout交换器时,它会把消息投递给所有附加在此交换器上的队列。
topic:这类交换器允许你实现有趣的消息通信场景,它使得来自不同源头的消息能够到达同一个队列。
3.vhost概念
每一个RabbitMQ服务器都能创建虚拟消息服务器,称之为虚拟主机(vhost)。每一个vhost本质上是一个mini版的RabbitMQ服务器,拥有自己的队列、交换器和绑定,更重要的是,它拥有自己的权限机制。vhost之于Rabbit就像虚拟机之于物理服务器一样:它们通过在各个实例间提供逻辑上分离,允许你为不同应用程序安全保密地运行数据。在RabbitMQ的例子中,控制权限是以vhost为单位的。当你在RabbitMQ里创建一个用户时,用户通常会被指派给至少一个vhost,并且只能访问被指派vhost内的队列、交换器和绑定。vhost需要通过RabbitMQ的安装路径下./sbin/目录中的rabbitmqctl工具来创建。
4.当RabbitMQ崩溃或者重启时,如何确保关键消息不丢失?
如果消息想要从Rabbit崩溃中恢复,那么消息必须:
1.把它的投递模式选项设置为2(持久)
2.发送到持久化的交换器
3.到达持久化的队列
RabbitMQ确保持久性消息能从服务器重启中恢复的方式是,将它们写入磁盘上的一个持久化日志文件。
建议部分关键信息使用持久化,不要大量的使用持久化。持久化需要磁盘写入,会降低RabbitMQ的吞吐量。不重要的信息的可靠传输可以考虑做一种应答模式,即生产者发送消息,消费者在得到并消费消息后给予应答,生产者同时监听应答队列,如果在指定时间内没有收到指定信息的应答,则生产者重新发送信息。
5.由于发布操作不返回任何信息给生产者,那我们怎么知道服务器是否已经持久化了持久消息到硬盘呢?
两种方案:第一种AMQP事务,第二种发送方确认模式。
AMQP事务不但会降低大约2-10倍的消息吞吐量,而且会使生产者应用程序同步,而我们使用消息通信就是想要避免同步。因此不建议使用AMQP事务。
发送方确认模式:需要发送方将信道设置为confirm模式,一旦信道进入confirm模式,所有在信道上发布的消息都会被指派一个唯一的ID号。一旦消息被投递给所有匹配的队列后,信道会发送一个发送方确认模式给生产者应用程序。这使得生产者知晓消息已经安全到达目的队列了。如果消息是可持久化的,那么确认消息只会在队列将消息写入磁盘后才会发出。发送方模式的最大好处是它们是异步的。一旦发布了一条消息,生产者应用程序就可以在等待确认的同时继续发送下一条。当确认消息最终收到的时候,生产者应用的回调方法就会被触发来处理该确认信息。如果Rabbit发生了内部错误从而导致了消息的丢失,Rabbit会发送一条nack(not acknowledge,未确认)消息。就像发送方确认消息那样,只不过这次说明的是消息已经丢失了。
6.生产者和消费者生产消费消息流程
发布者发布消息流程:
1. 链接到RabbitMQ
2.获取信道
3.声明交换器
4.创建消息
5.发布消息
6.关闭信道
7.关闭连接
消费者消费信息流程:
1.连接到RabbitMQ
2.获取信道
3.声明交换器
4.声明队列
5.把队列和交换器绑定起来
6.消费消息
7.关闭信道
8.关闭连接