RabbitMQ高级指南——AMQP解析(下)

2017-11-02 18:12 阅读 363 views 次 评论 1 条

RabbitMQ高级指南——AMQP解析(下)

上一篇介绍了AQMP的通讯实体和实体之间的关系,这一部分介绍底层通讯协议。理解了这部分内容基本上就理解了AMQP的网络通讯原理,写个Broker或者client都是分分钟的事情(^_^)。

AMQP底层通讯

AQMP规定了使用TCP的5672端口作为通讯端口,在规范中所有的数据包都被成为Frame(和数据链路层的Frame没有直接关系)。它一共有三种类型

  • Method Frame,主要是一些“管理数据包”(在AMQP规范中成为Command)。比如:declare queue、publish message都是通过method frame实现的。

  • Content Frame,Publish、Deliver消息的时候使用的数据包,Method Frame只做管理;消息本身则被封装为Content Frame

  • Heartbeat Frame,心跳

下面是Frame的数据包格式
一个Frame最小单位是8个字节,一个字节type,两个字节channel、四个字节size,一个字节frame-endtype,8个字节可以拥有255个不同的值,目前只用到4个:1表示method frame,2、3表示content frame,8表示hearbeat framechannel,只是一个逻辑概念,最大值是65536size,表示后续还有多少数据,最大值是4294967296,4Gframe-end,表示结束,没有什么意义固定值206我们看一下最简单的hearbeat frame
心跳包就是最小的合法数据包,它是8个字节:

  • 1byte type

  • 2byte channel number

  • 4byte payload size

  • 1byte FRAME_END

Method Frame、Content Frame会比较复杂一点,可以参考AMQP Java Client的。AMQPImpl、Frame、AMQPChannel这几个类。基本上就是把内容序列化一下,唯一复杂的地方是序列化Table类型(Key/Value结构)。

AMQP的Command

AMQP在“应用层”规定了一些通讯术语——“AMQP指令架构”(AMQP Command Architecture)所有的Command可以都是针对上一篇讲的实体,直接看一幅图


Connection、Channel类型是一定会用到的,AMQP所有的通讯都是建立在打开Connection->打开Channel之上的。我们来看如何Publish一条消息
AMQP的Command间接规范了Client的API命名,无论你是用Python、Java、C#的Client它们的方法都像代码例子中的那样(如果你仔细观察不难发现我们调用的方法名几乎和Command的术语是一一对应的“new connection”、“create channel”、“declare queue”、“baisc publish”)。

调试AMQP

Wireshark 2.0支持AMQP协议,抓取port 5672端口的数据包就可以看到Broker和Client的交互(注意不启用SSL的情况下密码是明文传送的)。
上图 对应的代码


连接到Broker后

  • Broker会先发送Command——Connection.Start(包含服务器支持的AMQP版本、厂商、支持的特性) ;Client向Borker确认Connection.Start-Ok。这个过程是Broker和Client协商过程。

  • Client发送Connection.Tune申请建立Channel,Broker返回Connection.Tune-ok确认

  • Client发送Connection.Open确认操作的vhost(可以理解为命名空间),Broker确认

以上操作就是完整的Connection过程,是最复杂的一部分。每个数据包都可以看到具体内容,比如


type=1(这是一个Method Frame),channel=0,len是404个字节,后面的class、method、arguments则是payload的内容,不同类型的method frame各自的class、method是不同的。比如上图是Connection.start。


版权声明:本文版权由木秀林网所有,转载请保留链接:RabbitMQ高级指南——AMQP解析(下)
分类:RabbitMQ 标签:

发表评论


表情

  1. 惠翔
    惠翔 【农民】 @回复

    有人吗