上一篇介绍了AQMP的通讯实体和实体之间的关系,这一部分介绍底层通讯协议。理解了这部分内容基本上就理解了AMQP的网络通讯原理,写个Broker或者client都是分分钟的事情(^_^)。
AQMP规定了使用TCP的5672端口作为通讯端口,在规范中所有的数据包都被成为Frame(和数据链路层的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在“应用层”规定了一些通讯术语——“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”)。
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。
欢迎关注公众账号了解更多信息“写程序的康德——思考、批判、理性”
