2
1
Fork
You've already forked specification
0
Complete specification of the LNPP protocol.
2025年12月13日 12:07:52 +03:00
architecture.svg Updated vector drawings 2025年12月06日 23:07:52 +03:00
flow-graph.svg Updated vector drawings 2025年12月06日 23:07:52 +03:00
README.md Added source for the netif length 2025年12月13日 12:07:52 +03:00

Создана: 2025年10月05日

Авторы: Lich author@lch361.net

1-е издание

Краткое содержание

Данный документ полностью описывает протокол LNPP. Описание включает в себя цель этого протокола, мотивацию его разработки, архитектуру работы и формат сетевых сообщений. Описание протокола LNPP призвано стандартизировать процесс разработки программ, пользующихся этим протоколом для измерения производительности в Linux системах.

Введение

LNPP (Linux Network Performance Protocol) — это сетевой протокол для передачи информации о производительности узлов сети, работающих на ОС Linux. Он может быть использован для таких задач, как массовый мониторинг производительности узлов локальной сети и выявление проблем с вводом/выводом между несколькими узлами.

Спецификация LNPP разрабатывается с учётом минимализма, легковесности и простоты в использовании. Клиенты и сервисы, реализующие протокол LNPP, разрабатываются в соответствии с данной спецификацией.

Мотивация

Измерение производительности — одна из самых распространённых задач в системном администрировании. Системные мониторы — тип программ, предназначенный для интерактивного измерения производительности (напр. htop, btop). Любой системный монитор выводит различную информацию о производительности системы, периодически её обновляя.

Системные мониторы, к сожалению, не пригодны для мониторинга производительности нескольких устройств одновременно. Также, они не пригодны для использования на заднем фоне (в качестве системного сервиса): их интерфейс, как правило, не машиноориентирован, а данные из интерфейса не получится вывести в файл для дальнейшего пользования.

LNPP, а также клиентские и серверные программы, реализующие данный сетевой протокол, разрабатываются с целью создания как открытого стандарта для передачи данных системного монитора, так и для реализации свободных программ, готовых для решения задач массового мониторинга локальной сети, состоящей из узлов с ОС Linux.

Учитывая уклон в минимализм при проектировании LNPP, ещё одна из целей — разработать средство мониторинга производительности Linux, доступное для встраиваемых систем.

Текущая версия протокола предусматривает, в основном, работу с Linux. Данная ОС была выбрана в силу самой большой её распространённости на серверах.

Соглашения, используемые в спецификации

Правила, описывающие грамматику, в данной спецификации оформлены по нотации ABNF, описанной в RFC 5234.

Архитектура протокола. Принцип работы программ

Схема архитектуры LNPP

LNPP — клиент-серверный протокол. Сервис LNPP — это непрерывный процесс (демон) под управлением ОС Linux, ответственный за хранение и периодическое обновление метрик производительности, а также за передачу этих метрик клиентам, подключившимся по сети. Клиент LNPP — это процесс, предоставляющий UI для подключения к сервису LNPP и вывода метрик производительности, полученных по сети.

Спецификация LNPP не накладывает строгих ограничений на реализацию сервиса и клиента. Однако, клиент и сервис должны для передачи данных использовать формат сообщений LNPP, чтобы понимать друг друга.

Схема коммуникации LNPP

Коммуникация между клиентом и сервисом LNPP происходит по принципу "запрос-ответ". Клиент, подключаясь, пишет серверу запрос. Сервер, получив и обработав запрос, посылает ответ, содержащий все метрики производительности, соответствующие запросу.

В модели OSI, LNPP занимает 7-й слой (приложение). На 4-м слою (транспортном) коммуникация предусмотрена только по UDP. Порт UDP предусмотрен любой, но любая программа LNPP должна реализовывать по умолчанию прослушивание и подключение на порту 3361.

LNPP — двоичный протокол, передающий данные как последовательность октетов (нежели строки, как, например, в HTTP). Большинство последовательностей октетов призваны кодировать произвольные числа фиксированного размера.

В спецификации введены обозначения для целых чисел фиксированного размера, но произвольного значения. Например:

uint64 = 8%x00-FF
uint16 = 2%x00-FF
uint8 = %x00-FF

Формат сообщений LNPP

По направлению, в LNPP сообщения различают на запросы и ответы.

