我需要使用tcpdump调试我的kafka使用者和zookeeper之间交换的数据。我查看了zookeeper文档但找不到有关zookeeper通信协议的任何内容,即删除标题后使用wireshark获取以下数据转储。我如何解释数据部分?
Frame 1: 78 bytes on wire (624 bits), 78 bytes captured (624 bits)
Ethernet II, Src: 22:00:0a:xx:xx:xx (22:00:xx:xx:xx:xx), Dst: fe:ff:xx:xx:xx:xx (fe:ff:ff:xx:xx:xx)
Internet Protocol Version 4, Src: 10.234.xxx.xxx, Dst: 10.231.xxx.xxx
Transmission Control Protocol, Src Port: 51720 (51720), Dst Port: 2181 (2181), Seq: 1, Ack: 1, Len: 12
Data (12 bytes)
Data: 00000008fffffffe0000000b
[Length: 12]
答案 0 :(得分:6)
很抱歉,但我不知道任何方便的文档,它们详细描述了Apache ZooKeeper线路协议。在内部,我们的代码库使用一个名为Jute的框架,该框架基于最初改编自Apache Hadoop的代码。该框架允许定义结构化记录,根据这些定义生成代码,然后提供由ZooKeeper代码的其余部分调用的序列化/反序列化例程。
黄麻记录定义在此处可见:
https://github.com/apache/zookeeper/blob/release-3.4.9/src/zookeeper.jute
这里可以看到用于处理这些记录定义的Jute框架代码:
https://github.com/apache/zookeeper/tree/release-3.4.9/src/java/main/org/apache/jute
我认为深入理解有线协议的唯一选择是深入研究这段代码。
在深入挖掘几层原始套接字处理代码(根据配置使用NIO或Netty)之后,反序列化有效负载的实际工作发生在ZooKeeperServer#processPacket(ServerCnxn, ByteBuffer)
:
这是对RequestHeader
进行反序列化的地方,RequestHeader
是所有协议消息前面的元数据的公共标题。 ZooDefs
的定义如下所示:
https://github.com/apache/zookeeper/blob/release-3.4.9/src/zookeeper.jute#L88-L91
我们可以看到它由2个4字节整数字段组成:连接ID后跟消息类型。类型值在Data: 00000008fffffffe0000000b
00000008 - payload length
fffffffe - connection ID
0000000b - op code ("ping")
此处定义:
了解所有这些,让我们回到您的数据包捕获并尝试理解它:
RequestHeader
在每条消息的前面(甚至在fffffffe
之前),有效负载的长度。这里我们看到8个字节的长度。
接下来的4个字节是连接ID 0000000b
。
最后4个字节是操作码,ZooDefs
(或十进制的11)。阅读#import <UIKit/UIKit.h>
float addingtheTime;
@interface ViewController : UIViewController
{
IBOutlet UILabel *Label;
NSTimer *Timer;
}
@end
,我们可以看到这是&#34; ping&#34;操作。 &#34; ping&#34; operation用于客户端和服务器之间的周期性心跳。在&#34; ping&#34;的有效载荷中不需要额外的数据。操作,所以这是该数据包的结束,并且之后没有其他数据。对于不同的操作,有效负载中会有其他数据,表示操作的参数。
我希望这会有所帮助。