| architecture.svg | Updated vector drawings | |
| flow-graph.svg | Updated vector drawings | |
| README.md | Added source for the netif length | |
Создана: 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 — это непрерывный процесс (демон) под управлением ОС Linux, ответственный за хранение и периодическое обновление метрик производительности, а также за передачу этих метрик клиентам, подключившимся по сети. Клиент LNPP — это процесс, предоставляющий UI для подключения к сервису 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-availabletrueесли сервер 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 и т. д.