您的位置:首页 > 其它

[置顶] 中间件系列九 RabbmtiMQ 通过wireshark抓包学习AMQP协议

2018-02-06 20:06 441 查看

1. 概述

本文先在普通场景下生产者发送一条消息,消费者接受此条消息,然后通过wireshark进行抓包,对抓的包进行详细的分析。

2. 背景

3.1. 本文测试的环境

RabbitMQ的IP地址是10.240.89.147

生产者和消费者的IP地址都是10.240.80.99

3.2. 测试的代码

本文的代码和之前博客的代码相似,这里略

相关的代码内容如下:

生产者代码NoPublisherConfirmSend.java

消费者代码PublisherConfirmRecv.java

测试代码PublisherConfirmTest.java

发送端先发送1条消息,消费者接收消息

// 发送端
executorService.submit(() -> {
NoPublisherConfirmSend.execute(rabbitmq_host, rabbitmq_user, rabbitmq_pwd, routingKey,1);
});
Thread.sleep(5* 100);

// 接收端
executorService.submit(() -> {
PublisherConfirmRecv.execute(rabbitmq_host, rabbitmq_user, rabbitmq_pwd, routingKey);
});
Thread.sleep(5* 100);


4. 生产者发送消息的包分析

4.1. 所有包的截图



下方对包进行详细描述

4.2. 109-110帧 : TCP的建立连接的三次握手

TCP的建立连接的三次握手,关于TCP的基本信息可以参考之前的文章

4.3. 112-113帧:RabbitMQ的客户端告诉RabbitMQ自己使用的协议及版本

112帧:RabbitMQ的客户端告诉RabbitMQ自己使用的协议及版本



113帧:TCP应答信令:表示服务端告诉发送端已经收到这之前的包

4.4. 114 - 122:RabbitMQ服务端和客户端建立连接,并约定参数

114帧 Connection.Start:RabbitMQ告诉客户端通信的协议和版本、SASL认证机制(详细见)、语言环境以及RabbitMQ的版本信息和支持能力



117帧 Connection.Start-Ok :客户端带上连接使用的帐号和密码、认证机制、语言环境、客户的信息以及能力



118帧 Connection.Tune:RabbitMQ服务端和客户端开始进行参数协商



119帧 Connection.Tune-Ok: 客户端要么接受服务端过来的参数,要么将这些值变低,在发送给服务端



120帧 Connection.Open vhost=/ :RabbbitMQ客户端打开一个连接,并请求设置vhost值



121帖 TCP应答

122帖 Connection.Open-Ok:RabbitMQ服务端对vhost进行验证,如果成功,则返回如下此信息



4.5. 123 - 124:创建通道

123帧 Channel.Open:客户端打开一个新通道



124帧Channel.Open-Ok:RabbitMQ服务端回复新通道准备完毕



4.6. 125 - 126帧: 创建Exchange

125帧 Exchange.Declare 客户端向RabbitMQ声明一个Exchange



126帧 Exchange.Declare-Ok:RabbitMQ收到请求后,如果发现同名的exchange存在且属性相同,则返回如下包,否则抛出异常



4.7. 127帧 Basic.Publish 客户端开始发送消息



在这里客户端只管发送消息,而不关心消息是否正确到达RabbitMQ

4.8. 128 - 132 帧:关闭通关,关闭连接,回收 资源

128 帧 Channel.Close:客户端请求关闭通道



129帧 ACK应答

130帧 Channel.Close-Ok:RabbitMQ关闭通关,并应答



131帧 Connection.Close:客户端请求关闭连接



132帧 Connection.Close-Ok:RabbitMQ关闭连接,并应答



4.9. TCP四次挥手关闭连接

最后是TCP四次挥手关闭连接,但是这里不是标准的四次挥手,可能是会话双方关闭顺序异常引起的问题

4.10. 总结如下



5. 消费者接收消息的包分析

5.1. 所有包的截图

和生产者通话大部分相同,以下部分不同

消费者比生产者少了发送消息部分

消费者比生产者多了声明队列、队列绑定到交换机、消费消息部分

下面只列出不同的地方



5.2. 367 - 368帧 声明队列

367帧Queue.Declare: 客户端向RabbitMQ服务端声明队列



368帧 Queue.Declare-Ok:RabbitMQ创建队列成功并返回信息给客户端



5.3. 369-370:队列绑定到交换机

369帧Queue.Bind: 客户端向RabbitMQ服务端要求将队列绑定到指定交换机



370帧 Queue.Bind-Ok:RabbitMQ绑定成功并返回信息给客户端



5.4. 371-372帧: 消费者接收消息

371帧 Basic.Consume 客户端设置要消费的队列



372帧 Basic.Consume-Ok RabbitMQ服务端向客户端推送消息



以上是一次接收一个消息,也可以同一个包同时接收多个消息







5.5. 整个流程如下



代码

上文的详细代码主要如下:

生产者代码: NoPublisherConfirmSend.java

消费者代码:PublisherConfirmRecv.java

测试代码:PublisherConfirmTest.java的方法 publisherconfirm_noPublisherConfirmSend()

所有的详细代码见github代码,请尽量使用tag v0.14,不要使用master,因为master一直在变,不能保证文章中代码和github上的代码一直相同
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