6 Заголовок

Обзор

Заголовок присутствует во всех сообщениях запросов и ответов между компонентами Zabbix. Он необходим для определения длины сообщения, сжато оно или нет, является ли пакет большим или нет.

Протокол обмена данными Zabbix имеет ограничение размера пакета в 1 ГБ на одно соединение. Ограничение в 1 ГБ применяется как к длине данных полученного пакета, так и к длине данных в несжатом виде.

При отправке конфигурации на Zabbix прокси ограничение размера пакета увеличивается до 4 ГБ, чтобы обеспечить синхронизацию больших конфигураций. Когда длина данных до сжатия превышает 4 ГБ, Zabbix сервер автоматически начинает использовать формат большого пакета (флаг 0x04), который увеличивает ограничение размера пакета до 16 ГБ.

Обратите внимание, что хотя формат большого пакета может использоваться для отправки любых данных, в настоящее время только синхронизатор конфигурации Zabbix прокси может обрабатывать пакеты размером более 1 ГБ.

Структура

Заголовок состоит из четырёх полей. Все числа в заголовке отформатированы в формате little-endian.

Поле Размер Размер
(большой пакет)
Описание
<PROTOCOL> 4 4 "ZBXD" или 5A 42 58 44
<FLAGS> 1 1 Флаги протокола:
0x01 — протокол обмена данными Zabbix
0x02 — сжатие
0x04 — большой пакет
<DATALEN> 4 8 Длина данных.
<RESERVED> 4 8 При использовании сжатия (флаг 0x02) — длина несжатых данных
Если сжатие не используется — 00 00 00 00

Примеры

Ниже приведены несколько фрагментов кода, показывающих, как добавить заголовок протокола Zabbix к данным, которые вы хотите отправить, чтобы получить пакет, который следует отправить в Zabbix, чтобы он был корректно интерпретирован. Эти фрагменты кода предполагают, что размер данных не превышает 1 ГБ, поэтому формат большого пакета не используется.

Python
packet = b"ZBXD\1" + struct.pack("<II", len(data), 0) + data

или

def zbx_create_header(plain_data_size, compressed_data_size=None):
    protocol = b"ZBXD"
    flags = 0x01
    if compressed_data_size is None:
        datalen = plain_data_size
        reserved = 0
    else:
        flags |= 0x02
        datalen = compressed_data_size
        reserved = plain_data_size
    return protocol + struct.pack("<BII", flags, datalen, reserved)

packet = zbx_create_header(len(data)) + data
Perl
my $packet = "ZBXD\1" . pack("(II)<", length($data), 0) . $data;

или

sub zbx_create_header($;$)
{
    my $plain_data_size = shift;
    my $compressed_data_size = shift;

    my $protocol = "ZBXD";
    my $flags = 0x01;
    my $datalen;
    my $reserved;

    if (!defined($compressed_data_size))
    {
        $datalen = $plain_data_size;
        $reserved = 0;
    }
    else
    {
        $flags |= 0x02;
        $datalen = $compressed_data_size;
        $reserved = $plain_data_size;
    }

    return $protocol . chr($flags) . pack("(II)<", $datalen, $reserved);
}

my $packet = zbx_create_header(length($data)) . $data;
PHP
$packet = "ZBXD\1" . pack("VV", strlen($data), 0) . $data;

или

function zbx_create_header($plain_data_size, $compressed_data_size = null)
{
    $protocol = "ZBXD";
    $flags = 0x01;
    if (is_null($compressed_data_size))
    {
        $datalen = $plain_data_size;
        $reserved = 0;
    }
    else
    {
        $flags |= 0x02;
        $datalen = $compressed_data_size;
        $reserved = $plain_data_size;
    }
    return $protocol . chr($flags) . pack("VV", $datalen, $reserved);
}

$packet = zbx_create_header(strlen($data)) . $data;
Bash
datalen=$(printf "%08x" ${#data})
datalen="\\x${datalen:6:2}\\x${datalen:4:2}\\x${datalen:2:2}\\x${datalen:0:2}"
printf "ZBXD\1${datalen}\0\0\0\0%s" "$data"