阿粉之前也讲述过关于 RabbitMQ 的相关内容,比如他们的配置,以及 RabbitMQ 整合 SpringBoot 使用,而且自己使用过之后,就会在自己的简历上面写上自己使用 RabbitMQ 实现了什么功能,但是这就会导致,有些面试官就会问一些关于 RabbitMQ 的一些相关的问题,比如, RabbitMQ 中的交换机是什么, RabbitMQ 中的路由都有哪些?
反正诸如此类的问题,都是属于相对简单的问题,但是也不排除会有一些相对高级一点的问题,就比如接下来的关于 RabbitMQ 的协议的问题。
AMQP 协议
AMQP(高级消息队列协议)是一个网络协议。它支持符合要求的客户端应用(application)和消息中间件代理(messaging middleware broker)之间进行通信。
消息代理(message brokers)从发布者(publishers)亦称生产者(producers)那儿接收消息,并根据既定的路由规则把接收到的消息发送给处理消息的消费者(consumers)。
由于AMQP是一个网络协议,所以这个过程中的发布者,消费者,消息代理 可以存在于不同的设备上。
这就是使用消息队列最好的地方,消息的发布者,也就是生产者和消息费可以不在相同的设备上,但是可以保持通信。
AMQP协议是一个二进制协议,拥有一些现代特点:多信道、协商式、异步、安全、跨平台、中立、高效。
AMQP通常被划分为三层:
模型层定义了一套命令(按功能分类),客户端应用可以利用这些命令来实现它的业务功能。
会话层负责将命令从客户端应用传递给服务器,再将服务器的应答传递给客户端应用,会话层为这个传递过程提供可靠性、同步机制和错误处理。
传输层提供帧处理、信道复用、错误检测和数据表示。
实现者可以将传输层替换成任意传输协议,只要不改变AMQP协议中与客户端应用程序相关的功能。实现者还可以使用其他高层协议中的会话层。
如果你要是去百度上所有 AMQP 反正各大博主上来就说 AMQP 0-9-1 ,但是也不说 这个 0-9-1 到底是什么意思,反正都是书中找的,直接介绍就完事。
这个东西,阿粉专门找了一些书籍,才了解这个东西指的是什么。
实际上 AMQP 后面所携带的 0-9-1 指的是他的版本号,主版本号和次版本号。我们约定版本由主版本号后面加小数点再加上次版本号组成(比如1-3表示主版本号为1,次版本号为3)。
主版本号保持不变,次版本号递增。当AMQP工作组提升主版本号时,次版本号将被设置为0。因此,有可能出现这样的版本序列:1-2,1-3,1-4,2-0,2-1……
旦本协议发布之后(主版本号大于1),应尽量防止次版本号递增到9。不过在发布之前(版本0-x),由于会对本协议进行频繁的修订,可以不遵守这条约定。
而这也是大家在百度上所有 AMQP 协议中的 AMQP 0-9-1 的由来。
AMQP 模型
一个由关键实体和语义表示的逻辑框架,遵从AMQP规范的服务器必须提供这些实体和语义。为了实现本规范中定义的语义,客户端可以发送命令来控制AMQP服务器。
实际上这个就是一个工作过程的简介。
消息的生产者,将消息发送到交换机,然后交换机收到消息之后,根据不同的路由规则,发给绑定的队列,最后 AMQP 代理会将消息投递给订阅了此队列的消费者,或者消费者按照需求自行获取。
也就是从 product ->exchange -> queue ->consumer
其实 AMQP 也是一个可编程的协议。
可编程协议是什么?
某种意义上说AMQP的实体和路由规则是由应用本身定义的,而不是由消息代理定义。包括像声明队列和交换机,定义他们之间的绑定,订阅队列等等关于协议本身的操作。
这虽然能让开发人员自由发挥,但也需要他们注意潜在的定义冲突。当然这在实践中很少会发生,如果发生,会以配置错误(misconfiguration)的形式表现出来。
应用程序(Applications)声明AMQP实体,定义需要的路由方案,或者删除不再需要的AMQP实体。
至于 RabbitMQ 中的 队列,交换机,后还有路由啥的,阿粉就不说了,那个东西自己理解反而比别人说的有效。
唯一需要注意的是, 当一条消息发布的时候,发布者可能会指定一些消息属性message attributes(也叫message meta-data消息元数据),其中有一些消息属性是用于消息中间件处理消息,其余的部分则是用于消息消费者对于消息中间件完全透明。
由于网络的不稳定性,消息在传输过程中可能出现失败的情况,鉴于此AMQP 0-9-1提供了一种消息确认机制message acknowledgements: 当一条消息传递给消费者后该消费者发送一条通知notifies给消息中间件来确认消息,无论是自动的还是开发者自己这样做,当消息确认机制使用时,只有当消息代理收到通知后才会将该条或该组消息从消息队列中移除。
在一些特定情况下,比如当消息不能被路由时,消息可能会被返回给消息发布者,或者删除,或者如果消息代理实现了某种扩展插件,则这些无法被路由的消息可能会被放入一个称之为dead letter queue(死亡标记队列)的队列中,发布者可以通过指定一些确定的消息属性 message attributes来响应出现这种情景时消息应该如何被处理。