Извините, но я не в курсе любой удобной документации, описывающей протокол проволочной Apache Zookeeper в любой большой детализации. Внутренне наша база кода использует фреймворк под названием Jute, который основан на коде, первоначально адаптированном из Apache Hadoop. Структура позволяет определять структурированные записи, генерирует код на основе этих определений, а затем предоставляет процедуры сериализации/десериализации, называемые остальной частью кода ZooKeeper.
Определения записей джута видны здесь:
https://github.com/apache/zookeeper/blob/release-3.4.9/src/zookeeper.jute
Структура кода джута для обработки этих определений записей видно здесь:
https://github.com/apache/zookeeper/tree/release-3.4.9/src/java/main/org/apache/jute
Я думаю, что единственный вариант для глубокое понимание проводного протокола было бы вникнуть в этот код.
После рытья через несколько слоев сокеты кода обработки (который использует либо NIO или Нетти в зависимости от конфигурации), реальная работа десериализации полезной нагрузки происходит в ZooKeeperServer#processPacket(ServerCnxn, ByteBuffer)
:
https://github.com/apache/zookeeper/blob/release-3.4.9/src/java/main/org/apache/zookeeper/server/ZooKeeperServer.java#L941
Здесь он десериализует RequestHeader
, который является общим заголовком метаданных в начале всех сообщений протокола. Определение RequestHeader
показано здесь:
https://github.com/apache/zookeeper/blob/release-3.4.9/src/zookeeper.jute#L88-L91
Мы можем видеть, она состоит из 2-х 4-байтовых целых полей: идентификатор соединения с последующим типом сообщения. Значения типа определены в ZooDefs
здесь:
https://github.com/apache/zookeeper/blob/release-3.4.9/src/java/main/org/apache/zookeeper/ZooDefs.java#L28
Зная все это, давайте вернемся к вашему захвату пакетов и попытаться понять его:
Data: 00000008fffffffe0000000b
00000008 - payload length
fffffffe - connection ID
0000000b - op code ("ping")
В передней части каждого сообщение (даже до RequestHeader
), есть длина полезной нагрузки. Здесь мы видим длину 8 байтов.
Следующие 4 байта - это идентификатор соединения, fffffffe
.
Окончательные 4 байта - это код op, 0000000b
(или 11 десятичных знаков). Чтение ZooDefs
, мы видим, что это операция «ping». Операция «ping» используется для периодического биения между клиентом и сервером. В полезной нагрузке для операции «пинг» нет дополнительных данных, поэтому это конец этого пакета, и после него нет дополнительных данных. Для разных операций в полезной нагрузке будут представлены дополнительные данные, представляющие аргументы операции.
Надеюсь, это поможет.
Я просмотрел документацию, но не понял, как прикреплены метаданные? Где мы указываем, какой тип запроса является конкретным сообщением? Извините, но я думал о строках декомпозиции заголовков, таких как TCP-пакеты. Однако документация помогает. – ankshah
@ankshah, я только что отредактировал свой ответ, чтобы предоставить ссылки на несколько других релевантных пунктов в базе кода ZooKeeper, а затем я использовал эту информацию, чтобы дать подробное пошаговое описание конкретного захвата пакета, опубликованного в вашем вопросе. Надеюсь, это полезно. –