6. Заголовок

Обзор

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

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

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

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

Структура

Заголовок состоит из четырёх полей. Все числа в заголовке имеют прямой порядок байтов (little-endian).

Поле Размер Размер
(большой пакет)
Описание
<ПРОТОКОЛ> 4 4 "ZBXD" или 5A 42 58 44
<ФЛАГИ> 1 1 Флаги протокола:
0x01 - протокол связи Zabbix
0x02 - сжатие
0x04 - большой пакет
<ДЛИНАДАННЫХ> 4 8 Длина данных.
<РЕЗЕРВ> 4 8 При использовании сжатия (флаг 0x02) - длина несжатых данных
Когда сжатие не используется - 00 00 00 00

Примеры

Здесь представлены несколько фрагментов кода, демонстрирующих, как к тем данным, которые вы хотите отослать (переменная data), добавить заголовок протокола 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"