Запрос
Сообщение, направленное от клиента к серверу.
Ответ
Сообщение, направленное от сервера к клиенту.

Сервер всегда отправляет по одному ответу на каждый запрос. Чтобы можно было отследить связь между отправленным запросом и полученным ответом, особенно в условии асинхронной отправки/получения UDP пакетов на стороне клиента, используется ID транзакции:

lnpp-message = transaction-id (lnpp-request / lnpp-response)
transaction-id = uint8

По типу данных, в LNPP различают 6 типов сообщений, для каждого из которых предусмотрены запросы и ответы:

message-type-discovery = %x00
message-type-cpu = %x01
message-type-memory = %x02
message-type-fs = %x03
message-type-blockdev = %x04
message-type-netif = %x05
Discovery
Запрос и выдача информации обо всех устройствах, измеряемых сервером LNPP.
CPU
Запрос и выдача информации о рабочем времени ядер CPU на сервере.
Memory
Запрос и выдача информации об использовании оперативной памяти на сервере.
FS
Запрос и выдача информации о вместимости файловой системы на определённой точке монтирования на сервере.
Blockdev
Запрос и выдача информации о вводе/выводе определённого блочного устройства на сервере.
Netif
Запрос и выдача информации о вводе/выводе определённого сетевого интерфейса на сервере.

Сообщения типа Discovery

Запрос

lnpp-request /= discovery-request
discovery-request = message-type-discovery

Ответ

lnpp-response /= discovery-response
discovery-response = message-type-discovery
 cpu-amount
 memory-available
 mountpoints
 blockdevs
 netifs
cpu-amount = %x00-20 %x00-FF
memory-available = true / false
true = %x01
false = %x00
mountpoints = mountpoints-amount *mountpoint
mountpoints-amount = uint8
mountpoint = mountpoint-length *uint8
mountpoint-length = %x00-0F %x00-FF
blockdevs = blockdevs-amount *blockdev
blockdevs-amount = uint8
blockdev = blockdev-length *uint8
blockdev-length = uint8
netifs = netifs-amount *netif
netifs-amount = uint8
netif = netif-length *uint8
netif-length = %x00-0F

Семантика

cpu-amount
Количество ядер CPU на сервере LNPP. Если сервер не измеряет процессорное время, то выражение принимает значение 0. Максимальное количество ядер в системе — 8192.
memory-available
true если сервер LNPP измеряет оперативную память, false если нет.
mountpoint
Строка байт, префикснутая собственной длиной. Максимальная длина — 4095 байт.
blockdev
Строка байт, префикснутая собственной длиной. Максимальная длина — 255 байт.
netif
Строка байт, префикснутая собственной длиной. Максимальная длина — 15 байт1 .

Ограничения

  • В выражении mountpoints, выражение mountpoint повторяется ровно mountpoints-amount раз.

  • В выражении mountpoint, выражение uint8 повторяется ровно mountpoint-length раз.

  • В выражении blockdevs, выражение blockdev повторяется ровно blockdevs-amount раз.

  • В выражении blockdev, выражение uint8 повторяется ровно blockdev-length раз.

  • В выражении netifs, выражение netif повторяется ровно netifs-amount раз.

  • В выражении netif, выражение uint8 повторяется ровно netif-length раз.

Сообщения типа CPU

Запрос

lnpp-request /= cpu-request
cpu-request = message-type-cpu cpu-number
cpu-number = cpu-all-core-sum / (%x00-1F %x00-FF)
cpu-all-core-sum = %x20 %x00

Семантика

cpu-number
Выбранное ядро CPU, которое опрашивает клиент. Если выражение принимает значение cpu-all-core-sum, сервер вернёт суммарную статистику по всем ядрам CPU. Счёт ядер ведётся, начиная с нуля. Максимальный номер ядра — 8191.

Ответ

lnpp-response /= cpu-response
cpu-response = message-type-cpu stat-response-ok timestamp cpu-stats
 / message-type-cpu stat-response-device-not-found
 / message-type-cpu stat-response-system-error timestamp errno
stat-response-ok = %x00
stat-response-device-not-found = %x01
stat-response-system-error = %x02
timestamp = uint64
errno = uint8
cpu-stats = cpu-cycles-user cpu-cycles-system cpu-cycles-idle
cpu-cycles-user = uint64
cpu-cycles-system = uint64
cpu-cycles-idle = uint64

