1.什么是协议

提到协议,需要先说一下TCP/IP,网络中的不同个体传输消息,底层可以通过TCP、UDP等机制进行传输。而TCP本身是基于流的传输层协议,并不具备数据描述,数据结构以及数据声明的功能。
但是很多时候,在不同网络个体之间传递数据,需要制定一些规范的数据结构,数据格式。这时候,就需要基于TCP链接,在应用层进行相关数据传输规范的制定,而这种制定的规范,称为协议
(通俗来说,通过一些约定,来从流数据中读取出需要的数据内容,这些约定就是协议)

2.Http协议是否适用于消息中间件

既然协议的制定就是为了数据的传输,那么对于RabbitMq这一类的消息中间件,也必然要遵守一些协议。然而问题就来了,Http协议是否适用于RabbitMq?
理论上来说,可以用,但是不适合

  1. 首先Http协议的内容太过复杂,请求头和响应头,其中包含了Cookie、请求方式,请求参数,响应状态,响应码等很多内容。然后消息中间件只需要进行消息的发送,消息的持久化以及消息的接收。Http协议对于消息中间件来说,太重了,消息中间件的协议要求就是简洁和高性能
  2. 其次,Http协议相对来说是一种短链接,然而消息中间件是需要频繁进行消息的接收和发送,频繁的创建、关闭链接对于追求吞吐量的消息中间件很明显不合适。并且链接关闭很有可能会带来消息数据的丢失,很明显这也是不适合消息中间件的

    3.RabbitMq支持的协议

    既然Http协议不适合消息中间件,哪些协议又适合呢?接下来,结合RabbitMq支持的协议,对这个问题进行解答

    AMQP

    AMQP全称Advanced Message Queuing Protocol,翻译为高级消息队列协议。
    RabbitMq的默认协议即为AMQP协议

    起源

    在消息中间件这个理念被提出并开始落地商用后,各大厂商都研发了各自的消息中间件。然后一个很大的问题就是,由于每个厂商的中间件协议各不相同,导致用户在使用时,无法做到使用一套协议就可以适配所有消息中间件
    2004年 JPMorgan Chase 和 iMatix 公司一起合作开发了AMQP协议,该协议被设计出后就成为了消息中间件协议的开放标椎。任意的用户基于AMQP协议都可以和AMQP供应商提供的消息中间件进行交互

    特点

  3. 独立于平台的底层消息传递协议

  4. 消费者驱动消息传递
  5. 跨语言和平台的互用性
  6. 有5种交换类型direct,fanout,topic,headers,system
  7. 长连接,并且在一个连接中打开多个Channel
  8. 面向缓存的
  9. 可实现高性能
  10. 支持长周期消息传递
  11. 支持经典的消息队列,循环,存储和转发
  12. 支持事务(跨消息队列)
  13. 支持分布式事务(XA,X/OPEN,MS DTC)
  14. 使用SASL和TLS确保安全性
  15. 支持代理安全服务器
  16. 元数据可以控制消息流
  17. 不支持LVQ
  18. 客户端和服务端对等
  19. 可扩展

    模型

    看上去是不是很眼熟,没错,RabbitMq就是一个标椎的AMQP协议的实现。
    最重要的概念就是Visual Host,Exchange,Queue,具体参考:RabbitMq基础知识
    image.png

    数据结构

    AMQP是一个基于帧的协议,包括方法帧、内容帧,心跳帧等
    所有的帧都由一个头(7个字节),任意大小的负载(payload),和一个检测错误的帧(frame-end)字节组成
    image.png

    MQTT

    MQTT全称Message Queuing Telemetry Transport,翻译为消息队列遥测传输协议

    起源

    随着万物互联的时代来临,越来越多的小型设备,例如各种家电等也需要进行一些实时的消息传输,然而AMQP的操作相对来说比较复杂,小型设备的性能无法在规定的短时间内解析出AMQP消息的内容
    此时MQTT出现了,MQTT的目的就是为了帮助小型设备,在低带宽,不稳定的网络环境下,进行高效稳定的消息服务

    特点

    MQTT是基于发布订阅模式的轻量级协议,特点就是数据结构简单且高效,用极少的代码和有限的带宽,提供可靠的消息服务。
    因为MQTT高效、简洁、低带宽的即时通讯性,其在物联网,移动通讯方面的有着极为广泛的应用

    模型

    MQTT使用的发布/订阅消息模式,它提供了一对多的消息分发机制,从而实现与应用程序的解耦。
    这是一种消息传递模式,消息不是直接从发送器发送到接收器,而是由MQTT Serve分发的。
    image.png

数据结构

固定头(Fixed header)

存在于所有MQTT数据包中,表示数据包类型及数据包的分组标识,包括如下数据结构
image.png

Qos

Qos全称Quality of Service levels,翻译为服务质量等级。
为了避免网络不稳定带来的服务不确定性,MQTT通过Qos来优化消息传输的可靠性,即发送者发送几次消息给接收者

  • 在消息发布时,发送者为Publisher,接收者为Broker
  • 在消息消费时,发送者为Broker,接收者为Consumer

Qos包含以下取值

  1. 0:最多发送一次,即<=1,此时会出现消息丢失情况
  2. 1:至少发送一次,即>=1。此时会出现消息重复的情况
  3. 2:发送一次,即=1。理论上不会出现消息的重复或丢失,但是此级别带来的网络损耗最高
    可变头(Variable header)
    存在于部分MQTT数据包中,取决于数据包类型
    消息体(Payload)
    存在于部分MQTT数据包中,表示客户端收到的具体内容
    Payload消息体是MQTT数据包的第三部分,CONNECT、SUBSCRIBE、SUBACK、UNSUBSCRIBE四种类型的消息存在消息体:
  • CONNECT消息体:客户端的ClientID、订阅的Topic、Message以及用户名和密码
  • SUBSCRIB消息体:一系列的要订阅的主题以及QoS。
  • SUBACK消息体:服务器对于SUBSCRIBE所申请的主题及QoS进行确认和回复。
  • UNSUBSCRIBE消息体:要取消订阅的主题。

    STOMP

    STOMP全称Simple Text Orientated Messaging Protocol,翻译为简单面向文本消息协议

    数据结构

    STOMP是一个基于帧(Frame)的协议,客户端与服务端通过发送不同的命令帧来开启或关闭链接,以及进行数据的交互
    每个帧的结构如下
    image.png
    可以看出,每个帧都是由line(行)构成
  1. 第一行包含了命令,然后紧跟键值对形式的Header内容。包含如下命令
  • CONNECT(链接)
  • SEND(发送消息)
  • SUBSCRIBE
  • UNSUBSCRIBE
  • BEGIN
  • COMMIT
  • ABORT
  • ACK
  • NACK
  • DISCONNECT
  1. 第二行必须是空行。
  2. 第三行开始就是Body内容,末尾都以^@结尾。虽然STOMP是简单文本传输协议,但是body也是可以传递流数据的