Настройка Grafana Live
Grafana Live — это движок обмена сообщениями в реальном времени, который можно использовать для отправки данных о событиях во фронтенд сразу после того, как событие произошло.
Это могут быть уведомления об изменениях дашборда, новые кадры для отображаемых данных и так далее. Возможности Live помогают во многих местах исключить перезагрузку страницы или опрос (polling), они позволяют передавать в панели показания датчиков Интернета вещей (IoT) или любые другие данные в реальном времени.
Note
Под
real-timeмы подразумеваем мягкий режим реального времени (soft real-time). Из-за сетевых задержек, циклов сборки мусора и так далее задержка доставки сообщения может составлять до нескольких сотен миллисекунд или больше.
Концепции
Grafana Live отправляет данные клиентам через постоянные WebSocket-соединения на основе модели Pub/Sub. Фронтенд Grafana подписывается на каждом канале, чтобы получать данные, опубликованные в этом канале. Все подписки на странице мультиплексируются в одном WebSocket-соединении. Существуют некоторые правила именования каналов Live — см. Канал Grafana Live.
Обработка постоянных соединений, таких как WebSocket, в масштабе может потребовать настройки операционной системы и инфраструктуры. Поэтому по умолчанию Grafana Live поддерживает максимум 100 одновременных соединений. Более подробно о том, как настроить этот лимит, см. в разделе Раздел конфигурации Live.
Возможности
Наличие способа отправлять данные клиентам в реальном времени открывает путь к новым способам взаимодействия с данными и их визуализации. Ниже описаны возможности Grafana Live, поддерживаемые в настоящее время.
Уведомления об изменениях дашборда
Как только происходит изменение компоновки дашборда, оно автоматически отражается на других устройствах, подключённых к Grafana Live.
Потоковая передача данных из плагинов
С помощью Grafana Live серверные плагины источников данных могут передавать обновления в панели фронтенда.
Для каналов плагинов источников данных Grafana использует область (scope) ds. Пространством имён в случае каналов источников данных является уникальный ID источника данных (UID), который выдаётся Grafana в момент создания источника данных. Путь — это произвольная строка, которую авторы плагинов могут выбрать самостоятельно (только убедитесь, что она состоит из допустимых символов).
Например, канал источника данных выглядит так: ds/<DATASOURCE_UID>/<CUSTOM_PATH>.
Дополнительные сведения см. в руководстве о создании серверного плагина источника данных с потоковой передачей.
Базовый пример потоковой передачи, входящий в ядро Grafana, передаёт кадры с некоторыми сгенерированными данными в панель. Чтобы посмотреть его, создайте новую панель и укажите для неё источник данных -- Grafana --. Затем выберите Live Measurements и выберите канал plugin/testdata/random-20Hz-stream.
Потоковая передача данных из Telegraf
Новая конечная точка API /api/live/push/:streamId позволяет принимать данные метрик в формате line protocol InfluxDB от Telegraf. Эти метрики преобразуются в кадры данных Grafana и публикуются в каналы.
Важно: При потоковой передаче данных из Telegraf убедитесь, что:
- Формат данных в вашей конфигурации Telegraf установлен в
influx - Метки времени указаны в наносекундах (время Unix epoch)
Дополнительную информацию см. в руководстве о потоковой передаче метрик из Telegraf в Grafana.
Канал Grafana Live
Grafana Live — это сервер PUB/SUB, клиенты подписываются на каналы, чтобы получать обновления в реальном времени, публикуемые в этих каналах.
Структура канала
Канал — это строковый идентификатор. В Grafana канал состоит из 3 частей, разделённых /:
- Область (scope)
- Пространство имён (namespace)
- Путь (path)
Например, канал grafana/dashboard/xyz имеет область grafana, пространство имён dashboard и путь xyz.
Область, пространство имён и путь в настоящее время могут содержать только буквенно-цифровые символы ASCII (A-Z, a-z, 0-9), _ (подчёркивание) и - (дефис). Часть пути дополнительно может содержать символы /, . и =. Значение области, пространства имён и пути зависит от контекста.
Максимальная длина канала — 160 символов.
Область определяет назначение канала в Grafana. Например, для каналов плагинов источников данных Grafana использует область ds. Для встроенных возможностей, таких как уведомления о редактировании дашборда, Grafana использует область grafana.
Пространство имён имеет разное значение в зависимости от области. Например, для области grafana это может быть имя встроенной возможности реального времени, такой как dashboard (то есть события дашбордов).
Путь, который является последней частью канала, обычно содержит идентификатор какого-то конкретного ресурса, например ID дашборда, который пользователь просматривает в данный момент. Но путь может быть любым.
Каналы являются лёгкими и эфемерными — они создаются автоматически при подписке пользователя и удаляются, как только последний пользователь покидает канал.
Формат данных
Данные, передаваемые по каналам Live, поддерживают несколько форматов в зависимости от конечной точки:
Каналы WebSocket
Данные, передаваемые через каналы WebSocket для потоковой передачи в реальном времени клиентам фронтенда, должны быть закодированы в JSON. Это относится к:
- Уведомлениям об изменениях дашборда
- Потоковой передаче плагинов источников данных (каналы области
ds) - Пользовательским каналам приложений
HTTP Push API
Конечная точка /api/live/push/:streamId принимает данные метрик в формате line protocol InfluxDB. Это особенно полезно для потоковой передачи метрик из таких инструментов, как Telegraf.
Формат line protocol имеет следующую структуру:
<measurement>[,<tag_key>=<tag_value>[,<tag_key>=<tag_value>]] <field_key>=<field_value>[,<field_key>=<field_value>] [<timestamp>]
Важно: Метки времени должны быть закодированы в наносекундах (время Unix epoch в наносекундах).
Пример:
temperature,location=room1,sensor=A temp_celsius=23.5,humidity=45 1651498849000000000
В этом примере:
temperature— это имя измерения (measurement)location=room1иsensor=A— это тегиtemp_celsius=23.5иhumidity=45— это поля1651498849000000000— это метка времени в наносекундах
Когда данные поступают через HTTP Push API, они автоматически преобразуются в кадры данных Grafana и публикуются в соответствующие каналы для визуализации.
Дополнительную информацию о формате line protocol InfluxDB см. в документации по line protocol InfluxDB.
Настройка Grafana Live
Grafana Live включён по умолчанию. В Grafana v8.0 действует строгое значение по умолчанию для максимального числа соединений на один экземпляр сервера Grafana.
Максимальное число соединений
Grafana Live использует постоянные соединения (в настоящее время WebSocket) для доставки обновлений в реальном времени клиентам.
WebSocket — это постоянное соединение, которое начинается с запроса HTTP Upgrade (используя тот же порт HTTP, что и остальная часть Grafana), а затем переключается в режим TCP, в котором кадры WebSocket могут передаваться в обоих направлениях между клиентом и сервером. Каждый вошедший в систему пользователь открывает одно WebSocket-соединение — по одному на вкладку браузера.
Количество максимальных WebSocket-соединений, которые пользователи могут установить с Grafana, по умолчанию ограничено 100. См. параметр max_connections.
Если вы хотите увеличить этот лимит, убедитесь, что ваш сервер и инфраструктура позволяют обрабатывать больше соединений. В следующих разделах рассматриваются несколько распространённых проблем, которые могут возникнуть при управлении постоянными соединениями, в частности соединениями WebSocket.
Проверка источника запроса
Чтобы избежать перехвата WebSocket-соединения, Grafana Live проверяет заголовок запроса Origin, отправленный клиентом в запросе HTTP Upgrade. Запросы без заголовка Origin проходят без какой-либо проверки источника.
По умолчанию Live принимает соединения с заголовком Origin, который соответствует настроенному root_url (который является публичным URL Grafana).
Можно предоставить список дополнительных шаблонов Origin, с которых разрешены WebSocket-соединения. Это можно сделать с помощью параметра allowed_origins конфигурации Grafana Live.
Использование ресурсов
Каждое постоянное соединение занимает некоторый объём памяти на сервере. Обычно на данный момент это около 50 КБ на соединение. Таким образом, сервер с 1 ГБ ОЗУ, как ожидается, сможет обрабатывать максимум около 20 тыс. соединений. Каждое активное соединение потребляет дополнительные ресурсы ЦП, поскольку клиент и сервер отправляют друг другу кадры PING/PONG для поддержания соединения.
Использование функциональности потоковой передачи приводит к дополнительному расходу ЦП. Точную загрузку ресурсов ЦП сложно оценить, поскольку она сильно зависит от характера использования Grafana Live.
Лимит открытых файлов
Каждое WebSocket-соединение занимает файловый дескриптор на серверной машине, где работает Grafana. В большинстве операционных систем довольно низкий лимит по умолчанию для максимального количества дескрипторов, которые может открыть процесс.
Чтобы посмотреть текущий лимит в Unix, выполните:
ulimit -n
В системе Linux вы также можете проверить текущие лимиты для работающего процесса с помощью:
cat /proc/<PROCESS_PID>/limits
Лимит открытых файлов показывает приблизительно, сколько пользовательских соединений ваш сервер может обрабатывать в данный момент.
Чтобы увеличить этот лимит, обратитесь к этим инструкциям для популярных операционных систем.
Исчерпание эфемерных портов
Проблема исчерпания эфемерных портов может возникнуть между вашим балансировщиком нагрузки (или обратным прокси) и сервером Grafana. Например, когда вы балансируете запросы/соединения между разными экземплярами Grafana. Если вы подключаетесь напрямую к одному экземпляру сервера Grafana, то с этой проблемой вы столкнуться не должны.
Проблема возникает потому, что каждое TCP-соединение однозначно идентифицируется в ОС по кортежу из 4 частей:
source ip | source port | destination ip | destination port
По умолчанию на границе балансировщика нагрузки/сервера вы ограничены 65535 возможными вариантами. Но фактически из-за некоторых ограничений ОС (например, в Unix доступные порты определяются параметром sysctl ip_local_port_range) и сокетов в состоянии TIME_WAIT это число ещё меньше.
Чтобы устранить проблему, вы можете:
- Увеличить диапазон эфемерных портов, настроив параметр ядра
ip_local_port_range. - Развернуть больше экземпляров сервера Grafana для балансировки между ними.
- Развернуть больше экземпляров балансировщика нагрузки.
- Использовать виртуальные сетевые интерфейсы.
WebSocket и прокси
Не все прокси могут по умолчанию прозрачно проксировать WebSocket-соединения. Например, если вы используете Nginx перед Grafana, вам нужно настроить прокси WebSocket следующим образом:
http {
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream grafana {
server 127.0.0.1:3000;
}
server {
listen 8000;
location / {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $http_host;
proxy_pass http://grafana;
}
}
}
Дополнительные сведения см. в блоге Nginx на их сайте. Также обратитесь к документации вашего балансировщика нагрузки/обратного прокси, чтобы узнать больше о работе с WebSocket-соединениями.
Некоторые корпоративные прокси могут удалять заголовки, необходимые для правильного установления WebSocket-соединения. В этом случае следует настроить промежуточные прокси так, чтобы они не удаляли необходимые заголовки. Однако лучший вариант — использовать Grafana с TLS. Тогда WebSocket-соединение унаследует TLS и, таким образом, должно обрабатываться прокси прозрачно.
У таких прокси, как Nginx и Envoy, есть лимиты по умолчанию на максимальное количество соединений, которые можно установить. Убедитесь, что в конфигурации вашего прокси установлен разумный лимит на максимальное число входящих и исходящих соединений.
Настройка конфигурации Grafana Live HA
По умолчанию Grafana Live использует структуры данных в памяти и хаб PUB/SUB в памяти для обработки подписок.
В конфигурации Grafana с высокой доступностью, включающей несколько экземпляров сервера Grafana за балансировщиком нагрузки, вы можете столкнуться со следующими ограничениями:
- Встроенные возможности, такие как уведомления об изменениях дашборда, будут транслироваться только пользователям, подключённым к тому же экземпляру процесса сервера Grafana.
- Потоковая передача из Telegraf будет доставлять данные только клиентам, подключённым к тому же экземпляру, который получил данные Telegraf; кэш активных потоков не является общим для разных экземпляров Grafana.
- Отдельный однонаправленный поток между Grafana и серверным источником данных может быть открыт на разных серверах Grafana для одного и того же канала.
Чтобы обойти эти ограничения, в Grafana есть движок Live HA, для работы которого требуется Redis.
Настройка движка Redis Live
Когда движок Redis настроен, Grafana Live хранит своё состояние в Redis и использует функциональность Redis PUB/SUB для доставки сообщений всем подписчикам на всех узлах сервера Grafana.
Вот пример конфигурации:
[live]
ha_engine = redis
ha_engine_address = 127.0.0.1:6379
Дополнительную информацию см. в параметрах ha_engine и ha_engine_address.
После запуска:
- Все встроенные уведомления в реальном времени, такие как изменения дашборда, доставляются всем экземплярам сервера Grafana и транслируются всем подписчикам.
- Потоковая передача из Telegraf доставляет сообщения всем подписчикам.
- Отдельный однонаправленный поток между Grafana и серверным источником данных открывается на разных серверах Grafana. Публикация данных в канал доставляет сообщения подписчикам экземпляра, в результате чего публикации из разных экземпляров на разных машинах не создают дублирующихся данных на панелях.
Note
В настоящее время Live не поддерживает Redis Sentinel. Мы рекомендуем использовать Redis Cluster для высокой доступности через helm-чарт для k8s, например чарт Bitnami Redis, в котором есть значения для развёртывания Redis Cluster. Затем Grafana Live можно направить на службу
redis-headless.live: ha_engine: redis ha_engine_address: redis-headless.grafana.svc.cluster.local:6379 ha_engine_password: $__file{/your/redis/password/secret/mount}
Чтобы подключиться к Redis по TLS, используйте URL-адрес соединения rediss:// в качестве адреса движка:
[live]
ha_engine = redis
ha_engine_address = rediss://redis.example.com:6380
Схема redis:// также поддерживается. Обе схемы принимают учётные данные и номер базы данных в URL, например redis://username:password@localhost:6379/0. Пароль, заданный в URL (даже явно пустой), имеет приоритет; ha_engine_password применяется, когда в URL пароль не задан. Grafana проверяет сертификаты сервера по доверенным центрам сертификации операционной системы; отключить проверку с помощью этого параметра нельзя.