Семантика

Общие выражения для всех дальнейших типов сообщений:

stat-response-ok
Сервер возвращает успешно измеренные данные о производительности.
stat-response-device-not-found
Сервер не измеряет устройство, указанное в запросе.
stat-response-system-error
Сервер возвращает код ошибки с последней неудачной попытки измерить производительность устройства.
timestamp
Время в секундах, прошедшее с момента запуска ОС, на которой запущен сервер, до момента взятия приведённого в ответе измерения производительности.
errno
Код системной ошибки, соответствующий стандарту POSIX (р. 2.3).

Выражения, специфичные для данного типа сообщений:

cpu-cycles-user
Количество циклов CPU, использованных для выполнения пользовательских программ, посчитанное с момента запуска системы.
cpu-cycles-system
Количество циклов CPU, использованных для выполнения ядра ОС, посчитанное с момента запуска системы.
cpu-cycles-idle
Количество циклов CPU, проведённых в бездействии, посчитанное с момента запуска системы.

Ограничения

Общие ограничения для всех дальнейших типов сообщений:

  • Выражение errno может принимать исключительно значения, описанные в POSIX (р. 2.3).

Сообщения типа Memory

Запрос

lnpp-request /= memory-request
memory-request = message-type-memory memory-device
memory-device = ram / swap
ram = %x00
swap = %x01

Семантика

ram
Клиент опрашивает статистику использования памяти произвольного доступа (RAM).
swap
Клиент опрашивает статистику использования подкачки (Swap).

Ответ

lnpp-response /= memory-response
memory-response = message-type-memory stat-response-ok timestamp memory-stats
 / message-type-memory stat-response-device-not-found
 / message-type-memory stat-response-system-error timestamp errno
memory-stats = memory-total memory-cached memory-free
memory-total = uint64
memory-cached = uint64
memory-free = uint64

Семантика

Все числовые значения даны в kB.

memory-total
Объём общей памяти, доступной всей ОС.
memory-cached
Объём кэшированной памяти.
memory-free
Объём свободной памяти, ещё ни как не использованной ОС.

Сообщения типа FS

Запрос

lnpp-request /= fs-request
fs-request = message-type-fs mountpoint

Ответ

lnpp-response /= fs-response
fs-response = message-type-fs stat-response-ok timestamp fs-stats
 / message-type-fs stat-response-device-not-found
 / message-type-fs stat-response-system-error timestamp errno
fs-stats = fs-used fs-total
fs-used = uint64
fs-total = uint64

Семантика

Все числовые значения даны в байтах.

fs-used
Использованный объём файловой системы, монтированной на mountpoint.
fs-total
Использованное + свободное пространство в файловой системе, монтированной на mountpoint.

Сообщения типа Blockdev

Запрос

lnpp-request /= blockdev-request
blockdev-request = message-type-blockdev blockdev

Ответ

lnpp-response /= blockdev-response
blockdev-response = message-type-blockdev stat-response-ok timestamp blockdev-stats
 / message-type-blockdev stat-response-device-not-found
 / message-type-blockdev stat-response-system-error timestamp errno
blockdev-stats = blockdev-read blockdev-write
blockdev-read = uint64
blockdev-write = uint64

Семантика

Все числовые значения даны в байтах.

blockdev-read
Объём прочитанных данных из блочного устройства.
blockdev-write
Объём записанных данных в блочное устройство.

Сообщения типа Netif

Запрос

lnpp-request /= netif-request
netif-request = message-type-netif netif

Ответ

lnpp-response /= netif-response
netif-response = message-type-netif stat-response-ok timestamp netif-stats
 / message-type-netif stat-response-device-not-found
 / message-type-netif stat-response-system-error timestamp errno
netif-stats = netif-rx netif-tx
netif-rx = uint64
netif-tx = uint64

Семантика

Все числовые значения даны в байтах.

blockdev-read
Объём полученных данных с помощью сетевого интерфейса.
blockdev-write
Объём отправленных данных с помощью сетевого интерфейса.

Рекомендации безопасности

Спецификация LNPP не предусматривает встроенного шифрования данных. Предполагается, что безопасность обмена данными между клиентом и сервером LNPP обеспечивается сторонними средствами: работа сервера только в локальной сети, DTLS и т. д.