Русский
Русский
English
Статистика
Реклама

Мониторинг

Когда без выделенного DevOps уже никуда. Кейс компании Geecko

18.05.2021 18:11:11 | Автор: admin


SberCraft, CyberCode, Luxcity возможно, вы слышали об этих играх или даже участвовали в них. Всё это Geecko рук дело. Самые крупные проекты Geecko собирают по 20 тыс. игроков, при этом до недавних пор в компании не было выделенной команды для поддержки инфраструктуры.

СТО компании Никита Обухов и директор по маркетингу Ирина Фёдорова рассказали об инциденте, который стал одним из аргументов всерьёз задуматься об инфраструктурных переменах, переезде на K8s и найме команды DevOps.

Что внутри:

  • потеря контроля над Facebook,
  • внезапный наплыв трафика в пятницу вечером,
  • грант от Microsoft Azure, переезд между облаками и сложности трансформации.

Поехали!

Geecko DevRel компания. Помогает выстраивать взаимоотношения IT-компаний с разработчиками, но делает это необычными способами: создаёт игры с задачами для программистов, кодинг баттлы, организует митапы и другие онлайн-форматы.

Что под капотом у игр Geecko


На каком движке сделаны игры, что они из себя представляют технически?

Никита: Наши игры исключительно браузерные. Мы используем собственные наработки и проверенные библиотеки для работы с Canvas, картами, изометрией. Используем JS/TS, фреймворк Vue.js для типичного web UI.

Под мобильные платформы мы пока не пишем в лучшем случае поддерживаем мобильную разрешения. Но это нужно нечасто в большинстве наших игр требуется писать код, а писать код с мобилы такое себе удобство.

Насколько игры требовательны к CPU и памяти?

Никита: В наших играх требуется писать код, и нам этот код надо исполнять.

Мы поддерживаем 12 языков: и компилируемые, и интерпретируемые в разных средах. Код исполняем на наших серверных ресурсах: нагрузка на процессор и память интенсивная.

Также мы запускаем LSP-сервисы, которые обеспечивают autocomplete кода для нашей онлайн IDE. Они тоже требуют CPU и особенно памяти: когда игроков много, нагрузка значительно растёт.

Где хостятся игры?

Никита: Это всегда были облака. Сейчас основной провайдер Azure (Geecko получила грант от Microsoft на бесплатное использование облака ред.). Все новые проекты мы запускаем там и, что для нас важно, запускаем в Kubernetes. Вся новая инфраструктура на основе Kubernetes и Docker.

У какого провайдера вы были до и почему решили перейти?

Никита: Мы были и до сих пор представлены и в DigitalOcean, и в Yandex.Cloud. Это хорошие провайдеры, но наиболее подходящая программа гранта для нас оказалась у Microsoft.

Сколько вы тратили на серверы раньше и тратить теперь?

Никита: Ещё полгода назад мы тратили около 30 тысяч рублей в месяц, сейчас эта цифра подбирается к 100 тысячам. Рост связан с количеством проектов: старые мы не останавливаем, они продолжают работать и получать органические регистрации. Регулярно запускаем новые активности: в один месяц можем зарелизить три проекта например, один баттл, одну игру и митап.

Грант от Microsoft покрывает все расходы?

Никита: Наши расходы на инфраструктуру не стали нулевыми: мы не можем перевезти всё за раз, это и экономически нецелесообразно. Поэтому у нас продолжает работать еще два облачных провайдера, просто их доля сокращается.

Бэкапы в других географических зонах, аварийное восстановление ресурсов в другом облаке всё это важно.

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


Скриншот из игры Cybercode

Пятничный наплыв трафика из Facebook


У вас были ситуации, когда наплыв пользователей ронял продакшн?

Никита: Да, однажды случился близкий к этому инцидент. У нас была задача от международной компании: найти много англоязычных разработчиков.

По замыслу игроки должны коллективно выполнить миссию, находясь на одной карте. Карта имеет конечные размеры, так что расположить на ней всех желающих нельзя. Мы делили пользователей на кластеры по 100 человек, каждый из которых живёт не больше пяти дней таков игровой цикл выполнения миссии. За это время участники либо выигрывают, либо проигрывают.

Мы рассчитывали, что одновременно будут активны до 10 таких карт, то есть до 1000 игроков. Но по факту на пике было больше 2000 игроков или 20 карт.

Почему так произошло? Почему в игру внезапно пришло столько пользователей?

Ирина: История случилась в начале марта, когда Facebook стал массово и стихийно блокировать рекламные кабинеты за несоответствие политике для рекламодателей. Очень многие компании тогда лишились рекламных кабинетов, в том числе и мы: у нас упали и основной, и оба резервных кабинета. И всё это как раз в тот момент, когда нам надо было продвигать игру.

Facebook один из основных каналов продвижения, потому что там достаточно легко подбирать аудиторию и сегментировать её с учетом имеющихся данных. И на целых 12 дней мы лишились доступа к этому каналу. Когда же мы потом, кровью и слезами его вернули, нам нужно было догнать KPI 4500 ликвидных регистраций по определённым геолокациям, в основном в Европе.

Не было никакого выбора, кроме как поднажать с бюджетом: мы подразогнали рекламные кампании.

Что значит поднажать с бюджетом?

Ирина: Если мы изначально тратили 300500 долларов в день, то тут перешли за 1000.

Надо понимать, что обычно рекламные кампании несколько дней обучаются, а потом начинают работать максимально профитно. Но у нас рекламный бюджет был больше обычного, поэтому кампания обучилась быстрее и уже на второй день начала откручивать действительно очень крутые показатели. В какой-то момент мы потеряли над ней контроль.

Мы рассчитывали на определённый коэффициент конверсии, а он оказался больше просто за счёт того, что Facebook разогнался. Если в среднем у нас конверсия в таких играх около 8%, то здесь в пиковый момент она дошла до 15%.

Круто!

Ирина: Да, тут-то мы и поняли, что значит большой рекламный бюджет. Правда, работает это только в случае с Западом в России просто нет аудитории, чтобы потратить столько денег.

Ну и, конечно же, всё это произошло в пятницу. Классика! В пятницу вечером мне приходит сообщение от Никиты, что у нас такой большой трафик, что нужно что-то с этим сделать.

Откуда Никита об этом узнал? Откуда пришел этот сигнал?

Никита: У нас есть автоматические оповещения о загрузке серверов. Вот как оно выглядело:



Приходит алерт, что виртуальная машина (8 ядер, 32 ГБ памяти) загружена на 90% по CPU при пороговом значении 50%.

Это не критично, так как сервис продолжает работу. Для игроков это значит, что они нажимают кнопку Запустить код и ждут выполнения раза в два дольше. Но также это значит, что если новые игроки продолжат приходить, ситуация ухудшится, вплоть до даунтайма.

В итоге самого плохого исхода удалось избежать сервис не лёг окончательно?

Никита: К счастью, все закончилось хорошо.

Конечно, если бы ситуация возникла в середине рабочего дня, мы бы вообще не переживали там можно оперативно реагировать. Но не в пятницу вечером. В пятницу вечером ты отправляешься в бар и получаешь такое сообщение на телефон. Но чтобы всё починить, на телефоне быть недостаточно.

Как вы разрулили ситуацию?

Ирина: Мы просто снизили расход рекламных кампаний почти на 70%.

Позже вы вернули обороты?

Ирина: Нет, до того же состояния не стали доводить, потому что ситуация была непредсказуемая: Facebook с каждым днём наращивал и наращивал конверсию. Если бы мы крутили на тех же оборотах ещё неделю, возможно, конверсия была бы ещё выше. Но героических побед не требовалось, поэтому мы восстановили комфортный уровень. Получалось где-то 10 загруженных карт, и при этом сервис работал спокойно.

Никита: Надо отметить, что есть и другие стороны вопроса: мы стараемся оперативно реагировать на сообщения игроков. Чем больше игроков, тем больше запросов в поддержку они генерируют. Мы хотели сохранить высокий уровень сервиса, и так спешно нарастить объёмы поддержки были не готовы. Решили, что разумнее делать всё более плавно и прогнозируемо, чем выходить на пик в выходные.

В этот раз вы решили придушить рекламную кампанию и тем самым спасли ситуацию. А как вы обычно решаете задачу с масштабированием с технической точки зрения?

Никита: Мы масштабируемся через запуск дополнительных инстансов сервиса.

В данном случае это не Kubernetes и нет автоскейла. Надо в полуручном режиме запустить клон виртуальной машины приходится подождать до получаса, пока ВМ воссоздастся из образа. После этого надо проверить, что ВМ работает как ожидается и все сервисы на ней поднялись: LSP-серверы, код-раннеры. После этого балансируем трафик на новые машины и продолжаем наблюдать за загруженностью и статус-кодами.


Скриншот из игры SberCraft

Выводы и планы


Как вы перестроили работу после этого случая?

Никита: Поняли, как лучше планировать маркетинг: какой объем вложений какой объем регистраций даёт.

На техническом уровне укрепились во мнении, что нам нужен новый способ масштабирования сервиса исполнения кода, в идеале автоскейл.

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

Но в случае с сервисом исполнения кода схема более сложная перевести его не так просто, как остальные. Мы пока проверяем, что всё работает как надо.

Прямо сейчас код выполняется в DigitalOcean, а будет выполняться в облаке Azure. В Kubernetes.

Там вы используете Kubernetes как сервис (Azure Kubernetes Service)?

Никита: Да. Мы используем Kubernetes как сервис и ещё рассматриваем вариант Cloud Functions.

Как AWS Lambda?

Никита: Да, у всех основных провайдеров они есть. Они позволяют платить ровно столько, сколько ты делаешь запусков кода. Но есть технические ограничения в возможностях сред выполнения.

Кто сейчас занимается инфраструктурой?

Никита: Моей квалификации и квалификации бэкенд-разработчиков не всегда хватает, потому что DevOps, SRE это очень широкая область. Да и оставлять на дежурство по инцидентам бэкенд-разработчиков не очень правильно. Поэтому в начале года у нас появилась аутсорс-команда DevOps ребята, с которыми мы раньше работали в других бизнесах.

Почему вы начали сотрудничать с командой, которая занимается инфраструктурой и DevOps?

Никита: Инцидент с игрой стал катализатором изменений, которые мы давно осознавали, но не имели возможности воплотить.

Компания выросла, стали происходить подобные случаи, которые подтверждали: да, ребята, вам нужны DevOps-инженеры, вам нужно сделать такую инфраструктуру, которую будет проще масштабировать.

Полноценно задачей занялись два месяца назад, когда получили грант от Azure. К настоящему моменту много сервисов перевезли в новое облако.

Почему решили брать людей на аутсорс, а не нанимать?

Никита: По собственному опыту знаем, что DevOps сложное направление для найма. А тут сложилось так, что есть проверенные ребята, и форма работы с подрядчиком для нас весьма удобна.

Ну и главное: мы приобрели не одного инженера, а целую команду, которая круглосуточно мониторит доступность сервисов и готова прореагировать на инцидент до того, как он будет обнаружен пользователями.

Команда DevOps настраивают всё с нуля или используют то, что было, включая мониторинг?

Никита: Мы пошли по пути вытеснения. Новые проекты начинаем в новой инфраструктуре, core-сервисы мигрируем туда же, а проекты в стадии поддержки оставляем в старой. Для новых проектов все новое, включая мониторинг.

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

Поэтому работа происходит и на стороне бэкенда: мы рефакторим код, обновляем архитектуру, но в достаточно умеренном объеме.

Получается, вы сейчас настраиваете новые процессы CI/CD?

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

Процессы CI/CD у нас были, просто они стали перекатываться на новую инфраструктуру. Конечно, они совершенствуются, но принципиально не меняются.


Скриншот из игры SberCraft

Какой глобальный вывод вы для себя сделали?

На разных этапах жизни проекта хорошо разное. Полгода назад к DevOps-команде мы были бы и сами не готовы. Зато сейчас можем общаться с ними гораздо предметнее. Мы чётко понимаем свои боли и пришли к ребятам со списком вопросов и предложений, как что-то сделать. Получилась хорошая коллаборация: совместно мы пришли к качественным и обоснованным решениям.

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

Так повелось, что в большинстве компаний задумываются над инфраструктурными вопросами уже после разработки продукта. Можно считать этот подход единственно верным, а можно поступить иначе.

Например, ещё на этапе разработки отправить ребят из бэкенда посмотреть на то, какие метрики стоит навесить и как спланировать пайплайн, чтобы в продакшене было не так больно.

21 мая в Слёрме стартует интенсив как раз для тех, кто планирует или уже поддерживает высоконагруженные системы.

В программе:
мониторинг,
управление инцидентами,
решение проблем с окружением,
решение проблем с инфраструктурой,
канареечные релизы и управление трафиком.

Интенсив подготовили и проведут опытные инженеры из Databricks, Mail.ru Cloud Solutions и TangoMe.

Узнать больше и записаться
Подробнее..

Мониторинг эксплойтов

08.04.2021 18:23:51 | Автор: admin

В прошлой статье мы собрали данные для того чтобы мониторить эксплуатацию уязвимости в Windows Server, который имеет роль контроллера домена. В этой статье мы попытаемся понять есть ли возможность мониторить остальные классы эксплойтов с помощью инструментов ELK, Zabbix или Prometheus.

Классификация эксплойтов с точки зрения мониторинга

Уязвимость - несовершенство программного обеспечения. В простом случае это причина почему приложение не может выполнить свою задачу и завершает работу аварийно.

Можно ли все уязвимости отследить? Попробуем собрать факты воедино. Факт 1 уязвимости с точки зрения их использования для достижения целей компрометации или вывода из строя информационной системы можно условно поделить на:

  1. Уязвимости приводящие к аварийному завершению работы приложения

  2. Уязвимости позволяющие запустить дополнительные команды в уязвимой системе

Стоит отметить, что для обеих групп мы можем мониторить только последствия или зависимые события.

Первая группа уязвимостей достаточно просто мониторится системами ELK, Zabbix и Prometheus. Недоступность пострадавшей системы тут же будет выведено на общий мониторинг.

Не так всё просто со вторым типом. Дело в том, что именно эти уязвимости имеют довольно большое количество вариаций. И как правило связаны с теми подсистемами, где важен порядок и скорость действий системы. В эти подсистемы очень сложно добавить механизмы снятия информации для мониторинга.

чтобы понять насколько много этих уязвимостей их список по популярности появления в программном обеспечении можно найти здесь.

Факт 2 - всего классов уязвимостей задокументировано - 699. Интересная цифра, но это тоже верхнеуровневая абстракция, на самом деле и у этих 699 уязвимостей тоже есть вариации.

Что особенного среди 699 групп уязвимостей? Особенность заключается в том, что большую часть этих уязвимостей в силу своей природы достаточно проблематично обнаружить. К примеру, группа CWE-120. Группа уязвимостей основной смысл которых заключается в том, что программист не верно рассчитал количество памяти, которое нужно было приложению для работы с определенным объектом. В результате у атакующего есть возможность влиять на заполнение памяти процесса. В ряде случаев это может привести к выполнению передаваемых злоумышленником команд.

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

Получается память для мониторинга недоступна? На самом деле это не так. Любая система мониторинга и даже логи операционных систем могут включать информацию о том как потребляется память приложениями. Можно эти данные наблюдать в режиме реального времени с помощью различного софта типа VMMap. Софт может показывать количество страниц памяти, которое используется, освобождается, резервируется и т.д. Что же это нам дает?

Ни одна уязвимость, которая была описана выше не может быть полезной для атакующего без специального метода её использования. У всех 699 групп есть свои способы и подходы, которые позволяют уязвимость использовать для выполнения команд. Иногда это отдельные паттерны программирования, иногда это набор последовательности функций, а иногда это просто список уязвимостей, которые используются в совокупности чтобы выполнить результирующую операцию. Поэтому для детектирования факта эксплуатации нам нужно:

  • понимать как работает эксплойт, идеально если будет исходный код

  • иметь возможность расширить набор событий в системных логах ОС

Тактика обнаружения на основании списка Mitre

Уязвимости сами по себе могут быть не видны на средствах мониторинга. При использовании возможностей только операционной системы. Иногда сами вендоры, видя популярность уязвимости могут создать отдельные события, которые помогают локализовать эксплуатацию уязвимости.

В случае с уязвимостью CVE-2020-1472 Microsoft добавила специальные события, которые генерируются, если система использует уязвимые алгоритмы. Нам же придется искать закономерности самостоятельно и использовать эти закономерности для мониторинга. Возможно даже придется прибегнуть к сторонним программным продуктам.

Для примера сбора таких закономерностей будем использовать эксплойт к уязвимости CVE-2020-0796. Основная проблема уязвимости - переполнение целочисленного элемента, который используется для контроля размера выделяемой приложением памяти. В сети можно найти 2 сценария использования уязвимости:

  1. Remote Code Execution

  2. Local Priveledge Escalation

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

Попробуем разобраться со второй. Проект на github предоставляет исходный код на языке программирования C++. Попробуем локализовать основные операциии, которые выполняет эксплойт.

Инициализация её код можно найти ниже:

Создается сокет на loopback интерфейсе и 445 порту. Далее эксплойт будет создавать в специальном формате пакет и отправит его на созданный сокет. Произойдет переполнение размера выделенной памяти в ядре ОС и код перетрёт память, которая относилась к primary токену основного процесса. С этими данными будет создан новый процесс cmd.exe. Как создается этот процесс? Эти данные можно найти в исходнике:

К сожалению, среди событий логов обнаружить ничего не удалось, так как все действия работали динамически в оперативной памяти и не задействовали стандартные механизмы получения доступа к объектам. Журнал "Security" тоже не будет содержать никакой информации. Что же делать? Есть 2 варианта:

  1. Использовать IDS для loopback интерфейса

  2. Использовать Endpoint защиту

Мы выберем 3-й путь. В ОС Windows есть возможность расширить список событий, которые будет генерировать система. Это возможно сделать с помощью инструмента SysMon. Чтобы инструмент мог генерировать нужные события, ему необходим конфиг, где и перечислены необходимые данные. Есть уже готовый. Причем если мы хотим поотслеживать события с loopback интерфейсом, нужно убрать следующие строки:

...<RuleGroup name="" groupRelation="or">        <NetworkConnect onmatch="exclude">            ...            <DestinationIp condition="is">127.0.0.1</DestinationIp> <==удалить            <DestinationIp condition="begin with">fe80:0:0:0</DestinationIp> <==удалить        </NetworkConnect>    </RuleGroup>...

Все данные по событиям выкладываются в системные журналы. Для Windows 10 можно использовать вот этот путь: Applications and Services Logs\Microsoft\Windows\Sysmon\Operational.

Для установки в систему конфига и Sysmon нужно набрать следующую команду:

sysmon.exe -accepteula -i sysmonconfig-export.xml

Запустим эксплойт и заглянем в лог Sysmon:

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

P.S. Для систем на базе Linux тоже скоро будет SysMon.

Подробнее..

1 CPU 1 Гб а я хочу мониторинг, как у больших дядей

10.05.2021 16:07:24 | Автор: admin


Я обожаю читать на хабре статьи про то, как устроены системы больших интернет-компаний. Кластеры SQL-серверов, монг и редисов. Тут у нас кластер ELK собирает трейсинг, там сборка логов, здесь балансер выдает входящим запросам traceID и можно отслеживать, как запрос ходит по всем нашим микросервисам. Класс. Но, допустим, у вас совсем маленький проект и вы можете себе позволить лишь VPS минимальной конфигурации. Реально ли на ней сделать мониторинг не хуже, чем у больших проектов? Я решил надо попробовать.


Создаем VPS


Сразу оговорюсь, что я ни разу не devops и не особо глубоко разбираюсь в Linux, поэтому, если что-то сделал неправильно, или у вас есть идеи, как можно было сделать то, что я делаю в этой статье проще и лучше пишите в комментариях, буду рад любым вашим советам и замечаниям!

Для экспериментов я создал на Маклауде VPS следующей конфигурации: 1 CPU, 1 Гб RAM и 20 Гб диск.


Для удобства я загрузил свой SSH ключ, и мог заходить в консоль сразу после запуска сервера. Также по умолчанию включено резервное копирование, я его отключил, так как в целях эксперимента мне оно было не нужно. Далее требовалось выбрать ОС. Для этого хотелось понять, какие ресурсы будут доступны на VPS сразу после создания. Меня интересовала свободная память и место на диске. Для этого, в панели управления можно инициировать переустановку ОС. Я поочередно установил доступные ОС и для каждой посмотрел, какие параметры она дает на старте:

CentOS 8:

[root@v54405 ~]# dfFilesystem     1K-blocks    Used Available Use% Mounted ondevtmpfs          406744       0    406744   0% /devtmpfs             420480       0    420480   0% /dev/shmtmpfs             420480    5636    414844   2% /runtmpfs             420480       0    420480   0% /sys/fs/cgroup/dev/vda1       20582864 1395760  18300472   8% /tmpfs              84096       0     84096   0% /run/user/0[root@v54405 ~]# free              total        used        free      shared  buff/cache   availableMem:         840960      106420      525884        5632      208656      600868Swap:             0           0           0


Debian 10

root@v54405:~# dfFilesystem     1K-blocks    Used Available Use% Mounted onudev              490584       0    490584   0% /devtmpfs             101092    1608     99484   2% /run/dev/vda1       20608592 1001560  18736224   6% /tmpfs             505448       0    505448   0% /dev/shmtmpfs               5120       0      5120   0% /run/locktmpfs             505448       0    505448   0% /sys/fs/cgrouptmpfs             101088       0    101088   0% /run/user/0root@v54405:~# free              total        used        free      shared  buff/cache   availableMem:        1010900       43992      903260        1608       63648      862952Swap:             0           0           0


Ubuntu 20.04

root@v54405:~# dfFilesystem     1K-blocks    Used Available Use% Mounted onudev              473920       0    473920   0% /devtmpfs             100480     592     99888   1% /run/dev/vda1       20575824 1931420  17757864  10% /tmpfs             502396       0    502396   0% /dev/shmtmpfs               5120       0      5120   0% /run/locktmpfs             502396       0    502396   0% /sys/fs/cgrouptmpfs             100476       0    100476   0% /run/user/0root@v54405:~# free              total        used        free      shared  buff/cache   availableMem:        1004796       65800      606824         592      332172      799692Swap:        142288           0      142288

Итак, в CentOS не доложили оперативной памяти (кстати почему хороший вопрос сервису), а Убунту занял на гигабайт больше места на диске. Так что я остановил свой выбор на Debian 10.

Для начала обновим систему:

apt-get updateapt-get upgrade

Также установим sudo

apt-get install sudo


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

Проверяем, что докер установлен

# docker -vDocker version 20.10.6, build 370c289


Также понадобится docker-compose. Процесс установки можно посмотреть тут.

Проверим, что докер установился:

# docker-compose -vdocker-compose version 1.29.1, build c34c88b2

Итак, все приготовления выполнены, посмотрим, сколько места осталось на диске:

Filesystem     1K-blocks    Used Available Use% Mounted onudev              490584       0    490584   0% /devtmpfs             101092    2892     98200   3% /run/dev/vda1       20608592 1781756  17956028  10% /tmpfs             505448       0    505448   0% /dev/shmtmpfs               5120       0      5120   0% /run/locktmpfs             505448       0    505448   0% /sys/fs/cgrouptmpfs             101088       0    101088   0% /run/user/0


Запускаем проект


Для эксперимента я написал на NestJS небольшой веб-сервис, который работает с изображениями. Он позволяет загружать изображения на сервер, извлекает из них метаданные, записывает их в MongoDB, а информация о сохраненных изображениях пишется в Postgres. Для каждого загруженного изображения можно получить метаданные и скачать само изображение. Изображения, к которым не обращались более 10 минут удаляются с сервера при помощи функции очистки, которая запускается раз в минуту.

Исходный код проекта на githab.

Я клонировал его на сервер при помощи команды:

git clone https://github.com/debagger/observable-backend.git

Чтобы было удобно разворачивать сервис на сервере я написал файл docker-compose.nomon.yml следующего содержания:
version: "3.9"volumes:  imagesdata:  grafanadata:  postgresdata:  mongodata:  tempodata:services:  backend:    image: node:lts    volumes:      - ./backend:/home/backend      - imagesdata:/images    working_dir: /home/backend    environment:      OT_TRACING_ENABLED: "false"      PROM_METRICS_ENABLE: "false"    ports:      - 3000:3000    entrypoint: ["/bin/sh"]    command: ["prod.sh"]    restart: always  db:    image: postgres    restart: always    expose:      - "5432"    volumes:      - postgresdata:/var/lib/postgresql/data    environment:      POSTGRES_PASSWORD: password      POSTGRES_USER: images  adminer:    image: adminer    restart: always    ports:      - 8080:8080  mongo:    image: mongo    restart: always    volumes:      - mongodata:/data/db  mongo-express:    image: mongo-express    restart: always    ports:      - 8081:8081


Для запуска проекта переходим в его директорию

cd observable-backend


И запускаем:

docker-compose -f docker-compose.nomon.yml up -d


Сервису понадобится некоторое время чтобы стартовать, я настроил его таким образом, чтобы он при запуске автоматически загружал зависимости и собирался.

После запуска можно проверить что он работает в браузере по ссылке
http://<ip сервера>:3000/

Должна вывестись строка Hello World!

Для того, чтобы испытывать производительность сервиса при помощи библиотеки autocannon я написал нагрузочный тест. Он находится в том же репозитории, в директории autocannon. Его надо запускать на машине с установленным node.js предварительно установив адрес сервера, где запущен проект в .env файле.

После запуска двухминутного теста я получил следующий результат:


В процессе теста я мог наблюдать за поведением системы при помощи стандартной команды linux top, а также docker stats. Помимо этого можно смотреть логи, при помощи команды docker logs. Но этого недостаточно, хочется лучше понимать, что происходит с моим сервисом под нагрузкой. Поэтому следующим шагом я решил добавить к проекту сбор метрик.

Настраиваем метрики


После недолгого гугления решений для сбора метрик я остановил свой выбор на связке Prometheus + Grafana.

Для использования этой связки я добавил в конфигурацию docker-compose следующее:

  prometheus:    image: prom/prometheus    ports:      - 9090:9090    volumes:       - ./prometheus.yml:/etc/prometheus/prometheus.yml  mongo-exporter:    image: bitnami/mongodb-exporter    ports:      - 9091:9091    command: [--mongodb.uri=mongodb://mongo, --web.listen-address=0.0.0.0:9091]  pg-exporter:    image: bitnami/postgres-exporter    ports:      - 9092:9092    environment:       DATA_SOURCE_NAME: sslmode=disable user=images password=password host=db      PG_EXPORTER_WEB_LISTEN_ADDRESS: 0.0.0.0:9092  grafana:    image: grafana/grafana    ports:       - 3001:3000    volumes:       - grafanadata:/var/lib/grafana


Здесь минимальная конфигурация для запуска Prometheus и Grafana, а также экспортеры для метрик из Postgres и Mongo. Для Prometheus я написал конфиг prometheus.yml со следующим содержимым.

global:  scrape_interval:     10sscrape_configs:  - job_name: 'nodejs'    honor_labels: true    static_configs:      - targets: ['backend:3000']  - job_name: mongodb    honor_labels: true    static_configs:      - targets: ['mongo-exporter:9091']  - job_name: postgres    scrape_timeout: 9s    honor_labels: true    static_configs:      - targets: ['pg-exporter:9092']


Чтобы собирать метрики из своего приложения я использовал библиотеку express-prom-bundle, которая позволяет собирать стандартные метрики и создавать свои собственные. Также я добавил в свой сервис переменную окружения PROM_METRICS_ENABLE для того, чтобы можно было включать и отключать метрики из конфигурации контейнера. Если активировать данную функцию, метрики, собираемые приложением, будут доступны по адресу http://<ip сервера>:3000/metrics.

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

Получившуюся конфигурацию я сохранил под именем docker-compose.metrics.yml.

Запустить эту конфигурацию можно командой

docker-compose -f docker-compose.metrics.yml up -d


После запуска можно зайти в интерфейс Grafana по адресу http://<ip сервера>:3001/

Логин/пароль по умолчанию admin/admin.

Здесь в настройках я добавил источник данных Prometheus


После этого нам доступны все метрики, которые собирает Prometheus.

Для примера выведем графики загрузки процессора по всем сервисам:


Для своих целей я настроил такую панель:


Теперь мне стало гораздо проще разобраться, что происходит с сервисом.

ELK неудача


Итак, я настроил метрики, и теперь мне хотелось заняться сбором логов. Я решил попробовать поднять для этих целей связку Elasticsearch + Logstash. Это просто первое, что пришло в голову, ибо читал много хорошего про эти инструменты. Особенно интересовало, удастся ли сделать сбор логов прямо с контейнеров, потому что у докера для этой целей есть встроенный плагин, позволяющий экспортировать вывод консоли сервисов в формате gelf, который поддерживает Logstash. Я добавил в docker-compose следующее

  elasticsearch:    image: elasticsearch:7.12.1    environment:      - discovery.type=single-node      - ES_JAVA_OPTS=-Xms250m -Xmx250m    ports:      - 9200:9200      - 9300:9300  logstash:    image: logstash:7.12.1    links:      - elasticsearch    volumes:      - ./logstash.conf:/etc/logstash/logstash.conf    command: logstash -f /etc/logstash/logstash.conf    ports:     - 12201:12201/udp    depends_on:      - elasticsearch


Также для начала настроил экспорт логов из Mongo. Для этого описание сервиса mongo в файле docker-compose я дополнил следующим образом:

  mongo:    image: mongo    restart: always    logging:      driver: gelf      options:        gelf-address: "udp://localhost:12201"


Когда я запустил новую конфигурацию я понял, что это конец. Ничего не работало. Сервер стал жутко тормозить, а kswapd0 периодически выходил на первое место по загрузке процессора, а свободная память была почти на нуле. Памяти для такой конфигурации явно не хватало.

Забегая вперед, когда я активировал файл подкачки, мне удалось запустить проект. Но все равно всё работало очень медленно, причем дольше всего запускался Logstash. Инструмент, задача которого всего лишь на всего грузить логи стартовал минут 20. Хотя, когда он наконец запустился, работал как предполагалось, и я даже смог посмотреть в Grafana кусочек лога Mongo, так что, в принципе решение работало, просто для системы с таким объемом оперативной памяти оно не подходило, что не удивительно, ведь если погуглить, каковы минимальные требования для Elasticsearch, то ответ будет таким:



Я действительно этого не знал, поэтому немного приуныл, поскольку я хотел позже использовать Elasticsearch в качестве хранилища данных для jaeger, чтобы реализовать сбор трейсов приложения и поставить Kibana чтобы добить ELK стек. Но, как говорится, на нет и суда нет, поэтому я стал искать альтернативу.

Loki


И альтернатива нашлась! Искать, к слову, долго не пришлось, потому что в списке поддерживаемых источников данных Grafana обнаружился зверь под названием Loki. Это сборщик логов из той же эко-системы, что Prometheus и Grafana. Напомню, что моя идея была в том, чтобы писать логи из стандартного потока контейнеров. И для этого сценария тоже быстро нашлось решение. Оказалось, для докера есть плагин, который позволяет делать именно то, что мне надо отправлять потоки стандартного вывода в Loki. Поставить его можно следующей командой:

# docker plugin install grafana/loki-docker-driver:latest --alias loki --grant-all-permissions

Я добавил в конфигурацию docker-compose сервис loki:

  loki:    image: grafana/loki:2.0.0    ports:      - 3100:3100    command: -config.file=/etc/loki/local-config.yaml

Кроме этого, я добавил ко всем сервисам, логи с которых хотел собрать, следующую секцию:

    logging:      driver: loki      options:       loki-url: http://localhost:3100/loki/api/v1/push

А к своему приложению добавил еще

        loki-pipeline-stages: |          - json:              expressions:                output: msg                level: level                timestamp: time                pid: pid                hostname: hostname                context: context                traceID: traceID


Чтобы из лога, который у меня в формате json парсились важные поля.

Получившийся конфиг я сохранил под именем docker-compose.metrics_logs.yml.

Теперь результат можно запустить при помощи команды

docker-compose -f docker-compose.metrics_logs.yml up -d

После запуска я понял, что что-то идет не так, потому что команда вылетела с сообщением Killed. Я попробовал еще раз сервисы запустились частично. На третий раз все заработало, но когда я заглянул в top то увидел, что там периодически проскакивает kswapd0, а это значило, что системе жестко не хватало памяти.


Простой выход добавить в конфигурацию хотя бы гигабайт оперативной памяти, но по условиям эксперимента я хотел запустить все на VPS минимальной конфигурации. Поэтому я решил активировать swap-файл, который в системе по умолчанию отключен. Сколько было эпичных баттлов в комментариях про то, нужен ли файл подкачки в Linux, но у меня выбора особо не было. Заодно я решил проверить, как будет влиять наличие файла подкачки на производительность системы.

Включаем swap:

# sudo fallocate -l 1G /swapfile# sudo chmod 600 /swapfile# sudo mkswap /swapfile# sudo swapon /swapfile

Проверяем про помощи команды free:

              total        used        free      shared  buff/cache   availableMem:        1010900      501760      202344       26500      306796      353952Swap:       4194300           0     4194300

В системе появился файл подкачки размером 4Гб. Должно хватить!

Снова пытаемся запустить нашу систему:

# docker-compose -f docker-compose.metrics_logs.yml up -d


Все работает! Теперь в Grafana добавляем в качестве источника логов Loki


Идем в Explore и видим, что логи начали подгружаться.


Проверим, что стало с производительностью.



Раз все работает, осталось закрепить файл подкачки в системе. Для этого надо в файле /etc/fstab добавить строку

/swapfile swap swap defaults 0 0

После этого файл подкачки останется в системе даже после перезагрузки.

Добавляем сбор трейсов при помощи Tempo


Для полного счастья мне нужна была система сбора трейсов. Чтобы не мудрить, раз уж так вышло, что я использую стек Grafana, можно добавить в качестве сборщика данных еще один инструмент от Grafana Lab сервер для сбора трейсов Tempo. Он из коробки поддерживается Grafana, поэтому попробуем его добавить его в систему.

Для того, чтобы приложение стало генерировать трейсы, его надо специальным образом инструментировать. Для этого есть замечательный проект под названием OpenTelemetry, который развивает систему спецификаций и библиотек для реализации трейсинга под различные платформы и системы. В нем есть готовые библиотеки для автоматической инструментации Node.js и сервера express.js, который работает под капотом у nest.js. Их я и добавил в свой проект.

Tempo может принимать трейсы про всем распространённым протоколам. Я выбрал протокол Jagger Trift binary простой двоичный формат, передаваемый по UDP. Также, как и в случае с метриками, я в своем приложение я добавил переменную окружения OT_TRACING_ENABLED, которая, если ее установить в true включает в приложении телеметрию.

Для запуска Tempo я добавил в файл конфигурации docker-compose следующее:

  tempo:    image: grafana/tempo:latest    command: [-config.file=/etc/tempo.yaml]    volumes:      - ./tempo-local.yaml:/etc/tempo.yaml      - tempodata:/tmp/tempo    ports:      - 6832/udp   # Jaeger - Thrift Binary

и сохранил его под названием docker-compose.metrics_logs_tempo.yml

Для настройки Tempo я создал файл конфигурации tempo-local.yaml (на самом деле просто скопировал из репозитория Tempo подходящий и немного поправил). Запустим его командой

docker-compose -f docker-compose.metrics_logs_tempo.yml up -d


Теперь осталось в Grafana настроить источник данных:


Чтобы было удобно переходить к просмотру трейсов из логов надо настроить источник данных Loki:


После такой настройки рядом с полем traceID появится ссылка:


По этой ссылке будет открываться окно с данным трейсом:


Испытываем производительность нашего сервиса.


Здесь уже видно заметное падение производительности сервиса, но надо понимать, что эта плата за детальную телеметрию.

Дополнение: уже когда я прогнал нагрузочные тесты, результаты которых приведены ниже и дописывал статью, изучая документацию Jaeger я выяснил, что он может использовать для хранения данных локальное хранилище на основе key-value базы данных Badger, и, таким образом, может работать без Elasticsearch. Я добавил в репозиторий файл конфигурации для docker-compose где вместо tempo используется jaeger (docker-compose.metrics_logs_jaeger.yml), но не проводил всего набора тестов. Я запустил тест производительности только на базовой конфигурации, и в этом режиме получилось 19,92 запроса в секунду, что несколько больше по сравнению с вариантом, где используется tempo 18,84.

В отличии от tempo, который позволяет искать трейсы только по traceID, jeaeger дает возможность поиска по различным параметрам и у него есть собственный, достаточно удобный интерфейс для просмотра трейсов.

Результаты тестов


Итак, мне удалость запустить все необходимые компоненты мониторинга и телеметрии. Осталось понять, насколько использование различных компонентов влияет на производительность системы.

Для каждого из перечисленных выше вариантов я запускал нагрузочный тест продолжительностью 20 минут. Для того, чтобы задействовать все компоненты системы, включая сетевой интерфейс я запускал тест autocannon со своей VPS размещённой у другого провайдера, предварительно проверив скорость соединения при помощи iperf она составила 90 Мбит/сек. Так же между запусками тестов я дожидался, пока отработает функция удаления старых изображений, полностью удалив загруженные в предыдущем тесте файлы с диска и информацию из баз данных.

Результаты я свел в таблицу. Для оценки производительности я решил ориентироваться на число запросов в секунду, которое может обрабатывать система. Конечно, есть куча других метрик, но именно эта наиболее наглядно, на мой взгляд, показывает общее влияние различных факторов на производительность системы. Вот что получилось.

Запросов в секунду Снижение производительности
Без мониторинга 28,07 100%
Prometheus 27,19 97%
Prometheus+Loki 25,47 91%
Prometheus+Loki+Tempo 18,84 67%

Выходит, что только использование трейсинга приводит к значительным потерям производительности, а в случае со сбором метрик и логов потери составляют менее 10%.

Добавляем ядра и память


Также я решил посмотреть, как будет влиять на производительность сервиса увеличение объема памяти и количества ядер процессора. Macloud.ru позволяет менять параметры тарифа и я решил посмотреть как работает эта функция. Первым делом я добавил еще 1 Гб оперативной памяти.


После нажатия кнопки Сменить тариф сервер перезагрузился и вот что получилось:

              total        used        free      shared  buff/cache   availableMem:        2043092      309876     1190416       14284      542800     1576804Swap:       4194300           0     4194300

Все правильно. Теперь можно отключить файл подкачки.

swapoff /swapfile

Посмотрим, что покажут тесты:

Запросов в секунду Снижение производительности
Без мониторинга 27,52 100%
Prometheus 24,78 90%
Prometheus+Loki 21,58 78%
Prometheus+Loki+Tempo 21,44 78%

Почему-то производительность в целом стала немного ниже, но не так сильно зависит от включения функций мониторинга. Я предположил, что может быть дело все-таки в файле подкачки и включил его обратно. Вот что получилось:

Запросов в секунду Снижение производительности
Без мониторинга 29,64 100%
Prometheus 26,97 91%
Prometheus+Loki 25,7 87%
Prometheus+Loki+Tempo 22,95 77%

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

После этого мне стало интересно а как повлияет на производительность добавление второго ядра CPU? Сказано-сделано:


После добавления второго ядра я погнал всё те же тесты и вот какой результат получился.

Запросов в секунду Снижение производительности
Без мониторинга 49,05 100%
Prometheus 44,52 91%
Prometheus+Loki 45,64 93%
Prometheus+Loki+Tempo 40,34 82%

Производительность увеличилась в 1,75 раза если сравнивать с базовым вариантом. Это хорошо, ведь если нагрузка на сервер будет расти, я могу просто докупить второе ядро, когда в этом появится необходимость.

Дальше я экспериментировать не стал, мне понятно, что, если продолжить добавлять память и процессорные ядра, производительность системы не будет расти так заметно. Чтобы обеспечить прирост производительности в этом случае нужно будет организовать запуск приложения в режиме кластера и внести еще ряд архитектурных изменений.

Выводы


Начиная этот эксперимент, я задался целью проверить, возможно ли на VPS c очень ограниченными ресурсами (я знаю, что можно найти предложения с еще более скромными параметрами, но 1 CPU + 1 Гб RAM это доступный минимум у большей части провайдеров) запустить полноценную систему мониторинга для приложения. Как видите, это оказалось вполне возможно. Конечно, не все инструменты, которые используют крупные компании, применимы, но вполне можно найти такой набор, который позволит организовать мониторинг вашей системы не сильно влияя на ее производительность.

Также в ходе эксперимента я смог ответить для себя на ряд вопросов:

Стоит ли заморачиваться с настройкой мониторинга для совсем небольшого проекта?

Я считаю, что да, стоит. Мониторинг помогает понять, как ведет себя ваш проект в рабочей среде и дает информацию для дальнейшего улучшения качества кода. Я в процессе данного эксперимента, благодаря изучению данных мониторинга я смог заметить ряд недостатков в своем приложении, которые мне бы вряд ли удалось выявить другим способом.

Нужно ли делать нагрузочное тестирование?

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

Сложно ли настроить мониторинг

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

А почему не облачные решения?

Мне просто спокойней платить фиксированную сумму и иметь в своем распоряжении все ресурсы, которые дает VPS. Истории, как разработчик что-то сделал неправильно и получил многотысячный счет пугают. Хотя возможно, что в облаке все, что я описываю в этой статье настраивается за пару кликов мышкой, и тогда это, конечно, огромный плюс.

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

Репозиторий можно посмотреть по этому адресу: github.com/debagger/observable-backend



Облачные серверы от Маклауд быстрые и безопасные.

Зарегистрируйтесь по ссылке выше или кликнув на баннер и получите 10% скидку на первый месяц аренды сервера любой конфигурации!

Подробнее..

Мониторим парк ИБП. Ч.3, заключительная

16.06.2021 12:16:05 | Автор: admin

Или что пригодится знать и уметь, если замена ИБП после поломки урон профессиональной гордости.

Часть 1
Часть 2
TL;DR

И вновь приветствую, уважаемые коллеги и читатели. За пару лет достаточно плотной работы с бесперебойниками я совершил для себя много "открытий чудных". Спешу поделиться с вами.

Disclaimer
  1. Речь идёт в основном о ИБП мощностью 400-800VA, "линейно-интерактивных", со свинцовыми батареями 12В;

  2. Бесперебойное обеспечение в основном офисных "печатных машинок": ЦП мощностью до 100 Вт и SSD в качестве системных дисков, без дискретных видеокарт;

  3. Централизованный ИБП отсутствует.

Решаемые задачи:

  1. Минимум: иметь хотя бы общее представление о состоянии парка устройств;

  2. Хорошо: менять устройства ДО возникновения сбоя, обеспечивая тем самых их фактический и экономический смысл. Да-да, просто поставить ИБП совершенно недостаточно;

  3. Отлично: иметь наглядные данные что было сделано IT-службой и почему это было необходимо сделать (потратив на это деньги и человекочасы).

Об офисных UPS

В очередной раз повторюсь: поставить и забыть не прокатывает.
ИБП без функции передачи данных бесполезны практически полностью, так как не решают одну из важнейших проблем безопасное выключение с сохранением данных. К сожалению, ИБП с передачей данных тоже далеко не панацея. Тому есть несколько причин:

1. Качество соединения
На основании двухлетнего наблюдения могу с уверенностью сказать, что это беда.
Если не следить за подключениями достаточно внимательно, большинство из бесперебойников поотваливаются в течение полугода. Такое поведение сильно зависит от конкретных условий и меняется от машины к машине. Основные причины потери соединения (насколько мне удалось разобраться):
а) чисто физические. Сюда входят ненадёжные разъёмы (и они случаются чаще, чем хотелось бы), случайные нарушения соединений (уборщица слишком ретива, пользователь дёргает ногами или двигает системник) и, внезапно, качество соединительного кабеля похоже, что ИБП довольно чувствительны к этому параметру, особенно при активном опросе;
б) на втором месте не "глючные драйверы", что удивительно, а электроника самих ИБП. Похоже, бесперебойникам из нижнего ценового сегмента не очень нравится, когда их часто "дёргают".

чуть подробнее

вообще, обмен данным с ИБП идёт постоянно, но всё же не раз в миллисекунду. Драйвер usbhid-ups получает данные раз в 2 секунды (видно в дебаг-режиме, если запускать руками с параметром -D+), что-то похожее, наверняка, и в стандартном драйвере Windows и WMI. Но это только "частичное" обновление, "полное" обновление происходит раз в 30 секунд

есть вероятность, что "полный" запрос сильно нагружает электронику ИПБ, и при частых запросах она начинает подглючивать. Это напрямую касается реализации сервера, о котором идёт речь в статьях. Чем это чревато и что с этим делать см. далее

2. Работа внутренних систем, сенсоров и логики UPS
Во-первых, ИБП от разных производителей обращаются с батареей по-разному. В моей практике хуже всех обращаются с батареями ИБП Powercom, лучше всех IPPON (далее по батарее см. п.3). Отличие не принципиальное, Powercom тоже через пол-года не дохнут, но оно есть и весьма заметно, если анализировать накопленные данные за достаточно длительный период. Здесь переходим к во-вторых: наиболее интересные параметры, которые ИБП сам считает и выдаёт:
а) нагрузка (load)
б) предсказание времени работы от батареи (runtime), вычисляемое на основе нагрузки
в) текущий заряд батареи (charge)

На эти параметры я уже ругался в предыдущих статьях, так что повторяться не буду, а просто кратко резюмирую: это синтетика, имеющая очень мало отношения к реальности. В каких-то ИБП эти данные поадекватнее, в каких-то совсем идиотизм, но в целом без реальной динамики от этих данных не просто крайне мало пользы они могут ввести в заблуждение.

К сожалению, есть куда больше параметров, которые анализировать, считать и даже просто получать стоило бы, но это не реализовано.
Простейший пример: просадка напряжения на батарее, когда пропадает питание. Это показательнейший параметр, на основании которого можно куда точнее сделать вывод об убитой батарее. Постоянная память EEPROM есть сейчас где угодно, и ИБП запросто может записывать такие данные самостоятельно. Но ни одного ИБП с таким функционалом мне не попалось.
Другой пример: Powercom'ы после потери питания и разряда батареи до 30 процентов могут "зарядить" 12-вольтовую батарею за 10 минут и утверждать, что всё прекрасно, а Self-test passed.

если вас ничего не смущает

время полного заряда 12 В свинцовой батареи даже в "агрессивном" режиме составит не меньше часа, и батарея после такого долго не живёт

Это прямо натуральный epic fail.
Те же Powercom не умеют в вольтаж батареи вообще, только в проценты. На основании чего там эти проценты внутри считаются покрыто китайской мракой.

Очень важного параметра "температура" (батареи, внутри корпуса, да хоть чего-нибудь) не найти днём с огнём в офисных ИБП, хотя датчик копеечный и вообще встроен в почти все микроконтроллеры. Тут переходим к третьему пункту раздела.

3. Батарея и её состояние
Из того зоопарка, с которым я имел дело, "посредственно" справляется с задачей анализа состояния батареи серверный ИБП IPPON. Потуги остальных иначе как "бессмысленно" назвать не могу. Очень важный параметр батареи кривая разряда просто игнорируется.

немного о кривой разряда

Свинцовые батареи ИБП разряжаются нелинейно. Проще говоря, чем меньше заряда осталось в батарее, тем быстрее она разряжается. Ещё проще: время разряда со 100% до 90% будет в разы больше, чем с 20% до 0%. Но и это ещё не всё. Кривая разряда становится круче в более старой батарее и/или в зависимости от внешних условий (та же температура). В итоге это выглядит так:

Чувствуете подвох? Угадайте, проводит ли ИБП запись скорости последнего разряда, анализ, учитывает ли дату установки батареи?

спойлер

ИБП ваще пофигу, не анализирует, не учитывает. Лучшее, что я видел через три года начинает орать "чота батарея старая".

Вспомним, с чего мы начали этот раздел: передача данных с ИБП нужна для того, чтобы сохранить данные, пока ещё осталось время. Но ни ИБП, ни драйвер не знают, какое время является безопасным: 50% новой батареи совсем не то же самое, что 50% годовалой батареи. И единственное решение проблемы на данный момент: параметр нужно периодически модифицировать вручную.

Запись и расчёт параметров реализован в очередном обновлении сервера мониторинга. В частности, теперь видно:

  • просадку заряда батареи непосредственно после потери питания. Если этот показатель низкий, сервер выдаст предупреждение;

  • скорость разряда батареи. Этот параметр требует для расчёта не менее 2 мин наблюдаемого разряда ИБП.

Для корректного учёта этих параметров требуется довольно частый опрос ИБП. Соответствующие изменения внесены в код сервера (см. раздел "NUT и сервер мониторинга"). К сожалению, здесь мы упираемся в ранее озвученный п. "б" ч. 1 текущего раздела при частых обращениях за данными возможны глюки. Более того, в первые секунды после потери питания ИБП данные не отдаёт вообще, а вместо этого передаёт "WAIT". По-хорошему, после потери питания ИБП для целей мониторинга нужно бы опрашивать как можно чаще. На данный момент частота опроса от 10 до 30 секунд, в целом для более-менее приличного анализа этого хватает. Более интенсивные опросы не тестировались достаточно долго, чтобы делать какие-то однозначные выводы.

Краткие итоги раздела:

  • обязательно нужен мониторинг самого факта подключения ИБП к машине;

  • нужно собирать и хранить данные о датах установки батарей;

  • в идеале нужно очень детально мониторить процесс разряда и заряда батарей.

NUT и сервер мониторинга

Изначально NUT был выбран как кроссплатформенное универсальное решение. В целом функции свои выполняет. Без нюансов, впрочем, не обошлось:
а) Не слишком дружелюбная и неочевидная установка на клиентских машинах, под Windows особенно. В частности:

  • иногда отказывается видеть библиотеки;

  • встроенный драйвер не обновлялся давно и половину ИБП не знает. Драйвер надо ставить вручную, и это отдельная песня;

  • на клиентах под Windows служба стартует "невовремя", раньше, чем фактически нужно (похожая история есть при поиске домена на Windows с некоторыми сетевыми адаптерами). Из-за этого приходится городить костыли.

б) Заявлено, что клиент NUT может оповещать сервер о пропадании и восстановлении питания, и даже выполнять скрипты по этим событиям. Это убрало бы и необходимость частого опроса ИБП, и позволило бы вести более точечный мониторинг важных состояний (см. предыдущий раздел). Однако заставить стабильно работать этот функционал мне не удалось. Некоторые машины не триггерят сервер вообще, либо делают это один раз из десяти. При этом есть машины, с которых это работает стабильно.

В качестве альтернативы я попробовал (и даже написал "адаптер") получать данные из WMI по предложению @firedragon. Суть, в общем, та же. Плюсы: не нужно альтернативных дайверов и библиотек, не нужно костылить некоторые вещи. Минусы: информации сильно меньше, а по сравнению с настроенным клиентом NUT стабильность ровно та же, при этом отсутствует, хотя бы потенциальная, возможность "триггера".

По результатам изысканий решено было оставить NUT в качестве основного решения для сервера. При этом "сильно больше данных" в какой-то момент обернулось базами, раздутыми по 100 Мб на бесперебойник, что повлияло на производительность. В итоге, сервер был перенесён из среды Windows в Linux, и:

  • написан соответствующий скрипт-демон на bash для непрерывного опроса;

  • оптимизировано хранение данных: если есть питание на входе и некоторые другие параметры в норме, последняя строка не добавляется в базу, а обновляется.

В саму веб-морду сервера, как уже говорилось, добавлено:

  • отображение заряда батареи сразу после последней потери питания и соответствующий алерт;

  • расчёт времени работы от батареи на основе реальных данных. Некоторым образом это тоже синтетика, т.к. реальная кривая разряда не строится. Однако, отлично себя показала следующая формула: рассчитанное на основе последних реальных данных время / 1+ лет с десятыми.

Итоги, советы, планы

Для тех, кто хочет "сделать всё правильно", исходя из полученного опыта, дам следующие советы:

  1. Тщательно выберите марку и модель ИБП и по возможности используйте только выбранный ИБП во всем офисе;

  2. Запишите серийные номера и/или присвойте каждому ИБП уникальный номер. Запишите дату установки батареи в каждый ИБП. Меняйте батареи раз в два года, и сразу, заранее, закладывайте эти расходы в бюджеты для бизнеса запланированные расходы гораздо удобнее внезапных;

  3. Любым способом следите за тем, чтобы машины, обеспеченные ИБП, имели с ним постоянную связь;

  4. Раз в пол-года обновляйте параметры battery low и battery warning в используемом вами драйвере/решении, прибавляя к ним от 5% до 20% в зависимости от опыта использования вашей модели ИБП, вручную или скриптами;

  5. По возможности проводите ручное тестирование ИБП (отключить от розетки и подождать) раз в квартал-полгода.

Это то, что нужно делать обязательно.

Использование постоянного и подробного мониторинга, в целом, скорее чрезмерно, хотя и может оказаться полезным и наглядным. Заводить для этого отдельный сервер или нет, решать вам. Некоторые параметры можно мониторить в том же Zabbix (и даже посредством WMI), однако лично у меня в целом не очень удачный опыт с Zabbix active parameters; к тому же, сложность реализации некоторых описанных решений внутри Zabbix по сложности приближается, на мой вкус, к сложности реализации представленного сервера мониторинга.

Я удивлён и рад, что довольно много читателей задумалось о мониторинге ИБП после первой статьи, и многие посоветовали довести решение "до энтерпрайза" после второй статьи. Благодарю за отклики и ответы!

Учитывая накопленный опыт, реализация "до энтерпрайза" может быть довольно длительной. Есть проблемы и на клиентской стороне, и в самом NUT; в веб-интерфейсе многое надо выносить в бэкэнд, нет даже банальной авторизации. Можно было бы даже в таком виде запихнуть всё это в контейнер Docker в качестве версии 0.1 alpha, но мой энтузиазм к теме несколько поугас. Если у кого-то энтузиазм найдётся пишите, буду рад поработать вместе!

Рад, если мой опыт вам пригодится. Спасибо всем, кто прочитал!

Подробнее..

Как ускорить миграцию Zabbix на TimescaleDB

29.03.2021 10:21:19 | Автор: admin

image


После того, как в прошлой статье Как мигрировать Zabbix с MySQL на PostgreSQL с минимальным downtime я успешно перенес Zabbix с MySQL на PostgreSQL, встала необходимость сделать следующий шаг мигрировать БД на TimescaleDB, т.к. ради нее все и затевалось.


У читателя может возникнуть вопрос: зачем нужна эта статья, если есть простой и понятный мануал?
Но проблема, как и в прошлой статье, скрыта в downtime. В мануале ясно написано:


The migration of existing history and trend data may take a lot of time. Zabbix server and frontend must be down for the period of migration.

Исходные данные следующие:



Я всячески игрался с тюнингом PostgreSQL, добавлял ресурсы на виртуальную машину с PostgreSQL. Испытанный максимум ресурсов 24 CPU, 64 GB RAM. Но, очевидно, скрипт миграции упирается в дисковую производительность. В итоге при моей базе данных размером в ~350 Гб миграция занимала 15 часов. Все это время мониторинг отключен.


Я пошел читать документацию TimescaleDB по миграции данных и нашел такой способ, обозначенный как "Faster Method":


  • выбираем таблицу, которую хотим мигрировать в гипертаблицу. Например, history
  • создаем новую таблицу, аналогичную старой, при этом исключая индексы
    CREATE TABLE history_new (LIKE history INCLUDING DEFAULTS INCLUDING CONSTRAINTS EXCLUDING INDEXES);
    
  • конвертируем новую таблицу в гипертаблицу
    SELECT create_hypertable('history_new', 'clock', chunk_interval => 86400);
    
  • перемещаем все данные из history в history_new
    INSERT INTO history_new SELECT * FROM history;
    
  • удаляем старую таблицу history
    DROP TABLE IF EXISTS history;
    
  • переименовываем history_new в history
    ALTER TABLE IF EXISTS history_new RENAME TO history;
    
  • создаем индекс (как описано в файле схемы БД schema.sql)
    CREATE INDEX history_1 in history (itemid,clock);
    

И так надо сделать для таблиц:


  • history
  • history_log
  • history_str
  • history_text
  • history_uint
  • trends
  • trends_uint

Для ускорения процесса я поместил команды для каждой таблицы в отдельные файлы, чтобы запускать их параллельно.
Ссылка на github репозиторий со скриптами:
https://github.com/niklep/zabbix_timescaledb_scripts


Скрипт finish.sql необходимо выполнить уже после завершения миграции всех таблиц.


В итоге миграция таблиц в гипертаблицы TimescaleDB в моем случае заняла 5 часов, что сильно меньше изначальных 15.
PROFIT.

Подробнее..

Мониторинг в ЦОДе как мы меняли старую BMS на новую. Часть 4

20.04.2021 16:13:49 | Автор: admin

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

Следующей задачей на пути развития системы стал вопрос ее настройки: как сделать так, чтобы работать с новой системой было удобно, а сама она была бы максимально информативной?

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

Другой вариант: выставить недостаточное количество таких оповещений, создав риски для дежурных пропустить действительно важное событие.

В этой части мы поделимся практическим опытом настройки нашей системы мониторинга работы ЦОДа.

Немного теории

Собираемые системой SCADA переменные делятся на телесигнализацию и телеизмерения учили меня когда-то в институте. И на самом деле ничего не поменялось: телесигнализация это состояние устройства, например, нет аварии, есть авария, открыт, закрыт и т. д.

А телеизмерение, как нетрудно догадаться, это цифровое значение какого-либо параметра, например 220 Вольт или 10 Ампер.

Состояние или значение, настроенное пользователем, при котором на экране появляется сообщение (авария), называется уставкой. Можно настроить задержку до появления сообщения, то есть авария на экране появляется только через Х секунд (при условии, если аварийная ситуация не прекратилась раньше) или на замораживание сообщения на экране в этом случае авария уже пропала, но сообщение о ней на экране сохраняется еще Х секунд.

Аварии по показателю приоритетности обычно делятся на три основных типа: Красная, Желтая и Голубая. Красные аварии требуют немедленных действий сотрудников, Желтые о чем-то их предупреждают, Голубые чаще всего сообщают о каких-то некритичных событиях. Например, мы вывели Голубые аварии из сводки, которую видят дежурные, и используем их для мониторинга различных коммерческих параметров (превышение заказанной мощности). Отчеты по этим авариям направляются только менеджерам и не отвлекают дежурных.

Для удобства настройки однотипного оборудования переменные в разных устройствах, но с одним именем (например, OutputCurrent) имеют одинаковые настройки на всех устройствах системы. Если мы меняем уставку в одном месте она меняется везде.


Когда какое-то устройство требует индивидуальных настроек у требуемой переменной, мы применяем специальную отметку Только для этого устройства. Теперь переменная стала индивидуальной для одного конкретного устройства, имеет свою уставку и не влияет на другие одноименные переменные.

Дополнительно в самих устройствах есть собственные заводские уставки. Например, в PDU с завода настроено распознавание аварийной ситуации на превышение тока в 32А. В случае ее срабатывания от PDU поступит оповещение о типе аварии Overload Alarm. И это совсем другая переменная, не связанная с переменной OutputCurrent, настроенной в BMS.

Пример заводских настроек уставок внутри PDU:


Итак, мы перечислили основной функционал для настройки системы мониторинга.

Как же правильно настроить это пианино? Давайте рассмотрим задачи по порядку.

Чего мы хотим добиться

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

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

Этап 1. Определение нужных и ненужных переменных у каждого устройства

Обычно к каждому устройству идет так называемая карта переменных, на основании которой инженером-наладчиком создается драйвер. Его задача указать системе мониторинга, в каком именно регистре получаемых данных находится нужная переменная. Например, в регистре 1 протокола опроса устройства находится информация о режиме работы двигателя System_on_fun, а в регистре 2 о режиме работы компрессора Compressor_1.

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

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

  • Лишние переменные загружают оперативную задачу системы мониторинга и увеличивают размер архива, система вынуждена обрабатывать и сохранять ненужные данные.

  • Чем больше опрашивается переменных, тем выше вероятность сбоя опроса. Особенно это актуально для устройств, подключенных по шлейфу (например, через шлюз по протоколу MODBUS). Это приводит к получению состояний нет данных (Н/Д) или обрыв связи, то есть фактически устройство периодически выпадает из мониторинга.

  • Некоторые переменные лишние по умолчанию. Например, в вашей версии оборудования нет компрессора или датчика давления, но они прописаны в универсальном драйвере для всего модельного ряда оборудования и опрашиваются, добавляясь в архив, нагружая сеть и процессинг.

На скриншотах приведена часть кода драйвера. Символами // указаны скрытые из опроса переменные. Также виден список переменных, отображаемых для пользователя при настройке уставок в самой BMS.



Заводские уставки внутри устройств по нашему опыту на начальном этапе лучше не трогать (конечно, если они не сообщают вам уже об аварии). Однако на каждой тренировке по конкретному оборудованию следует напоминать сотрудникам о наличии уставок и в самом устройстве, и в BMS. Это в будущем поможет дежурным точно понимать, что именно является причиной аварийного сообщения.

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

Делать это должен не наладчик системы, а сотрудник, понимающий работу системы, которую контролирует система мониторинга, желательно главный инженер или главный энергетик.

Этап 2. Минимизация ложных и неинформативных сообщений

Ложные срабатывания часто происходят из-за сбоев в опросе устройства. Если сетевая карта устройства не снабжена автономным питанием, то и сбой в опросе и реальное отключение питания будут отображаться как один тип аварии обрыв связи.

В этом случае надо разделить оборудование на критическое (например, PDU) и обычное (например, щиты вентиляции ЩУВ). Для обычного оборудования можно установить задержку на сигнал обрыв связи (например, 300 секунд) тогда большинство ложных обрывов будут игнорироваться.

Понятно, что на критическое оборудование такую задержку ставить нельзя, поэтому если оно постоянно дает ложные сбои, то следует разбираться с физической сетью, количеством опрашиваемых переменных. Вполне возможно, что на один шлюз повешено очень много устройств и надо сегментировать сеть через добавление новых шлюзов.

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

В этом случае часть оборудования, запитанного без ИБП, штатно обесточивается и выдает ошибку обрыв связи, а сами ИБП выдают целый букет сообщений нет питания на вводе, нет питания на байпасе, питание от АКБ и т. п. Персонал сразу получает десятки сообщений.

Для оптимизации количества сообщений при переходе на ДГУ следует:

  • настроить на штатно появляющиеся во время перехода аварийные сигналы более длительные временные задержки, чем время появления питания от ДГУ. Например, установить задержку на сигнал обрыв связи щита вентиляции 300 секунд при штатном времени перехода на ДГУ 200 секунд.

Тогда питание на ЩУВ появится раньше задержки уставки, и ситуация не будет распознана как аварийная. При это есть критически важные устройства, которые запитаны от ИБП и всегда должны быть на связи (например, PDU) сообщения об их дисконнекте должны появляться без задержки.

  • проанализировать сообщения от ИБП при переходе на ДГУ и разделить их на нормальные с присвоением им желтого типа (например, констатация факта нет питания на вводе) и ненормальные (отключение батарейного автомата, которого быть не должно в любом режиме работы), с присвоением им красного типа.

При этом отдельно записываем в инструкцию дежурным, что в случае перехода на ДГУ желтые аварии можно наблюдать и не квитировать (они пропадут сами после завершения штатного перехода), а красные немедленно устранять (их быть не должно).

За один раз, полагаясь только на теорию, настроить уставки для этого переходного процесса очень сложно. Для успешной настройки надо несколько раз наблюдать за переходами на ДГУ в реальном времени.

Например, нам потребовалось наблюдение за 4-5 переходами для приемлемой настройки новой BMS. Чтобы проанализировать внеплановый процесс перехода, мы делали запись экрана системы мониторинга, так как важно наблюдать аварийные сообщения не в архиве событий, а анализировать появление аварий в динамике оперативной сводки.

Этап 3. Дополнительные советы из нашего опыта

1.На экранах дежурной смены не должно быть лишней индикации в цветах аварийных сообщений.

Пример из реальной практики. Один ЦОД заказал карту температурных потоков в серверной. Это 3D модель потоков воздуха с множеством температурных данных с датчиков. Получился вид северной с потоками воздуха где-то воздух был выделен зеленым, где-то желтым и красным (от самого холодного к самому горячему). При этом температуры воздуха везде в пределах нормы, а цвета применены только для наглядности отображения разницы температур в разных точках.

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

Наверное, дежурным объяснили, что на левом экране красное/желтое это нормально, а на правом экране эти же цвета сигнал к действию. Однако ясно, что такая практика очень серьезно увеличивает риск человеческого фактора.

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

2. С осторожностью используйте SMS-оповещения.

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

3. Настраивайте дублирование сообщений об авариях через мессенджер.

Это можно реализовать, например, через Microsoft Teams или Telegram. Сообщения об авариях будут приходить и вам, и дежурным, при этом телефон будет издавать звуки и вибрировать (чего нет при работе с системой через браузер).

И не бойтесь, что сообщений будет много. По нашему опыту, за среднестатистический день работы ЦОДа приходит всего несколько десятков сообщений, и они не загружают телефоны сотрудников. То есть оборудование ЦОД и систему BMS можно настроить так, чтобы не получать сотни оповещений и при этом ничего важного не пропускать.

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

4. Группируйте сообщения в мессенджерах.

Во время перехода на ДГУ или из-за комплексной аварии у вас будут запущены десятки активных аварийных ситуаций, телефон будет постоянно вибрировать от поступающих в мессенджер сообщений, не давая сделать важный звонок или открыть окно системы мониторинга.

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

5. Ярко выделяйте в интерфейсе сообщение о пропадание связи с сервером.

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

На скриншоте пример индикации о пропадании связи с сервером BMS, при этом отображаются неактуальные параметры работы оборудования.


6.Подключайте к мониторингу как можно больше систем.

Например, традиционно система пожарной сигнализации работает автономно, а ее панель висит на посту охраны.

Да, по сигналу ПОЖАР срабатывают автоматические алгоритмы работы систем, запускается система оповещения, но о появлении сигналов Неисправность или Внимание сотрудник охраны сообщает дежурным голосом.

Полноценно подключить к мониторингу такую систему очень сложно, но в такой системе легко настроить три релейных сигнала неисправность, внимание и пожар, а затем подключить их сухими контактами в модуль системы BMS.

Тем самым снижается риск пресловутого человеческого фактора. Пример тестового сигнала ПОЖАР в системе BMS ЦОДа, подключенного через сухие контакты.


Подведем итоги нашей 4-серийной истории

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

Пройдя довольно трудный и длинный путь, мы получили:

  • быструю и стабильную систему мониторинга, которая на данный момент контролирует более 2500 устройств и обсчитывает около 10000 виртуальных датчиков;
  • резервирование системы на платформе облачных решений Linхdatacenter в Санкт-Петербурге и Москве;
  • доступ к системе из любой точки мира через веб-интерфейс, с дополнительной отправкой сообщений из системы на любые мессенджеры, что позволило сократить максимальное время информирования персонала об аварии до 1 минуты;
  • ощутимую экономию, так как система обошлась в разы дешевле аналогов, легко масштабируется и не требует платы за лицензии для устройств или пользователей;
  • надежное решение, которое позволило нам не только улучшить собственные процессы, но и предложить новый коммерческий продукт нашим заказчикам гибко настраиваемую и масштабируемую систему мониторинга.
Подробнее..

Опыт написания асинхронного поллинга сетевых устройств

03.06.2021 14:23:54 | Автор: admin

Основная идея асинхронного поллинга

Асинхронность позволяет сильно увеличить парралельность работы. В случае сетевого взаимодействия и съема SNMP времена ожидания ответов большие, что позволяет программе заняться чем-то полезным пока не пришел ответ.

Есть синхронные способы реализации парралельности форки, треды. Это просто с точки зрения написания программы, но это очень дорого с точки зрения ресурсов ОС

Немного математики

Математика будет инженерно-прикидочная, точность 20%

Я хотел опрашивать 100 тысяч устройств по 100 метрикам каждое один раз в 5 минут, с запасом один раз в минуту.

То есть нужно снимать 10 млн метрик в минуту или 150 тысяч в секунду. Округлю до 100 тысяч метрик в секунду.

Опрос одной метрики занимает около 5мс: 4мс отвечает устройство, + 1мс на обработку.

Это значит, что один синхронный поток может обрабатывать 200 метрик в секунду или нужно 500 синхронных потоков. Вполне реалистично.

(Все, конец, больше писать нечего)

На самом деле это только начало. Фишка в не идеальности мира, а именно в потерях ответов на запросы.Потери происходят из-за потерь траффика или недоступности устройств.

В моем случае таймаут ожидания составлял одну секунду и делалось 2 попытки, значит на недоступном устройстве можно потерять 2000мс на ожидание

Посчитаем еще раз

По нашему опыту в инфраструктуре вчегда недоступны 3% устройств. Причины разные работы по модернизации, обрывы сети, отключения света.

Итак, 3% метрик опрашиваются со скоростью 2000мс.

В таком случае один поток cможет опрашивать всего 15,5 метрик в секунду.

Но введем оптимизацию и в случае, если у устройства 5 раз подряд не удается снять метрики, остальные 95 метрик не будем снимать в текущем цикле опроса. Получится, что один поток может обрабатывать 125 метрик в секунду или нам нужно будет 800 потоков. На грани, но можно.

Учтем специфику задачи у нас мониторинг и нам интересно чтобы он быстро работал _особенно_ когда все идет нет так. Плюс есть технические аргументы 800 потоков генерируют высокую конкуренцию за общие ресурсы и в целом, работают плохо в системе, которая по дизайну была рассчитана на десятки потоков.

А что, если недоступно не 3%, а 20% или все 100% устройств?

Ок, посчитаем еще один раз

Чтобы не было скучно вымышленный, но вполне возможный пример из какого ни будь постмортема ошибка конфигурации X привела к недоступности по мониторингу и управлению примерно половины сети. Исправление было сделано сразу же, проверенные вручную 10 устройств стали доступны, но реально проблема решилась только в одном сегменте, поэтому устранение для остальной части сети затянулось на 2 часа.

Хорошо бы, чтобы мониторинг мог локализовывать и такие аварии, когда и 45%, и 99% сети недоступно.

Тогда немного другая задача: 100% устройств не отвечают. Сколько нужно потоков, чтобы увидеть, что они заработали в течении 30 секунд? - Около 7 тысяч.

Такую параллельность разумно обеспечить асинхронностью

Входные данные

Система написана на С, парралельность обеспечена форками, для синхронизации используются мьютексы, активно используется Shared Memory для хранения объектов. Реализация SNMP на основе Net-SNMP

Задача минимальными усилиями сделать так, чтобы поллинг был асинхронным

Реализация1 : все что работает пусть работает, лишнего не трогай

Кажется, нужно просто добавить парралелизма?

Я взял код синхронной версии поллера SNMP, изменил размеры массивов, немного переписал инициацию SNMP, чуть помучался с сильно возросшими требованиями по памяти, но получил псевдо-асинхронный режим работы:

Работал он примерно так:

Первая реализация парралельного поллингаПервая реализация парралельного поллинга

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

Схема сильно упрощена количество одновременных запросов 2 тысячи, и масштаб ожидания тоже другой. В реальности ожидание таймаута выглядит примерно так:

Ожидание таймаутов огромно по сравнению с нормальными ответамиОжидание таймаутов огромно по сравнению с нормальными ответами

Несмотря на простую реализацию, прирост скорости оказался примерно 100- кратным.

С установкой на продуктив появились особенности устройства, обладающие большим количеством элементов, стали опрашиваться нестабильно.

Но схема хорошо работала на большом количестве одинаковых небольших устройств.

Поэтому появилась вторая реализация:

Реализация2 : Синхронно-асинхронный режим работы

Анализ показал, что устройства с большим количеством метрик получают разом от десятков до сотен запросов, на часть из которых не отвечают. То есть нужно вводить сериализацию запросов для хостов. Перед началом цикла опроса запросы сортировать по хосту и для одного хоста задания выполнять одно за другим. Если случится тайм-аут или два подряд, то дальнейшие задания для этого хоста отбросить.

Стало лучше. Но проблемы с хостами с большим количеством метрик остались: все еще иногда фиксировались не ответы или потери элементов.

На количестве метрик больше 2-3 тысяч такая потеря происходила примерно в каждом цикле опроса и приходилось увеличивать количество попыток или отбрасывать элементы только после 3-4 неудачных опросов, что затягивало общий цикл съема.

В итоге, вторая реализация стала работать качественней, но потеряла в скорости. Стало ясно, что малой кровью не обойтись.

Реализация3 : Настоящая асинхронная

Это первая версия, которая могла считаться истинно асинхронной. Для ее реализации пришлось ввести полноценную машину состояний для каждой операции, благо в случае SNMP это протокол UDP и состояний немного.

Введение состояний позволило разсинхронизировать общую работу соединений и получать новые элементы данных по мере того, как появлялись свободные соединения:

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

Реализация3.5 : еще лучше, еще быстрее

Вины механизма поллинга в неответах не было. Проблема была в механизмах распределения задач. Один хост мог попасть в несколько асинхронных поллеров и в таком случае сразу несколько поллеров его начинали параллельно опрашивать.

Поэтому нужно было оптимизировать механизмы распределения задач на поллинг.

Сначала я сделал так, чтобы один хост гарантированно попадал в один и тот же поллер. Потери пропали, хотя иногда хосты с 3-4 тысячами метрик могли ожидать 2-4 минуты пока устройство отвечало на все запросы и такие метрики фиксировались как опаздывающие.

Появилась возможность для еще одной оптимизации я не закрывал в одном соединении сокет до тех пор, пока обрабатывал метрики одного и того-же хоста. Фаерволам стало немного легче. Но потом пришлось отказаться: некорректно работал библиотечный механизм таймаутов, который пришлось продублировать своим, но самое неприятное, случались утечки памяти в Net:SNMP.

В итоге, такими стараниями асинхронный поллинг смог достигать цифр 60-70 тысяч метрик в секунду. Дальше он выявил ряд проблем и узких мест в общей архитектуре, упираясь в блокировки больше, чем в ограничения поллинга.

Реализация4.0 : до основанья, а затем

Раз уж удалось гарантировать, что хосты из общей очереди задач всегда будут попадать в свои поллеры, то необходимость держать такие хосты в общей очереди задач отпала.

В 4 версии я реализовал получение сразу всего списка во внутреннюю очередь, с сопутствующей оптимизацией резолвинг и кеширование ДНС, макросов и конфигурации элемента данных делались на входе единоразово. Таким образом, сотни тысяч блокировок конфигурации в общей памяти трансформировались в одну две для выполнения массовой операции обновления элементов в течении достаточно долгого периода времени.

Версию 4.0 оказалось проще переписать заново, так как поллер стал сильно самостоятельным благодаря собственной очереди и опала необходимость подгонять его под логику работы классических поллеров. Еще одна диаграмма работы:

Тут снова не в масштабе расстояния между оранжевыми столбцами обновлениями конфигурации огромны, это минуты, нужно картинку удлинить в десять тысяч раз чтобы было пропорционально.

И осталось еще одно ограничение - количество исходящих портов. Так как серверу нужна еще прочая сетевая активность помимо SNMP, общее количество соединений ограничил в 48 тысяч.

Даже это - большая цифра. Поллер с таймаутом в 2 секунды при 100% неответов сможет проверить 15 хостов за 30 секунд в одном соединении или примерно 720 тысяч! хостов за 30 секунд в 48 тысяч соединений.

Эти цифры больше, чем устраивают, но, если нужно больше всегда можно решить с помощью конфигурации с несколькими IP адресами или RAW socket.

Сейчас такой поллинг в тестах упирается в соединения на отметке в 120-140 тысяч метрик в секунду.

На проде снимает около 30-40 тысяч метрик в секунду, работает в один поток, использует при этом 50% одного ядра.

Вывод:

От Реализации1 до Реализации4 прошло почти 2 года. Каждая реализация занимала по 2-3 человеко-недели.

Стоило оно того?

Как простое решение - можно же было просто поднять пачку контейнеров для скейла.

Думаю, что очень даже стоило.

Все, что снималось на 15 вспомогательных серверах, получилось снимать на одном и тот курит.

А мониторинг должен быть максимально простым, а лучше всего - сосредоточенным в одном сервере. Иначе он тоже претендент на выход из строя при инфраструктурных проблемах.

Мониторьте в радость.

Подробнее..

Управление наружным освещением

24.03.2021 00:15:52 | Автор: admin

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

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

Разбираемся с инфраструктурой

На практике мне встречалось несколько подходов к управлению наружным освещением: регламентированное включение и отключение силами оперативного персонала, применение реле времени, сумеречных датчиков, фотореле и астрономических реле.

Использование астрономических реле является, наверное, одним из самых интересных решений. Их работа основана на определении времени восходов и закатов в определенном географическом положении. Во время заката освещение включается, во время восхода - отключается. Как правило, при настройке таких реле имеется возможность установки временных корректировок для ускорения или замедления действия реле. Внесение таких корректировок позволяет включить (отключить) освещение на несколько минут позже заката или раньше рассвета.

По похожей схеме работает и модернизируемая нами система. В роли астрономического реле выступает свободно программируемый логический контроллер (ПЛК). По линии RS485 ПЛК управляет проприетарными модулями ввода-вывода, которые установлены в разных зданиях. Управление и настройка системы осуществляется с использованием SCADA и OPC-сервера, установленного на одной из машин в сети Ethernet, к которой подключен ПЛК. Все используемое ПО является проприетарным.

Выявленные недостатки и их причины

В ходе эксплуатации осветительных установок стало понятно, что система управления требует постоянного внимания персонала. По большому счету все сводилось к тому, что становилось очевидно: подсветка зданий включается слишком поздно, а отключается слишком рано. Эта проблема решалась корректировкой коэффициентов в системе диспетчеризации. Путем ручного подбора коэффициентов удавалось достигнуть времени включения и отключения, соответствующего городскому графику. Коэффициенты оставались неизменными до следующей подобной ситуации. А повторялись такие ситуации довольно часто.

Было сделано предположение, что причина проблемы кроется в проекте, загруженном в ПЛК. Ознакомиться с исходниками проекта не представлялось возможным. Из текстового описания проекта стало понятно, что для определения времени включения/отключения освещения используется функциональный блок, доступный в проприетарной среде программирования. Используя триальную версию этой среды, удалось получить доступ к справке и более подробному описанию этого блока. Это внесло некоторую ясность: функциональный блок высчитывает время, когда угол (высота) Солнца над горизонтом для заданного географического положения станет равен 0. Коэффициенты корректируют этот угол. Например, при коэффициенте "-6" будет высчитано время, когда Солнце окажется ниже горизонта на 6. Но в ходе проведенных экспериментов сложилось мнение, что функциональный блок производит расчеты не совсем так, как это предполагается. Дальнейшие работы в этом направлении были прекращены ввиду отсутствия универсальности такой реализации.

Начинаем модернизацию

При рассмотрении существующих вариантов, я склонялся к варианту управления по расписанию. Не секрет, что существуют общедоступные графики отключения наружного освещения. Для Москвы и Санкт-Петербурга, например - МОССВЕТ и ЛЕНСВЕТ. Обладая этой информацией несложно написать скрипт, который следит за временем и по графику управляет освещением. Тем более, что в сети Ethernet, к которой подключен ПЛК, имеется Linux-машина.

Для того чтобы такой скрипт мог управлять удаленными модулями ввода-вывода, потребовалось заново создать проект для ПЛК. По-сути ПЛК стал выступать в роли шлюза, что предоставило нам возможность управлять освещением по открытому протоколу Modbus TCP.

Для работы с Modbus будем использовать утилиту modpoll. Скачаем и распакуем ее на нашей Linux машине:

$ wget https://www.modbusdriver.com/downloads/modpoll.tgz$ tar xzf modpoll.tgz$ sudo cp modpoll/linux_x86-64/modpoll /usr/local/bin/

Теперь управлять освещением будем следующим образом:

#Включить освещение$ modpoll -m tcp -r 2 -t 0 -a 1 -p 502 192.168.0.227 1 1 1 1 1 1 1 1 #Отключить освещение$ modpoll -m tcp -r 2 -t 0 -a 1 -p 502 192.168.0.227 0 0 0 0 0 0 0 0 

Дело осталось за малым - вызывать эти команды по заранее сформированному расписанию. Как было упомянуто выше, подобные графики доступны и мы можем ими воспользоваться. Но появилось желание найти более универсальный подход, поэтому давайте вспомним о таком явлении, как "сумерки".

Сумерки

В сутках существуют периоды, называемые сумерки. Это время перед восходом Солнца и после заката, когда небо частично освещено рассеянным солнечным светом. Выделяют три вида сумерек: гражданские, навигационные и астрономические. Гражданские сумерки определяются как период, когда угол нахождения Солнца под горизонтом составляет от 050 до 6, навигационные сумерки от 6 до 12, а астрономические сумерки от 12 до 18.

Наибольший интерес для нас представляют навигационные сумерки. Именно в этот период освещение становится ближе к ночному, чем к вечернему, поэтому улицы городов нуждаются в искусственном освещении. Проще говоря, наружное освещение включается с началом навигационных сумерек (Солнце опускается ниже -6 ) и отключается с их окончанием (Солнце поднимается выше -6 ). Конечно стоит понимать, что в зависимости от погодных условий и в условиях городской застройки, включение может потребоваться раньше, чем Солнце опустится ниже -6 за горизонт.

Еще немного об астрономических реле.

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

Если управлять освещением, опираясь именно на фактическое положение Солнца, то такая проблема отсутствует.

Подробный и крайне наглядный рассказ о движении Солнца был найден на Youtube - Как солнце ходит по небу / How the sun moves across the sky (by daybit).

Положение Солнца и наружное освещение

Итак, для решения нашей задачи мы будем синхронизировать работу наружного освещения с положением Солнца. При наступлении навигационных сумерек - включение освещения, в момент начала гражданских - отключение. Так как в нашем распоряжении имеется Linux машина и соответственно Perl, то для расчета положения Солнца воспользуемся им. Загрузим необходимый нам модуль:

$ sudo cpan install Astro::Coord::ECI

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

#!/usr/bin/perl# Вычисление высоты Солнца над горизонтом в градусах в текущий момент# get_sun_elevation.pl 55.7558 37.6173 127# 55.7558 - широта в градусах# 37.6173 - долгота в градусах# 127 - высота над уровнем моря в метрахuse Astro::Coord::ECI::Sun;use Astro::Coord::ECI::Utils qw{:all};my ($lat, $lon, $elev) = (deg2rad($ARGV[0]), deg2rad($ARGV[1]), $ARGV[2]/1000);my $time = time ();my $loc = Astro::Coord::ECI->geodetic ($lat, $lon, $elev);my $sun = Astro::Coord::ECI::Sun->universal ($time);my ($azimuth, $elevation, $range) = $loc->azel ($sun);print rad2deg ($elevation), "\n";

Скрипт moscow_lights_ctrl.sh будет сравнивать заданное положение Солнца и его текущее положение в Москве. Если Солнце окажется ниже заданного угла, то отправим команду на включение, иначе - команду на отключение освещения:

#!/bin/sh[ -z "$1" ] && angle=-6 || angle=$1sun_angle=`./sun_pos.pl 55.751244 37.618423 124`if [ $(echo "$sun_angle >= $angle" |bc -l) -eq "0" ]; then  modpoll -m tcp -r 2 -t 0 -a 1 -p 502 192.168.0.227 1 1 1 1 1 1 1 1  exit 0fimodpoll -m tcp -r 2 -t 0 -a 1 -p 502 192.168.0.227 0 0 0 0 0 0 0 0

Опытным путем было определено, что на модернизируемом объекте потребность в наружном освещении возникает, когда Солнце опускается ниже -1.5. К слову, также было замечено, что городское освещение включается примерно в это же время.

С помощью cron будем выполнять moscow_lights_ctrl.sh каждую минуту:

# Если Солнце ниже 1.5 градусов - включение освещения, иначе - отключение* * * * * root /path/to/moscow_lights_ctrl.sh -1.5

Нам ничего не мешает создавать такие скрипты для любого географического положения. А когда возникнет необходимость расширения системы, мы сможем применить любое оборудование. Лично я склоняюсь к использованию модулей ввода-вывода, поддерживающих протокол Modbus TCP.

По большому счету все поставленные цели достигнуты. Модернизацию можно считать успешно завершенной.

ZABBIX

В ходе работ появились некоторые планы на ближайшее будущее, а именно настройка мониторинга работы оборудования. Возможности такого мониторинга сильно зависят от степени готовности самих инженерных систем. Например, мы можем следить за положением силового контактора и контролировать включение освещения. Или получать значение силы тока и тем самым определять, сколько ламп вышло из строя и т.д. К сожалению, на текущий момент к полноценному мониторингу модернизируемая система не готова. Тем не менее, для задела на будущее было решено использовать уже существующую на предприятии систему мониторинга - ZABBIX.

Все принципы работы остаются неизменными. Мы лишь перенесем всю описанную выше логику управления в ZABBIX.

Шаблон для ZABBIX

Создадим шаблон astro_outdoor_lighting для Zabbix со следующими макросами:

  • {$CIVIL_DEGREES} - Окончание и начало гражданских сумерек в градусах. Включение и отключение наружного освещения,

  • {$ELEV} - Высота над уровнем моря в метрах,

  • {$LAT} - Широта в градусах,

  • {$LON} - Долгота в градусах.

Элементы данных

Шаблон содержит только один элемент данных - elevation. Этот элемент следит за положением солнца в заданном географическом положении.

Чтобы получать текущее положение Солнца, элемент осуществляет внешнюю проверку через ранее созданный скрипт get_sun_elevation.pl.

/usr/lib/zabbix/externalscripts/get_sun_elevation.pl
#!/usr/bin/perl# Вычисление высоты Солнца над горизонтом в градусах в текущий момент# get_sun_elevation.pl 55.7558 37.6173 127# 55.7558 - широта в градусах# 37.6173 - долгота в градусах# 127 - высота над уровнем моря в метрахuse Astro::Coord::ECI::Sun;use Astro::Coord::ECI::Utils qw{:all};my ($lat, $lon, $elev) = (deg2rad($ARGV[0]), deg2rad($ARGV[1]), $ARGV[2]/1000);my $time = time ();my $loc = Astro::Coord::ECI->geodetic ($lat, $lon, $elev);my $sun = Astro::Coord::ECI::Sun->universal ($time);my ($azimuth, $elevation, $range) = $loc->azel ($sun);print rad2deg ($elevation), "\n";

Подробности настройки внешних проверок в ZABBIX смотрите в документации.

Триггеры

Единственный триггер civil_twilight_dawn срабатывает по окончании гражданских сумерек, т. е. в момент, когда возникает необходимость в работе наружного освещения.

Шаблон созданного макроса доступен на github.

Добавляем узел сети

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

Скрипты и действия ZABBIX

В разделе [Администрирование]->[Скрипты] создадим глобальные скрипты с говорящими названиями facade light off и facade light on.

Когда триггер civil_twilight_dawn переходит в состояние "Проблема", нам необходимо включить наружное освещение, т.е. выполнить скрипт facade light on. После восстановления триггера освещение необходимо отключить, для чего потребуется вызвать скрипт facade light off. Поэтому в разделе [Настройки]->[Действия] мы создадим действие facade light, реализующее необходимое нам поведение системы.

Подобным же образом добавляем скрипты и действия для каждого узла сети.

На этом настройку ZABBIX сервера для управления установками наружного освещения можно считать завершенной.

Заключение

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

Как мне видится, даже в простейшем варианте (работа по cron) такой подход перекрывает потребности большинства подобных типовых задач в крупных коммерческих и административных зданиях. В плане экономической конкурентоспособности он тоже выглядит вполне достойно. Когда на объекте требуется более одного астрономического реле, реле времени и т. п., то их стоимость может быть вполне ощутимой. Кроме этого, чаще всего эти элементы управления разнесены по разным частям зданий и добиться их синхронной работы - не такая простая задача, как это может показаться.

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

Конечно, все вышесказанное актуально при наличии какой-никакой IT инфраструктуры. Но, как правило, она имеется.

На этом все. Спасибо за внимание!

Подробнее..

Как я мониторил РИП-12 от Bolid

28.04.2021 02:24:00 | Автор: admin

Резервированные источники питания используются повсеместно. Они обеспечивают бесперебойным электропитанием приборы охранной и пожарной сигнализации, оборудование систем контроля доступа и другие системы. На нашем предприятии в качестве таких источников, как правило, используются приборы от ЗАО НВП Болид. У некоторых из них, как, например, у РИП-12-6/80M3-R-RS, имеется интерфейс RS485, что позволяет включать их в систему мониторинга.

Средства мониторинга

Мы используем Zabbix 5.2. Получать данные от РИП будем по протоколу Modbus RTU over TCP. Поддержка этого протокола реализована в Zabbix с помощью загружаемого модуля libzbxmodbus. Также в процессе мониторинга принимают участие преобразователь протокола C2000-ПП (вер. 1,32) в режиме Master и преобразователь последовательных интерфейсов (RS485 в Ethernet).

Объекты мониторинга

Для начала определимся, что конкретно мы сможем контролировать. Из документации к РИП-12-6/80M3-R-RS и С2000-ПП выяснилось, что рассчитывать мы можем на получение состояния семи зон (ШС) и числовых значений тока и напряжения. В ходе экспериментов мне удалось воспроизвести следующие состояния ШС:

ШС 0 Состояние прибора

149

Взлом корпуса прибора

Корпус РИП открыт

152

Восстановление корпуса прибора

Корпус РИП закрыт

250

Потеряна связь с прибором

Потеряна связь с прибором

ШС 1 Выходное напряжение

193

Подключение выходного напряжения

РИП подключил выходное напряжение при появлении напряжения в сети

192

Отключение выходного напряжения

РИП отключил выходное напряжение при отсутствии напряжения в сети и разряде батареи

199

Восстановление питания

Напряжение питания прибора пришло в норму

250

Потеряна связь с прибором

Потеряна связь с прибором

ШС 2 Ток нагрузки

194

Перегрузка источника питания

Выходной ток РИП более 7,5 А

195

Перегрузка источника питания устранена

Выходной ток РИП менее 7,5 А

250

Потеряна связь с прибором

Потеряна связь с прибором

ШС 3 и ШС 4 Напряжение на батарее 1 и 2 соответственно

200

Восстановление батареи

Напряжение батареи выше 10 В, заряд батареи возможен

202

Неисправность батареи

Напряжение на батарее ниже 7 В или не подключена

211

Батарея разряжена

Напряжение на батарее ниже 11 В при отсутствии сетевого напряжения

250

Потеряна связь с прибором

Потеряна связь с прибором

ШС 5 Степень заряда батарей

196

Неисправность зарядного устройства

ЗУ не обеспечивает напряжение и ток для заряда батареи в заданных пределах

197

Восстановление зарядного устройства

ЗУ обеспечивает напряжение и ток для заряда батареи в заданных пределах

250

Потеряна связь с прибором

Потеряна связь с прибором

ШС 6 Напряжение сети

1

Восстановление сети 220

Сетевое напряжение питания < 150 В или > 250 В

2

Авария сети 220 В

Сетевое напряжение питания в пределах 150250 В

250

Потеряна связь с прибором

Потеряна связь с прибором

Крайне вероятно, что мной была получена только часть из всех возможных состояний. Например, имеются догадки, что ШС 3 и 4 должны также иметь состояние [204] Необходимо обслуживание, а ШС 0 - состояние [203] Сброс прибора и другие. К сожалению, чтение документации ситуацию не прояснило. В связи с этим нам необходимо следить и реагировать на появление событий, которые мы не предусмотрели.

Конфигурирование устройств

Не будем долго останавливаться на процессе конфигурирования приборов, только коротко рассмотрим перечень необходимых действий. Настройка устройств Болид осуществляется при помощи утилиты UProg и имеет следующий порядок:

  1. Назначение сетевых адресов всем устройствам (РИП и С2000-ПП),

  2. Конфигурирование интерфейса интеграции С2000-ПП (Modbus RTU),

  3. Добавление ШС, описанных выше, в таблицу зон С2000-ПП. Крайне важно, чтобы, во-первых, были добавлены все ШС, а во-вторых, ШС должны следовать друг за другом в порядке возрастания.

UProg. Конфигурация С2000-ППUProg. Конфигурация С2000-ПП

При заполнении таблицы зон следует помнить следующее:

  • адрес прибора - сетевой адрес РИП, в нашем случае 126,

  • номер ШС - номер ШС от 0 до 6,

  • тип зоны - тип ШС, для ШС 0 назначаем тип зоны "3 - состояние прибора", для всех остальных - "8-РИП напряжение / ток".

Создаем шаблоны Zabbix

Напомню, что Zabbix с модулем libzbxmodbus выступает в роли Modbus-мастера. Из-за особенностей получения данных от C2000-ПП, о которых речь пойдет в процессе создания шаблонов, мы будем рассматривать два подхода к мониторингу.

  • мониторинг состояния ШС.

  • мониторинг как состояния, так и числовых параметров РИП.

Мониторинг состояния ШС

Итак, создадим шаблон RIP 12 mod 56 RIP 12 6 80 M3 R RS. Шаблон имеет один элемент данных с именем Request и типом "Простая проверка". Ключом элемента является функция: modbus_read[{$MODBUS_PORT},{$MODBUS_SLAVE},{$STATUS_REG},3,7*uint16] . В параметрах функции используются значения макросов, которые позволяют составить корректный modbus запрос к C2000-ПП.

  • {MODBUS_PORT} - тип используемого протокола (enc - Modbus RTU over TCP), адрес и порт преобразователя последовательных интерфейсов.

  • {MODBUS_SLAVE} - Modbus UID С2000-ПП (настраивается в UProg на вкладке прибор).

  • {STATUS_REG} - адрес регистра в котором расположен ШС 0 интересующего нас РИПа. Получить данный адрес можно следующим образом: "Номер зоны в таблице зон С2000-ПП" + 40000 - 1. В нашем примере это: 450+40000-1 = 40449.

Основная задача элемента Request - запросить у С2000-ПП значение всех семи ШС контролируемого РИП и предоставить их в формате JSON. Результирующий JSON содержит объекты, ключами которых являются адресы регистров С2000-ПП, а значениями - содержимое этих регистров:

{  "40449":39115,  "40450":51195,  "40451":50171,  "40452":51963,  "40453":51451,  "40454":50683,  "40455":763}

Зависимые элементы данных

Элемент данных Request имеет 7 зависимых элементов. Основная задача этих элементов - распарсить JSON и получить состояние каждого ШС индивидуально. Вот эти элементы:

  • Status - состояние прибора (ШС 0),

  • Uout - выходное напряжение (ШС 1),

  • Iout - ток нагрузки (ШС 2),

  • Ubat1 - напряжение АКБ1 (ШС 3),

  • Ubat2 - напряжение АКБ2 (ШС 4),

  • Capacity - степень заряда АКБ (ШС 5),

  • Uin - напряжение сети (ШС 6).

Предобработка зависимых элементов данных

Чтобы получить состояние ШС 0 (Status), нам достаточно два шага предобработки. На первом шаге мы воспользуемся стандартным функционалом JSONPath, а затем разделим полученное значение на 256, тем самым получим код состояния.

К сожалению, мне не удалось использовать математические операции в параметрах JSONPath. Поэтому для оставшихся элементов данных пришлось использовать javascritpt-предобработку. Например, для элемента данных Iout (ШС 2) javascript-предобработка выглядит так:

function (value){    var reg = parseInt({$STATUS_REG})+2;    var data = JSON.parse(value);    return data[reg];}

Триггеры

После добавления триггеров создание шаблона можно считать завершенным. Перечень созданных триггеров:

  1. Взлом корпуса прибора,

  2. Перегрузка источника питания,

  3. Отключение выходного напряжения,

  4. Неисправность батареи АКБ1,

  5. Неисправность батареи АКБ2,

  6. АКБ1 разряжен,

  7. АКБ2 разряжен,

  8. Авария сети 220 В,

  9. Потеряна связь с прибором,

  10. Неизвестное состояние Status,

  11. Неизвестное состояние Iout,

  12. Неизвестное состояние Uout,

  13. Неизвестное состояние АКБ1,

  14. Неизвестное состояние АКБ2,

  15. Неизвестное состояние Capacity,

  16. Неизвестное состояние Uin,

  17. Превышено время отсутствия по MODBUS.

Демонстрация и импорт RIP 12 mod 56 RIP 12 6 80 M3 R RS

Шаблон RIP 12 mod 56 RIP 12 6 80 M3 R RS в картинкахШаблон RIP 12 mod 56 RIP 12 6 80 M3 R RS в картинкахПример создания узла сетиПример создания узла сети

Ссылки для импорта: Шаблон RIP 12 mod 56 RIP 12 6 80 M3 R RS, Преобразование значений RIP 12 mod 56 RIP 12 6 80 M3 R RS.

Мониторинг состояния и числовых параметров

Мониторинг числовых параметров имеет свои особенности. Все дело в том, что для получения числового значения нам необходимо сделать два modbus-запроса к С2000-ПП. Первый запрос устанавливает зону для запроса тока или напряжения, второй - непосредственное получение значения. В таком случае мы не имеем возможности использовать функционал libzbxmodbus, т.к. попросту не cможем гарантировать правильную очередность запросов.

Первое и самое простое, что приходит на ум, - это создать скрипт, который сделает получение числового параметра атомарной операцией и воспользоваться возможностями внешних проверок Zabbix. Но такой скрипт тоже не позволит использовать загружаемый модуль libzbxmodbus по причине невозможности организации монопольного доступа к разделяемому ресурсу, в нашем случае к преобразователю последовательных интерфейсов.

В связи с вышесказанным, для этих целей было решено отказаться от использования libzbxmodbus и написать скрипт, который сможет предоставлять и числовые параметры РИП и состояния его ШС.

Пишем shell скрипт для внешней проверки

Для того, чтобы синхронизировать доступ к преобразователю последовательных интерфейсов, воспользуемся утилитой flock. Работу с Modbus будем осуществлять при помощи modpoll. В /usr/lib/zabbix/externalscripts создадим скрипт rip_12_mod_56.sh

#!/bin/bash# rip_12_mod_56.sh# $1 - protocol://host:port# $2 - Modbus UID# $3 - Status register# $4 - Offset (0 - 6)# Example of requesting statuses:       ./rip_12_mod_56.sh enc://127.0.0.1:4001 1 40000# Example value request:                ./rip_12_mod_56.sh enc://127.0.0.1:4001 1 40000 3(($# < 3)) && { printf '%s\n' "You have given little data. Command exited with non-zero"; exit 1; }lockfile=$(echo "$1" | awk -F "://" '{print $2}')setzone(){        modpoll -m $1 -a $4 -r 46181 -0 -1 -c 1 -p $3 $2 $5> /dev/null 2>&1    (($? != 0)) && { printf '%s\n' "Command exited with non-zero"; exit 1; }    sleep 0.15}getvalue (){        value=$(modpoll -m $1 -a $4 -r 46328 -0 -1 -c 1 -t 4:hex -p $3 $2 |grep ]: |awk '{print $2}')        printf "%d" $value}getstatus (){        status=$(modpoll -m $1 -a $4 -r $5 -1 -c 7 -t 4:hex -p $3 $2 | grep ]: | awk -F "0x" 'BEGIN { printf"["} NR!=7{printf "\""$2"\","} NR==7 {printf "\""$2"\""} END { printf "]"}')    echo "{ \"status\": $status }"}(        flock -e 200        protocol=$(echo $1 | awk -F "://" '{print $1}');        host=$(echo $1 | awk -F "://" '{print $2}' | awk -F ":" '{print $1}')        port=$(echo $1 | awk -F "://" '{print $2}' | awk -F ":" '{print $2}')        register=$(($3+1))        if (($# >= 4)); then                zone=$(($register+$4-40000))                setzone $protocol $host $port $2 $zone                echo $(getvalue $protocol $host $port $2)                sleep 0.15                exit 0        fi        echo $(getstatus $protocol $host $port $2 $register)        sleep 0.15;) 200> /tmp/$lockfile

Подробности настройки внешних проверок в Zabbix уточняйте в документации.

Создаем RIP 12 mod 56 RIP 12 6 80 M3 R RS EXTENDED

Для получения информации о состоянии ШС шаблон содержит элемент данных Request с типом "Внешняя проверка". Ключом элемента является скрипт: rip_12_mod_56.sh[{$MODBUS_PORT}, {$MODBUS_SLAVE}, {$STATUS_REG}]. Как и в шаблоне RIP 12 mod 56 RIP 12 6 80 M3 R RS, задача элемента Request - сформировать JSON с состояниями всех ШС.

Возвращаемый JSON оптимизирован для использования функционала JSONPath. Для упрощения скрипта значения возвращаются в шестнадцатеричной форме:

{  "status": ["98CB","C7FB","C3FB","CAFB","C8FB","C5FB","02FB"]}

Состояния ШС. Снова зависимые элементы данных.

Как и в предыдущем шаблоне, элемент данных Request имеет 7 зависимых элементов. Задача этих элементов тоже неизменна - распарсить JSON и получить состояние каждого ШС.

Получаем числовые значения

Для получения числовых значений создадим 5 элементов данных с типом "Внешняя проверка".

  • Uout_value - значение выходного напряжения, В.

  • Iout_value - значение выходного тока, А.

  • Ubat1_value - значение напряжения на батарее 1, В.

  • Ubat2_value - значение напряжения на батарее 2, В.

  • Uin_value -значение напряжения сети, В.

Ключом этих элементов является скрипт: rip_12_mod_56.sh[{$MODBUS_PORT}, {$MODBUS_SLAVE}, {$STATUS_REG}, <НОМЕР ШС>].

Триггеры

Перечень триггеров не отличается от триггеров, созданных в шаблоне RIP 12 mod 56 RIP 12 6 80 M3 R RS.

Демонстрация и импорт RIP 12 mod 56 RIP 12 6 80 M3 R RS EXTENDED

Шаблон RIP 12 mod 56 RIP 12 6 80 M3 R RS EXTENDED в картинкахШаблон RIP 12 mod 56 RIP 12 6 80 M3 R RS EXTENDED в картинкахПоследние значения RIP 12 mod 56 RIP 12 6 80 M3 R RS EXTENDEDПоследние значения RIP 12 mod 56 RIP 12 6 80 M3 R RS EXTENDED

Ссылки для импорта: Шаблон RIP 12 mod 56 RIP 12 6 80 M3 R RS EXTENDED, rip_12_mod_56.sh.

Вместо заключения

В своем мониторинге мы используем шаблон RIP 12 mod 56 RIP 12 6 80 M3 R RS. По-большому счету причина такого решения одна - расширяемость системы. Использование загружаемого модуля позволяет включать в одну линию приборы разных типов и модификаций, организовать их мониторинг стандартными средствами. Кроме этого, большой потребности в получении числовых значений у нас пока не возникало.

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

Спасибо за внимание!

Подробнее..

Zabbix OPC DA

25.05.2021 00:13:35 | Автор: admin

В последних релизах Zabbix "из коробки" стал поддерживать некоторые популярные протоколы промышленного оборудования. Имея поддержку Modbus и MQTT, его использование с системами промышленной автоматизации стало чуточку проще. Но подобный подход к мониторингу такого рода оборудования не всегда возможен.

Как правило, на предприятиях используется большое количество устройств промышленной автоматики разных лет и от разных производителей, поддерживающих разные протоколы обмена. OPC серверы являются универсальным инструментом обмена данными с такими устройствами. Информация на тему интеграции Zabbix и OPC DA в сети практически отсутствует. Возможно, мой небольшой опыт в этом направлении окажется полезен.

Для чего нам Zabbix

В нашем сценарии использования Zabbix последний не является заменой имеющейся SCADA-системе. Параллельное развертывание системы мониторинга позволит иметь возможность гибкой настройки триггеров и своевременного получения оповещений о нештатных ситуациях на оборудовании. Также мы сможем создавать дополнительные информационные панели с графиками, которые смогут давать быстрое представление о ходе тех. процессов.

Взаимодействие с OPC серверами

Самой сложной задачей, которая стоит перед нами, является организация взаимодействия с OPC-серверами. В ходе поисков готового решения такого взаимодействия стало понятно, что подходящих нам вариантов не так много. Из того, что было найдено, наиболее пригодным к использованию оказался консольный клиент OpenOPC.

Установка OpenOPC

Как было сказано ранее, речь идет о стандарте OPC DA, а значит, о технологии DCOM и, соответственно, ОС Windows. В нашем случае установка OpenOPC производилась на машину с Windows XP, где и находится проприетарный OPC сервер. После завершения установки необходимо добавить путь до opc.exe в системную переменную среды PATH.

Проверим работу утилиты. Для начала выведем в консоль список доступных OPC серверов:

C:\Users\Администратор> opc.exe -qMerz.OPC_SAIA_S-BUS.1C:\Users\Администратор>

Теперь попробуем получить теги в удобном нам формате - csv:

C:\Users\Администратор>opc.exe -o csv -s Merz.OPC_SAIA_S-BUS.1 ATP.Register.OAT ATP.Register.OAT,197,Good,05/24/21 07:16:15C:\Users\Администратор>opc.exe -o csv -s Merz.OPC_SAIA_S-BUS.1 ATP.Register.OAT ATP5.Register.T_inlet ATP5.Register.T_outletATP.Register.OAT,198,Good,05/24/21 07:16:41ATP5.Register.T_inlet,627,Good,05/24/21 07:16:41ATP5.Register.T_outlet,654,Good,05/24/21 07:16:41C:\Users\Администратор>

Если что-то пошло не так

В ходе экспериментов с opc.exe выяснились некоторые моменты. Первое: каждый OPC клиент запускал новую копию OPC сервера, а их параллельная работа невозможна. Так как запустить используемый нами OPC сервер как службу не получилось, то через DCOM был настроен запуск OPC сервера от определенного пользователя. Все OPC клиенты - SCADA и агент Zabbix - были также настроены на запуск от этого пользователя. Второе: выявлены некоторые недостатки в работе самого OpenOPC. Например, клиент не вычитывает теги, в названии которых присутствуют символы, отличающиеся от латинских. С этим пока пришлось смириться и решать такие проблемы путем переименования тегов в OPC сервере.

Установка Zabbix агента

На ту же машину установим Zabbix агент, который сможет работать под Windows XP, например, zabbix_agent-5.2.0-windows-i386-openssl.msi. Агент будет выполнять активные проверки. Чтобы облегчить дальнейшую конфигурация агента, во время установки заполним следующие поля:

  • Ноst name - уникальное имя хоста, совпадающее с именем узла сети на Zabbix сервере.

  • Zabbix server IP/DNS - IP-адреса Zabbix сервера.

  • Server or Proxy for active checks - IP-адрес Zabbix сервера для активных проверок.

Конфигурирование Zabbix агента

В конфигурационный файл C:\Program Files\Zabbix Agent\zabbix_agentd.conf были внесены некоторые изменения.

  1. Увеличено время выполнения скрипта.

    ### Option: Timeout#Spend no more than Timeout seconds on processing.## Mandatory: no# Range: 1-30# Default:# Timeout=3Timeout=30
    
  2. Создан параметр для мониторинга.

    #User-defined parameter to monitor. There can be several user-defined parameters.#Format: UserParameter=<key>,<shell command>## Mandatory: no# Default:# UserParameter=UserParameter=opc[*],opc.exe -o csv -s $1 $2
    

Узел сети и элементы данных на сервере Zabbix

На Zabbix сервере создадим узел сети. Имя узла сети должно совпадать с Ноst name, указанном при установке агента, интерфейс - IP-адрес агента.

Далее к созданному узлу сети добавим элемент данных c типом Zabbix агент (активный). Ключом должна являться конструкция типа: opc[<ИМЯ OPC СЕРВЕРА>, <ЗАПРАШИВАЕМЕ ТЕГИ ЧЕРЕЗ ПРОБЕЛ>].

Значениями элемента данных будут строки, разделенные запятыми:

ATP2.Register.OAT,273,Good,05/24/21 15:21:33ATP2.Register.GVS.T_inlet_W,501,Good,05/24/21 15:21:33ATP2.Register.GVS.T_outlet_W,445,Good,05/24/21 15:21:33ATP2.Register.T_outlet_w_com,404,Good,05/24/21 15:21:33ATP2.Register.RAD.T_outlet_W,256,Good,05/24/21 15:21:33ATP2.Register.P_in_W_com,39,Good,05/24/21 15:21:33ATP2.Register.P_out_W_com,36,Good,05/24/21 15:21:33ATP2.Register.RAD.P_outlet_W,43,Good,05/24/21 15:21:33ATP2.Register.FIRE.P_gidrant,68,Good,05/24/21 15:21:33

Зависимые элементы данных

Создадим зависимые элементы данных для того, чтобы распарсить CVS, полученный в самом элементе.

В предобработке используем JavaScript, который получит необходимую нам строку в CVS, проверит качество тега и вернет результат.

function (value){    var nr_line = 4;    var lines = value.split('\n');    var fields = lines[nr_line].split(',');    if(typeof fields[2] != "undefined" &&  fields[2] == "Good"){    return (typeof fields[1] != "undefined") ? fields[1] : null;    }    return null;}

Пример визуализации полученных данных:

Заключение

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

Подробнее..

Эмулятор ИБП с протоколами Megatec и Voltronic

11.05.2021 08:07:02 | Автор: admin

Ряд наших устройств имеет встроенный порт RS-232 для считывания данных с источников бесперебойного питания (ИБП) по двум наиболее распространённым протоколам обмена Megatec и Voltronic. Для облегчения тестирования устройств мы разработали небольшую программу-эмулятор. Именно о ней дальше и пойдёт речь.

Протоколы Megatec и Voltronic текстовые и довольно простые. Обмен данными ведётся на низкой скорости 2400 бит/сек, 8 бит данных, без контроля чётности по принципу запрос-ответ. Запросы представляют собой текстовые строки длиной от одного до трёх символов, оканчивающихся байтом перевода строки (код 0x0D). Ответы приходят также в текстовом виде с завершающим символом 0x0D. Значения в ответах разделяются пробелами. Числа могут передаваться либо с незначащими нулями в начале, либо с дополнительными пробелами.

В зависимости от конкретного ИБП таких команд может быть разное количество, но основную информацию можно получить при помощи четырёх из них. Рассмотрим их подробнее.

Q1 запрос текущего состояния
Ответ ИБП:
(MMM.M NNN.N PPP.P QQQ RR.R S.SS TT.T b7b6b5b4b3b2b1b0
( начальный символ.
MMM.M входное напряжение, В.
NNN.N напряжение, при котором последний раз был осуществлён переход на работу от батареи, В.
PPP.P выходное напряжение, В.
QQQ потребляемая мощность, %.
RR.R частота сети, Гц.
SS.S напряжение на батарее, В. Оно может передаваться в двух форматах: SS.S для линейно-интерактивных ИБП или S.SS для онлайн-ИБП (указывается напряжение на одном элементе).
TT.T температура ИБП, C.
b7...b0 статусные биты, которые могут принимать значение 0 или 1.
b7 1 : работа от АКБ, 0 : работа от сети.
b6 1 : низкий уровень заряда АКБ, 0 : АКБ в норме.
b5 1 : байпас включён, 0 : байпас выключен (только для онлайн-ИБП).
b4 1 : авария ИБП, 0 : ИБП в норме.
b3 1 : линейно-интерактивный ИБП, 0 : онлайн-ИБП.
b2 1 : запущен тест ИБП.
b1 1 : ИБП выключен, 0 : ИБП включён.
b0 1 : звуковой сигнал включён, 0 : выключен.

I запрос информации об ИБП
Ответ ИБП:
#CompanyName Model Version
# начальный символ.
CompanyName производитель ИБП.
Model название модели.
Version версия ИБП.

F запрос информации о номинальных параметрах ИБП
Ответ ИБП:
#MMM.M QQQ SS.SS RR.R
# начальный символ.
MMM.M номинальное выходное напряжение, В.
QQQ номинальный выходной ток, А.
SS.SS номинальное напряжение АКБ, В (может быть в форматах SS.SS или SSS.S).
RR.R номинальная частота выходного напряжения, Гц.

QBV запрос информации об АКБ
Ответ ИБП:
(RRR.R NN MM CCC TTT
( начальный символ.
RRR.R номинальное напряжение АКБ, В.
NN количество батарей в АКБ, шт.
MM количество параллельных групп батарей, шт.
CCC ёмкость АКБ, %.
TTT оставшееся время работы от АКБ, мин.

Помимо команд, которые считывают какие-либо параметры ИБП, есть ещё управляющие команды. Часто используются такие:
T запуск теста АКБ на 10 сек.
TL запуск теста АКБ до полного разряда.
T<n> запуск теста АКБ на заданное количество минут.
CT остановка теста АКБ.
Q включение/отключение звукового сигнала ИБП.

На первый взгляд вышеописанные команды очень простые, но дьявол, как обычно, кроется в мелочах. Например, некоторые ИБП вообще не выдают ответы на команды I и QBV. Примером может служить ряд моделей от Ippon.

Также замечено, что различные ИБП выполняют команду Q (управление звуковым сигналом) за совершенно разное время. То есть от момента выдачи команды Q и до момента смены бита b0 в ответе на команду Q1 может пройти до 30 сек!!! А так как включение и выключение осуществляется одной командой, то при автоматизированном управлении может начаться колебательный процесс. Например, контроллеру через Web-интерфейс задаётся выключенное состояние звукового сигнала. Он анализирует текущее состояние ИБП (по флагу b0), и если оно отличается от нужного, то подаёт команду Q. При следующем запросе Q1 контроллер опять проверяет флаг b0 и видит, что он не поменялся. В результате он опять подаёт команду Q. Но ИБП всё это время на самом деле что-то там у себя внутри обдумывал, поэтому не сразу среагировал на первую Q, а тут уже пришла и вторая. В результате звуковой сигнал может остаться включённым. И, более того, в некоторых ИБП при смене статуса звукового сигнала осуществляется короткий бип. А из-за такого колебательного процесса эти бипы могут издаваться много раз, пока наконец контроллер и ИБП не синхронизируются.

Мы решили эту проблему просто смену состояния звукового сигнала проводим только раз в минуту. За это время у ИБП внутри уже всё устаканится.

Ещё один интересный момент заключается в расчёте оставшейся ёмкости АКБ. Считается она по упрощённой формуле:

BatCap = \frac{U - U_{min}}{U_{max} - U_{min}}\times100\%

Здесь:
U текущее напряжение АКБ.
Umin минимально допустимое напряжение на АКБ (обычно около 10В).
Umax напряжение заряженной АКБ (обычно 13,8...14,2В).

Этого обычно достаточно для оценки оставшегося заряда.

Протокол Voltronic на множестве указанных выше команд отличается только одной из них вместо кода Q1 используется QS. При этом форматы ответов совпадают. В наших устройствах реализовано автоматическое определение протокола обмена как раз на основе данного отличия. Контроллер при включении пробует посылать по очереди команды Q1 и QS. На какую приходит ответ, тот протокол дальше и используется. Если в течение определённого тайм-аута на команду перестают приходить ответы (был подключён другой ИБП на горячую), то определение протокола автоматически запускается заново.

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

Она представляет из себя экран с настройками и выбором COM-порта, через который будет осуществляться обмен. Поддерживаются все указанные выше команды, в том числе и для запуска тестов:

Работа с программой нее вызовет затруднений. Менять любые параметры можно прямо в процессе работы, и тут же видеть результат:

Для оценки работы программы в динамике я записал небольшое видео:

Саму программу эмулятора можно скачать здесь.

Подробнее..

Проблемы мониторинга дата-пайплайнов и как я их решал

16.06.2021 00:20:01 | Автор: admin

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

В этом деле проблем можно ждать откуда угодно и на каждом шаге: источник данных прилег, данные пришли битые, источник без объявления войны поменял формат данных или доступ к ним, хранилище тупит, данных внезапно стало меньше или больше и много других приколюх.

Чтобы понять, как все это мониторить, давайте разберемся кто вообще работает с данными, которые мы с таким трудом намайнили:

Бизнес - это все те люди, которые не особо разбираются в инженерии, но принимают важные решения, основываясь на добытых нами данных: увеличить ли расходы на рекламу, как быстро увеличивать размер аудитории для раскатывания апдейта, как работают различные партрнеры и т.п.

Технари - это мы, инженеры, можем запустить руки в логи, доработать логику, следим, чтобы ничего не падало без острой необходимости.

Код - запускается следующий в цепочке пайплайн, происходят преобразования, рисуются графики и т.п.

Дата-пайплайны могут слегка отличаться от классического бэкенда - если упал какой-то из пайплайнов, это не значит, что все плохо и нужно бежать немедленно чинить, данные могут определенное время продолжать оставаться актуальными. Вы тут скажете, что бэкенд тоже может успешно падать частями, так-то оно так, но я в данном контексте рассматриваю бэкенд и дата-пайплайн как одну логическую сущность, а не набор дублирующих микросервисов и баз с репликациями.

Вот примеры:

  • Пайплайн отрабатывает каждые 10 минут, а люди смотрят в отчеты, в среднем, раз в час. Падение одной из джоб не критично, да и если источник данных прилег, тут все равно ничего не поделаешь.

  • Пайплайн стучится в источник с надеждой получить свежие данные, которые появляются в API источника с неопределенной задержкой (привет Apple), пайплан может успешно завершиться как скачав отчет, так и получив сообщение о том, что отчета еще нет. Тут, конечно, можно делать бесконечные ретраи внутри, либо просто ронять пайплайн, но тогда не особо очевидно будет, по какой причине он упал - что-то пошло не так, или данные в источнике еще не подтянулись.

  • Пайплайн работает слишком долго - это может быть как разовой проблемой из-за тормозов в сети или в источнике, так и постоянной проблемой: что-то сломалось в трансформации, или ретраев стало больше чем нужно, в любом случае требуется вмешательство человека.

ETL как он естьETL как он есть

И тут вы скажете, но в том же Airflow есть замечательная система мониторинга, которая показывает и время работы джобы, и количество упавших или требующих перезапуска задач, и т.п. И я соглашусь, отчасти...

Чего не хватает во встроенных мониторингах систем работы с данными:

  • Бизнес не может просто посмотреть в модный мониторинг типа того же Airflow или ELK и понять, можно или нельзя доверять данным, актуальность состояния данных непрозрачна.

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

  • Нет возможности собрать реальную статистику и проанализировать, где самое слабое место. Просто считать инциденты не вариант, т.к. важнее не количество инцидентов, а время, в течение которого состояние данных было неактуальным. Знаю, что такие проблемы некоторые компании решают самописными парсерами логов или подсчетом пиков-просадок на графиках (напишите, как это реализовано у вас).

Все это превращается в такие вот проблемы:

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

  2. Люди из бизнеса хотят более наглядного отображения состояния данных и системы, чем оно представлено в технических мониторингах.

  3. Статистика, если и собирается, то собирается по техническим проблемам и нельзя понять, насколько эти технические проблемы повлияли на бизнес.

Концепция

Чтобы решить некоторые из проблем, я написал простую систему мониторинга, прикинув, что идеально было бы получать от процессов события, а затем анализировать их количество, отправленное значение, продолжительность и разные временные интервалы между началом и концом событий. Этот мониторинг, после некоторого тестирования локально, я решил выкатить в паблик, назвав его Sensorpad.

Смотрите, сколько всего можно мерять, получая простые запросы в вебхук.Смотрите, сколько всего можно мерять, получая простые запросы в вебхук.

Почему вообще вебхуки?

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

После того, как мы начали отсылать из процессов события, нужно их проанализировать и получить ответы на всякие важные вопросы, например (все числа абстрактны):

  • запустилась ли наша задача 10 раз за последний день?

  • не превышает ли количество падений (определяем падение, если полученное значение > 0, например) 15% от всех запусков за сегодня?

  • нет ли процессов, которые длятся больше 20 минут?

  • не прошло ли больше часа с момента последнего успешного завершения?

  • стартовало ли событие по планировщику в нужное время?

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

Реализация

Я начал с дашборда, дизайн - не моя профессия, так что просто взял за основу дашборд, показывающий состояние крон-джобов на сайте Nomadlist, у меня получилось как-то так:

Дашборд состояния серверов Sensorpad средствами SensorpadДашборд состояния серверов Sensorpad средствами Sensorpad

Каждый монитор на этом дашборде - это комбинация метрик, которые должны быть понятны и бизнесу, и инженерам.

Для примера попробуем настроить мониторинг для чего-то, что понятно даже тем, кто не знаком с дата-инженерингом, например, мониторингом свободного места на диске. Допустим, нам надо показывать дашборд сразу и отделу поддержки, чтобы они знали, когда чистить старые логи, и отделу закупок, чтобы не надеялись на поддержку и сразу заказывали новые диски.


Для инженера тут все понятно:

  • скрипт отрабатывает быстро (еще бы, простая крон-джоба);

  • монитор вполне живой, 25 минут назад обновился;

  • места еще с запасом (цифра 53 в левом нижнем углу - это последнее принятое значение);

Для людей из бизнеса тут тоже все просто:

  • монитор зеленый;

  • статус прописан в первой же строчке;

  • никакой лишней информации;

Вместо размера диска, разумеется, может быть что угодно, начиная от импорта данных из гугл-аналитики, заканчивая мониторингом ревенью компании - суть не меняется.

И насколько просто такое настроить?

  1. Создаем вебхук в самом сервисе, они там называются сенсорами, по аналогии со всякими штуками из физического мира.

  2. Настраиваем крон-джобу на сервере, которая будет отсылать события со значением свободного места в процентах:

    df -h |grep vda1 | awk  '{ print $5 }'| sed 's/.$//' | xargs -I '{}' curl -G "https://sensorpad.link/<уникальный ID>?value={}" > /dev/null 2>&1
    
  3. Присоединяем к этому вебхуку монитор, называем его: количество свободного места (но можно еще и другие, например, то, что события уходят по графику означает, что сервер не упал)

  4. Настраиваем правила, по которым монитор меняет свой статус.

  5. Присоединяем каналы для отправки уведомлений.

  6. Добавляем монитор на один или несколько дашбордов.

А можно поподробнее?

Для вебхуков я пока что сделал саму простую имплементацию:

  • базовый вебхук, который будет нужен для 80% проектов;

  • cron-вебхук, который ожидает события в заданное через cron-синтаксис время;

  • chain-вебхук, который умеет отслеживать события от процессов, соединенных в цепочки;

главное в нашем деле - не усложнять интерфейсыглавное в нашем деле - не усложнять интерфейсы

После создания попадаем на страницу сенсора, тут автоматически появляются полученные события (повозился в js) и кнопочкой можно отсылать тестовые события, для тех, у кого не установлен Curl или кому лень делать это из браузера:

Догфудинг в действииДогфудинг в действии

Дальше создаем тот самый монитор - квадратик, меняющий статус и цвет.

Можно даже иконку выбратьМожно даже иконку выбрать

Есть две стратегии для статуса по умолчанию: сказать, что монитор должен быть в статусе "все хорошо", а потом правилами менять его на "что-то пошло не так", или можно сразу сделать ему статус "все плохо", а правилами проверять, что все действительно хорошо - обе стратегии имеют право на жизнь.

Теперь, собственно то, из-за чего я и написал эту балалайку: правила и гибкая логика.

К каждому монитору можно прицепить определенное количество правил, дальше движок мониторинга проверяет все правила раз в пару секунд. Правила проверяются поочередно, как только одно из правил вернет значение True, статус монитора изменится и остальные правила проверяться не будут. Если никакое из правил не сработало, статус монитора примет значение по умолчанию - то самое, которое задавалось при создании монитора.

Правила для мониторинга места на дискеПравила для мониторинга места на диске

На скриншоте выше видно уже созданные правила, но я покажу как они создаются.

Например правило, которое можно сформулировать так: "установи статус Warning, если за последний день было больше 5 джоб, которые работали дольше 10 секунд".

А вот какие вообще можно выбирать проверки в каждом из пунктов:

И какие реальные кейсы можно покрыть этими правилами?

У каждого свои кейсы. Дата-инженерия вообще весьма специфичное для каждой компании направление. Если у вас есть дата-пайплайны или cron jobs, сервис оповестит вас, если (все цифры, разумеется, конфигурируемы):

  • Cron job, Airflow DAG или любой другой процесс не запустился по расписанию;

  • 20% задач одного и того же пайплайна за день не отработали как надо;

  • связанная задача в пайплайне не запустилась через 2 минуты после окончания родительской задачи;

  • интервал между запусками двух задач меньше 1 минуты (похоже, у нас две конкурентные джобы);

  • с момента последнего успешного завершения пайплайна прошло 2 часа (а данные должны считаться каждый час);

  • время работы пайплайна уже целых 20 минут (а должен был отработать за 5, что-то подвисло).

Это те идеи, которые могли бы использоваться в практически любой, полагаю, компании.

А теперь - статистика!

Красивые графики любят все. Крутость sensorpad в том, что он показывает в статистике реальные состояния систем, а не просто количество уведомлений (их, кстати, тоже показывает). А уже с этими данными можно разгуляться: и самому поковырять, чтобы понять во что вложить силы и что нужно оптимизировать, да и стейкхолдерам не грех показать идеально зеленый график.

Немного полезных и не очень графиковНемного полезных и не очень графиков

Я подумываю допилить возможность шарить эти странички по секретной ссылке за пределы аккаунта, тогда такую страницу можно будет использовать не хуже любой status page.

Вот такой концепт. Чего не хватает?


Sensorpad - проект выходного дня, который делался в свободное от основной работы время, без тонны инвестиций да еще и в одно лицо, именно поэтому мне так важно мнение комьюнити: как вам? Что добавить, что улучшить, продолжать ли развивать?

Потыкайте его вживую, заодно зацените, какой я у мамы дизайнер лендингов: https://sensorpad.io

Подробнее..

Перевод Tоп 10 PromQL запросов для мониторинга Kubernetes

12.06.2021 10:05:57 | Автор: admin

В этой статье приведены примеры популярных запросов Prometheus для мониторинга Kubernetes.

Если вы только начинаете работать с Prometheus и у вас возникают сложности при создании запросов PromQL, советуем обратиться к руководству по началу работы с PromQL. Здесь мы пропустим теорию и сразу перейдём к практике.

Рейтинг основан на опыте компании Sysdig, ежедневно оказывающей сотням клиентов помощь в настройке мониторинга их кластеров:

1. Количество pods в каждом namespace

Информация о количестве pod в каждом namespace может быть полезна для обнаружения аномалий в кластере, например, слишком большого количества pods в отдельном namespace:

sum by (namespace) (kube_pod_info)

2. Количество контейнеров без CPU limits в каждом namespace

Важно правильно задавать лимиты для оптимизации производительности приложений и кластера. Этот запрос находит контейнеры без CPU limits:

count by (namespace)(sum by (namespace,pod,container)(kube_pod_container_info{container!=""}) unless sum by (namespace,pod,container)(kube_pod_container_resource_limits{resource="cpu"}))

3. Количество перезагрузок pods в каждом namespace

С помощью этого запроса вы получите список pods, которые перезапускались. Это важный показатель, поскольку большое количество перезагрузок pod обычно означает CrashLoopBackOff:

sum by (namespace)(changes(kube_pod_status_ready{condition="true"}[5m]))

4. Pods в статусе Not Ready в каждом namespace

Запрос выводит все pods, при работе которых возникла проблема. Это может быть первым шагом к её локализации и устранению:

sum by (namespace)(kube_pod_status_ready{condition="false"})

5. Превышение ресурсов кластера ЦП

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

sum(kube_pod_container_resource_limits{resource="cpu"}) - sum(kube_node_status_capacity_cpu_cores)

6. Превышение ресурсов кластера Память

Если все Memory limits суммарно превышают ёмкость кластера, то это может привести к PodEviction, если на узле не будет хватать памяти. Для проверки используйте запрос PromQL:

sum(kube_pod_container_resource_limits{resource="memory"}) - sum(kube_node_status_capacity_memory_bytes)

7. Количество исправных узлов кластера

Запрос выведет количество исправных узлов кластера:

sum(kube_node_status_condition{condition="Ready", status="true"}==1)

8. Количество узлов кластера, которые могут работать некорректно

Найти узлы кластера, которые периодически меняют состояние с Ready на Not Ready:

sum(changes(kube_node_status_condition{status="true",condition="Ready"}[15m])) by (node) > 2

9. Обнаружение простаивающих ядер ЦП

Планировании ресурсов кластера Kubernetes не самая простая задача. Этот запрос поможет вам определить, сколько ядер ЦП простаивают:

sum((rate(container_cpu_usage_seconds_total{container!="POD",container!=""}[30m]) - on (namespace,pod,container) group_left avg by (namespace,pod,container)(kube_pod_container_resource_requests{resource="cpu"})) * -1 >0)

10. Обнаружение неиспользуемой памяти

Этот запрос поможет снизить ваши затраты, предоставив информацию о неиспользуемой памяти:

sum((container_memory_usage_bytes{container!="POD",container!=""} - on (namespace,pod,container) avg by (namespace,pod,container)(kube_pod_container_resource_requests{resource="memory"})) * -1 >0 ) / (1024*1024*1024)

Хотите узнать больше?

Рекомендуем изучить нашу шпаргалку по PromQL, чтобы узнать, как писать более сложные запросы PromQL.

Также воспользуйтесь отличной коллекцией Awesome Prometheus alerts collection. Она включает несколько сотен Prometheus alert rules, вы можете изучить их, чтобы узнать больше о PromQL и Prometheus.

Подробнее..

Давайте обсудим мониторинг

07.04.2021 16:22:59 | Автор: admin

Вот уже четвертый год я занимаюсь организацией того, что принято называть Observability. Набранный за это время опыт я обличаю в текст, делюсь им с вами в виде размышления-рекомендации и выношу на суд общественности. Здесь практически не будет технических деталей статья намеренно написана таким образом, дабы изложенное можно было положить на практически любой стек технологий. Дело в том, что инструменты врываются в тренды и покидают их с невероятной скоростью, посему их выбор остается за вами. Давайте обсудим мониторинг.

О мониторинге в контексте метрик

Если спросить среднестатистического технаря-инженера, с чем у него ассоциируется мониторинг, то скорее всего вам ответят метрики приложения, и подразумеваться будет их сбор и некоторая визуализация. Причем, о изнанке этого процесса, как показал мой опыт, многие даже не задумываются в понимании большинства оно просто показывается в Grafana/Kibana/Zabbix/подставьте нужное.

Ответ этот, замечу, всё же не полный, поскольку одними лишь метриками всё не ограничивается. Точнее даже так: мониторинг - это не только о том, чтобы метрики собрать и вывести на дашборд. И вот с этого момента давайте поподробнее.

Из чего же сделан мониторинг?

Со временем, я для себя вывел следующие аспекты:

  1. Сбор метрик из различных источников приложения, показатели хоста, железной части площадки; различия в pull и push моделях пока не затрагиваем, об этом чуть позже

  2. Запись и дальнейшее их (метрик) хранение в базе данных с учетом особенностей самой БД и использования собранных данных

  3. Визуализация метрик, которая должна балансировать между возможностями выбранного технологического стека, удобством использования дашборд и хотелками тех, кому с этим всем предстоит работать

  4. Отслеживание показаний метрик по заданным правилам и отправка алертов

  5. В случае продвинутого мониторинга сюда можно добавить еще один пункт - выявление аномалий и проактивное информирование о деградации наблюдаемой системы на основе ML.

О сборе метрик

Итак, вы решили создать систему мониторинга. Первым шагом предлагаю задуматься о том какие метрики собирать:

  • Показатели хост-системы и окружающего железа - утилизация ресурсов CPU, RAM, нагрузка на дисковые и сетевые устройства, статистика по процессам, информация о состоянии платформы оркестровки и так далее; всех их объединяет один признак такие метрики относятся к самому низкому доступному вам уровню инфраструктуры, с которой вы работаете.
    Например, если вы предоставляете сервис для хостинга виртуальных машин, вам понадобится мониторить сервера виртуализации; а если выкатываете свой продукт на площадку клиента, это наверняка будут виртуальные машины и/или K8s-кластер

  • Показатели обслуживаемых приложений здесь появляется слой метрик, которые можно связать с процессами, в корректности и стабильности работы которых вы напрямую заинтересованы; ими могут быть гипервизор, ваш софт для клиента, некоторые системные процессы.
    На этом уровне появляется возможность (а часто необходимость) устанавливать однозначную связку инфраструктура-приложение. В самом простом виде она может выглядеть так вы мониторите состояние процесса запущен/не запущен, к этой метрике привязываете теги с именами хоста и приложения, по сумме которых можно будет однозначно определить, к чему именно эта метрика относится

  • Показатели бизнес-процессов сюда относится информация, на основе которой можно делать выводы о работоспособности бизнес-функций.
    В качестве примера возьмем операцию списания денег с лицевого счета пользователя допустим, для успешного выполнения операции необходимо, чтобы был доступен личный кабинет (веб-сервер), сервис постановки задач в очередь, брокер асинхронных сообщений, платежный шлюз и база данных. Чтобы быть уверенным, что операция может быть выполнена, вам понадобится следить за состоянием всей цепочки, хотя бы в самом простом виде работают ли все приложения в ней

  • Результаты смок-тестов по сути, расширение предыдущего уровня; это показатели периодически выполняемых фейковых бизнес-операций, по которым можно будет поймать проблему

Pull VS Push

Предмет жарких споров в тематических каналах и форумах с извечным вопросом что же лучше?

Push-модель это когда у вас есть классическая БД, в которую активно пишут агенты. Отличается большим объёмом точек конфигурирования (как правило, по количеству агентов мониторинга), но в то же время дает возможность базе заниматься своей основной задачей хранить метрики и управлять их жизненным циклом, пассивно ожидая, пока в неё что-нибудь положат.

Pull-модель насколько мне известно, относительно новый подход, набравший популярность с приходом в нашу жизнь платформ для оркестровки контейнеров. В этом случае, сам сервер мониторинга ходит по пассивным экспортерам и забирает у них метрики. Плюс единая точка конфигурирования, сам сервер, которому надо рассказать, что и откуда забирать. ИМХО, он же и главный минус в случае отвала сети вы теряете показатели за время её простоя. Отлично показывает себя в эфемерных средах вроде K8s, когда количество сущностей, которые необходимо мониторить, изменяется с течением времени. За их пределами уже не столь удобен для получения метрик от хостов вам понадобятся агенты-экспортеры.

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

О хранении

Здесь буду немногословен на текущий момент придумано немало TSDB (Time-Series DataBase), заточенных именно под временные ряды. Вам остается только выбрать то, что по соотношению доступный функционал производительность удобство и возможности языка запросов покажется максимально приемлемым.

Мой личный фаворит VictoriaMetrics, рекомендую ознакомиться.

О визуализации

Подобно тому, как метрики делились уровни, аналогично разделяется и визуализация:

  1. Уровень площадки самый высокий уровень визуализации, с которого, после получения алерта, пользователю мониторинга стоит начинать работать. Дашборд(ы) здесь представляют собой набор логически разделенных индикаторов всё хорошо/что-то сломалось.
    Например, каждая панель показывает состояние какой-либо группы приложений Nginx`ы, Apache`и, Службы виртуализации; при наличии проблемы с любой из сущностей группы панель переходит из состояния всё хорошо в состояние что-то сломалось, привлекая внимание

  2. Уровень группы следующий уровень, к которому переходит пользователь; должен быть доступен по drilldown-ссылке с предыдущего дашборда. Если ранее мы подсветили, с какой группой возникла проблема, здесь мы должны ответить на вопрос с каким именно объектом группы?.
    Продолжая начатый выше пример, здесь отображаются все Nginx на вашей площадке, по которым выведены ключевые показатели состояния процессов, состояния соединений с БД, количество ошибок и так далее. Тут не стоит сильно вдаваться в детали, пяти-шести панелей на объект наблюдений будет достаточно

  3. Уровень объекта конечная точка движения нашего пользователя в большинстве случаев.
    На этом уровне детально визуализируются метрики конкретного приложения/процесса/другого подвергнутого принудительному мониторингу объекта. Здесь пользователь должен найти для себя ответ на такой вопрос что же именно сломалось?. Начиная с этого уровня, переходы между дашбордами должны наследовать контекст если пользователь на уровне группы кликнул по панели процесса nginx_01 хоста proxy.local, метрики именно этого приложения на этом хосте и должны отображаться

  4. Уровень фрагмента объекта формально, продолжение предыдущего уровня, но введен вот зачем: если какая-либо часть нашего объекта имеет слишком много метрик и достойна того, чтобы рассматриваться отдельно, под неё заводится персональный дашборд.
    Например, у нашего Nginx есть апстримы со своими метриками; дабы не усложнять уровень объекта и не перегружать его, мы заводим под апстрим персональный дашборд, а на предыдущем оставляем только кликабельные индикаторы с состоянием апстрима онлайн/частично онлайн/оффлайн. И вновь, переходы должны наследовать контекст, чтобы облегчить пользователю навигацию

  5. Уровень инфраструктуры самый низкий уровень визуализации и отправная точка в сборе метрик.
    Тут отображаются показатели хост-системы и окружающего железа. Хорошим ходом будет разбить на разные дашборды метрики разных частей состояние CPU, RAM, дисков и т.д., организовав возможность горизонтального перехода между ними. Переход же на этот уровень можно создать с двух предыдущих, снова с учётом ранее установленного контекста; если пользователь смотрел на метрики приложения на хосте proxy.local, этого хоста метрики и должны отображаться

Подводя итог написанному выше, у нас получается такая диаграмма уровней, демонстрирующая путь пользователя:

Пользователь мониторинга двигается сверху вниз, разбирая инцидентПользователь мониторинга двигается сверху вниз, разбирая инцидент

Общие рекомендации:

  • Делайте ваши дашборды шаблонными, с возможностью установки контекста через переменные. Мысль достаточно очевидная, согласен, но, тем не менее, мне приходилось встречать хардкод хостов и приложений, порождающий ворох из копий одних и тех же дашборд, что выливалось в неподдерживаемый хаос

  • Также, стоит выносить в переменные различные потенциально изменяемые вещи имя базы данных с метриками, вручную составленные словари число-значение и т.п.

  • Добавляйте описание к всем панелям. Если отображаемая на панели информация кажется хоть немного неочевидной, не поленитесь дать ей описание буквально одно-два предложения сильно облегчат работу пользователей и помогут вам же, когда возникнет необходимость вернуться к работе с дашбордом

В качестве средства визуализации сейчас лидирует небезызвестная Grafana, в которой есть функционал переменных, внутренних и внешних ссылок c шаблонизацией, комментариев к панелям и еще всякое-всякое.

О алертинге

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

К сожалению, или к счастью, в мире нет ничего идеального, но можно попробовать к этому приблизиться. Итак, хороший алерт можно приготовить из таких ингредиентов:

  • Полнота сообщения в теле алерта должна содержаться информация о том, что именно произошло и за какой период времени.
    Пример: Средняя нагрузка на CPU превышает 90% в течение последних пяти минут; пользователь, получивший такое сообщение, видит информацию, во-первых, о событии, во-вторых, о его длительности на момент получения, что позволяет сходу примерно оценить масштабы бедствия.
    Здесь стоит уточнить, что метрика обычно оценивается за некоторый период, из которого выводится максимальное/среднее/минимальное/иное другое значение, а не её мгновенный показатель это позволяет сгладить (или же выделить зависит от того, что именно вам нужно) всплески и временнУю задержку в доставке метрик до базы данных

  • Уточняющие метаданные алерт должен сопровождаться набором тегов/лейблов, раскрывающих контекст события; это могут быть имя хоста, приложения, идентификатор uri веб-сервера и т.п.

  • Штамп времени первого срабатывания тут всё просто, в алерте жизненно необходима метка времени, чтобы при получении нотификации можно было понять, новый ли алерт у вас сработал, или это всё еще горит старый

  • Ссылка на систему управления алертами/систему визуализации метрик, на ваш выбор она нужна для получателя, чтобы он смог сразу перейти в мониторинг, а не тратил время на судорожный поиск закладки в браузере

С самим алертом, вроде, разобрались, теперь немного о процессе нотификации:

  • Не допускайте спама со стороны системы управления алертами. Когда вашего получателя заваливает письмами/СМСками/сообщениями от бота, рано или поздно он перестанет предавать им хоть какое-то значение и пропустит критичную нотификацию. Хорошим тоном будет настроить рассылку таким образом, чтобы по уже горящим алертам повторные уведомления отправлялись спустя какое-то время

  • Выделите ключевые метаданные и группируйте алерты по ним; тогда вместо, например, семи сообщений по одному объекту, ваш пользователь получит одно, в которое будут вложены остальные. Это также позволяет снизить количество нотификаций (помним про предыдущий пункт)

  • Предусмотрите возможность для себя и/или пользователя временно отключать некоторые алерты, например, на время технических работ

  • Если ваша система это позволяет, настройте иерархию алертов с автоматическим подавлением нижестоящих. Если у вас из сети выпал сервер, нет необходимости дополнительно слать письма о том, что приложения на нем стали недоступны, это и так очевидно из первого

  • Разделите алерты по группам инженерам пусть приходят технические алерты, а бизнесу бизнесовые. Условной коммерческой дирекции не интересно, что у вас упал Nginx (им это ни о чем не скажет), для них куда важнее знать, что цепочка выполнения бизнес-функции покупка товара развалилась и компания несет потенциальные убытки

Рекомендую пощупать AlertManager приложение из стека Prometheus, в котором есть все описанные выше возможности. Лично для меня он стал той самой серебряной пулей, решившей сразу вагон и маленькую тележку проблем. Веб-хуки и API для интеграций входят в комплект.

Вместо заключения

В первую очередь, выражаю благодарность тем, кто прочитал до конца; надеюсь, что статья показалась вам интересной и полезной.

Это первый текст из трех запланированных дальше я бы хотел затронуть тему логирования и его синергии с мониторингом, после чего, возможно, перейти к некоторым техническим деталям (уже не только сухим текстом). Если вам было бы интересно об этом почитать, пожалуйста, напишите в комментариях. Попробуем разобрать и обсудить сначала общий подход к сбору и централизованному хранению журналов, их роль в оценке состояния наблюдаемой площадки, а также затронем вопрос можно ли отрывать логи от метрик?.

Подробнее..

Full-stack мониторинг напримере Java приложений

27.04.2021 14:21:47 | Автор: admin

Всем привет! Запоследние пять лет мыдостаточно часто сталкивались сзапросами намониторинг Java приложений. Собрав основные моменты помониторингу Java, мырешили написать данный пост.

Сегодня мысвами рассмотрим, что такое full-stack мониторинг ичем онотличается отпривычного уху понятию мониторинга, нюансы full-stack мониторинга для Java исложности мониторинга микросервисных приложений наJava. Расскажем, как мыреализуем full-stack мониторинг спомощью open-source стандартов иплатной платформы.

Full-stack мониторинг

Давайте определимся, что мы называем full-stack мониторингом?

Full-stack мониторинг это подход вмониторинге производительности приложений, который подразумевает под собой мониторинг всего стека, что включает всебя:

  • Мониторинг приложений сбор метрик приложения, сбор трейсов транзакций, обеспечение видимости науровне кода ит.д.

  • Мониторинг инфраструктуры метрики хостов, процессов, контейнеров ит.д.

  • Мониторинг конечных пользователей сбор метрик сбраузера пользователя, мобильного приложения, синтетические проверки ит.д.

Основное отличие full-stack мониторинга от привычного мониторинга заключается в том, что, применяя full-stack мониторинг, мы получаем реальное представление о том, как себя "чувствует наше приложение и как его работа влияет на пользовательский опыт, так как видим не просто метрики приложения, а влияние всех инфраструктурных компонентов на приложение и то, как это сказывается на опыте наших пользователей.

Зачастую под full-stack мониторингом подразумевают продукт/решение, который предоставляет единый сервис для сбора, хранения и анализа собираемых данных с приложения, инфраструктуры и пользователей. Но в нашей статье мы поговорим именно про подход и расскажем про использование как open-source стандартов, так и платной платформы для реализации full-stack мониторинга Java.

По результатам нашего опыта можем сказать, что применение full-stack подхода к мониторингу позволяет заметно ускорить процесс root cause анализа инцидентов и действительно снизить MTTR.

Нюансы full-stack мониторинга Java

Чтобы понимать что нужно мониторить в Java приложениях, давайте для начала разберемся что собой представляет Java. Во-первых, Java это приложения, написанные не только на языке программирования Java, но и на других языках, которые основываются на Java Kotlin, Scala, JRuby, и другие.

Во-вторых, Java это еще и среда для чтения, понимания и выполнения байт-кода Java. Приложения, написанные на Java языке или на языках, базирующихся на Java, компилируются в байткод и запускаются в определенной среде исполнения JVM (Java Virtual Machine).

Поэтому нам нужно мониторить как само приложение на Java, так и среду, в которой оно запускается.

В целом full-stack мониторинг Java будет выглядеть следующим образом:

  1. Сбор Java и JVM метрик.

  2. Сбор распределенных трассировок транзакций.

  3. Профилирование Java кода.

  4. Мониторинг конечных пользователей.

Давайте подробнее пройдемся по всем компонентам full-stack мониторинга Java.

Сбор метрик Java и Java Virtual Machine

Под сбором метрик Java подразумевается сбор уникальных метрик с используемых фреймворков Java (SpringBoot, DropWizzard и т.д.) и applications серверов (JBoss/Wildfly, Websphere и т.д.), например:

  • количество HTTP Requests для SpringBoot Framework;

  • количество WebDeployments и количество их активных сессий для JBoss;

  • количество запросов и среднее время отклика servlets для Websphere.

Получить метрики Java Virtual Machine (JVM) можно с помощью имеющейся у Java технологии JMX (Java Management Extensions), которая представляет информацию о состоянии самой JVM, garbage collection и других внутренних элементов.

Какие метрики JVM нас интересуют в первую очередь:

  • Memory Usage
    Общий объем памяти, используемый самой JVM.
    Получим из java.lang.Runtime#totalMemory

  • Threads
    Количество тредов, находящихся в статусах: new, runnable, timed-waiting, waiting или blocked.

    • Текущие идентификаторы тредов получим из java.lang.management.ThreadMXBean#getAllThreadIds

    • Статус тредов получим из ThreadMXBean#getThreadInfo

  • Heap Memory
    Общее использование heap memory самой JVM.

    • Текущее значение получим из java.lang.Runtime#totalMemory-java.lang.Runtime#freeMemory

    • Максимальное значение получим из java.lang.Runtime#maxMemory

  • Memory Pools
    Использование memory pools

    • Информацию о пуле получим из ManagementFactory#getMemoryPoolMXBeans

    • Значение использования памяти пулом получим из java.lang.management.MemoryUsage

    • Максимальное значение получим из getMax, начальное значение получим изgetInit, и текущее значение получим изgetUsage.

  • Garbage Collection
    Значение garbage collection и время его выполнения

    • Информацию о garbage collection получим из ManagementFactory#getGarbageCollectorMXBeans

    • Значение для каждого коллектора получим из java.lang.management.GarbageCollectorMXBean

    • Garbage collection runtime получим из getCollectionTime

Во время разработки приложений, самыми популярными инструментами для сбора и анализа метрик являются VisualVM и JDK Mission Control.

Помимо стандартного набора метрик, можно описать свои собственные (кастомные) метрики и здесь нам помогут такие инструменты, как DropWizard, Micrometer, StatsD и Prometheus.

На нашей практике, чаще всего используется Prometheus для описания кастомных метрик. Prometheus предоставляет большой набор интеграций и оберток для большинства популярных фреймворков, основанных на Java. Благодаря чему, Prometheus достаточно просто и быстро интегрируется с приложением.

У всех вышеупомянутых инструментов есть один большой недостаток метрики изолированы друг от друга из-за чего отсутствует контекст данных, который нам необходим для расследования инцидентов, особенно если у нас микросервисная среда. Но к этому мы вернемся чуть позже, а пока перейдем к трейсингу запросов.

Сбор распределенных трассировок (distributed tracing)

Чтобы обеспечить быстрое выявление и решение проблем с Java приложениями, одного сбора метрик будет недостаточно, необходимо видеть, как все наши сервисы взаимодействуют между собой, то есть собирать информацию о наших транзакциях. Это возможно сделать с помощью end-to-end трейсинга всех вызовов в нашем Java приложении.

Наиболее распространенный путь в получении end-to-end трейсинга это использование open-source стандартов, например, таких как, OpenTelemetry и OpenTracing.

Пример видимости транзакции в одном из самых распространенных open-source инструментов для end-to-end трейсинга Jaeger

Но важно учитывать, что, используя разные open source решения - одно для сбора метрик (например, Prometheus), другое для сбора транзакций (Jaeger, Zipkin и т.п.) мы столкнемся с необходимостью ручной корреляции метрик и трейсов между собой. Связанно это с тем, что все open source решения по-разному записывают и хранят данные. И если инцидент затронул много сервисов, что часто происходит в микросервисных инфраструктурах, то при использовании такой связки, как например Prometheus + Jaeger, процесс root-cause анализа инцидента наоборот может усложниться и в результате увеличиться MTTR.

Поэтому для сбора метрик, транзакций и их корреляции между собой в микросервисных инфраструктур, мы используем готовые продукты для full-stack мониторинга, ниже расскажем про их применение.

Профилирование Java кода

Чтобы понять причину, почему наше Java приложение потребляет много ресурсов, нам нужно видеть, какой именно метод приложения вызывает проблемы с производительностью. Поэтому нужно производить профилирование Java кода.

Профилировщики существуют уже очень давно. Первые профилировщики использовались только на этапе отладки приложения, в тестовой среде, из-за их высокого потребления CPU и Memory ресурсов. Но сейчас существуют профилировщики, которые не несут такой высокой нагрузки, и мы можем их запускать уже в продакшен среде.

На нашей практике, для профилирования приложения в основном используются такие инструменты, как VisualVM, jProfiler и JavaMissionControl в сочетании с Flight Recorder.

Мониторинг конечных пользователей (End user мониторинг/Real user мониторинг)

Как мы писали выше, одной из важных частей full-stack мониторинга является мониторинг наших конечных пользователей. Это обусловлено тем, что работа нашего приложения напрямую влияет на пользовательский опыт. Пользователи взаимодействуют с приложением через веб-сайт или мобильное приложение и понимание того какие запросы от пользователей уходят на бэкенд, т.е. запросы к Java приложению, обеспечивают сквозную видимость запроса, от клика пользователя в браузере или мобильном приложение до конкретной транзакции на бэкенде.

Таким образом, мы видим влияние скорости работы и ошибок в Java приложение на пользовательский опыт.

Мы решили сейчас много не писать на тему end user мониторинга так как мы ранее уже достаточно подробно раскрыли эту тему в одном из наших постов:

Сложности мониторинга микросервисных Java приложений

Не могли не затронуть, хотя бы вскользь, тему мониторинга микросервисных Java приложений.

Основная сложность мониторинга таких приложений заключается в том, что увеличивается количество подконтрольных компонентов контейнеры, оркестраторы (k8s, docker swarm, openshift и т.д). Контейнеры с приложениями постоянно скейлятся, могут запускать только на короткий срок времени. Все это экспоненциально усложняет процесс мониторинга.

Динамичность микросервисной архитектуры Java приложения приводит нас к тому, что для обеспечения full-stack мониторинга нам необходимо проводить постоянную инвентаризацию инфраструктуры c целью получения актуальных данных о нашей инфраструктуре. Это возможно реализовать с помощью autodiscovery подхода .

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

Визуализация стека компонентов с их ключевыми метриками в продукте InstanaВизуализация стека компонентов с их ключевыми метриками в продукте Instana

Отсутствие автодискаверинга как неотъемлемой части full-stack мониторинга микросервисных приложениях приводит к тому, что вновь запущенные компоненты, могут быть не замониторены и в результате у нас появятся слепые зоны в инфраструктуре. Мы не будем иметь представления о том, как себя действительно чувствует тот или иной компонент инфраструктуры, не сможем корректно оценить состояние приложения.

Реализовать подход автодискаверинга вручную, достаточно трудоемкий процесс, поэтому в наших проектах мы используем готовое решение Instana.

Full-stack мониторинг как продукт

Выше мы с вами рассмотрели full-stack мониторинг как подход, здесь же мы поговорим о full-tack мониторинге как готовом к использованию продукте.

На рынке существуют различные решения для full-stack мониторинга - Dynatrace, DataDog, New Relic, AppDynamics, Instana и т.д. Но мы расскажем именно про Instana, так она на данный момент объединяет в себе объемный функционал, необходимый для full-stack мониторинга как классических инфраструктур, так и микросервисных и выгодно отличается по цене от конкурентов.

С помощью Instana мы получаем full-stack мониторинг в том числе и для Java приложений без необходимости ручной настройки.

Instana постоянно и автоматически собирает ключевые данные для поддерживаемых технологий, относительно JVM обнаруживает все что находится внутри нее:

  • тип JVM;

  • версия JVM;

  • используемый framework;

  • коннекторы к базам данным;

  • Upstream и Downstream сервисы;

  • и многое другое.

Причем для агента Instana не важно в какой инфраструктуре запущено приложение в Docker, Kubernetes, OpenShift, Linux или Windows. После обнаружения JVM агент подключается к самому процессу и анализирует архитектуру сервиса, какой Framework используется (Spring Boot, DropWizzard и так далее), сервер приложений (Jboss/Wildfly, Websphere, и тд) и коннекторы к базам данных. Далее приложение автоматически инструментируется и агентом начинают собираться ключевые метрики и трейсы приложения. Очень важно, что при этом не требуется перезапуск приложения.

Понимание топологии приложения позволяет Instana построить логическую модель всего стека, обнаружить сервисы и их зависимости.

Давайте посмотрим на пример топологической модели Spring Boot приложения:

  • Sping Boot приложение, это часть ->

  • Java процесса, который представляет собой Java приложение, запущенное в ->

  • JVM, которая запущена в ->

  • Docker контейнере, который запущен в ->

  • процессе операционной системы, который запущен на ->

  • Linux хосте.

Представив топологию в виде вертикального стека зависимостей компонентов инфраструктуры, с каждого уровня необходимо собрать уникальные метрики. И Instana собирает метрики с каждого уровня и визуализирует весь стек.

Но как мы писали выше, метрик недостаточно для полноценного мониторинга Java приложений. Приложения предоставляют собой сервисы, которые между собой как-то взаимодействуют. Instana обнаруживает все вызовы между сервисами и создает распределенные трейсы, показывая end-to-end карту вызовов.

Посмотрев на карту вызовов, возникает необходимость проанализировать трейсы проблемного сервиса. И мы можем более детально проанализировать каждый из вызовов. Instana не сэмплирует вызовы, что позволяет анализировать абсолютно каждый из них.

Важной частью мониторинга Java приложений является профилирование кода. У нас могут быть метрики всех компонентов приложения и видимость всех вызовов, и мы можем понять связана ли эта проблема с использованием ресурсов и какой сервис именно пострадал. Но мы не узнаем, какой именно метод в работающем сервисе приложения вызывал проблемы с производительностью. И тут нам поможет постоянно работающий Java профилировщик. Профилировщик покажет точный метод(ы), которые перегружают CPU или имеют большой wait time.

Подводя итоги

Актуальность full-stack мониторинга будет только расти и это обусловлено, в том числе, переходом на микросервисную архитектуру, которая экспоненциально усложняет мониторинг по причине постоянного увеличения подконтрольных компонентов инфраструктуры.

Full-stack мониторинг позволяет охватить весь наш стек приложения, инфраструктуру, пользователей, и значительно ускорить root-cause анализ и снизить MTTR.

Имплементировать full-stack мониторинг возможно и как с помощью подхода сделай сам, используя open source стандарты (Prometheus/statsD для сбора метрик, Jaeger/Zipkin для сбора трейсов, jProfiler/Java VisualVM для профилирования Java кода), так и с помощью готовых продуктов, которых на рынке сейчас уже не мало.

Будем рады, если в комментариях вы поделитесь применяете ли full-stack мониторинг, как мониторите Java приложения и какие используете для этого инструменты?

Подробнее..

SaaS и ALEPIZ мониторинг и управление инфраструктурой

20.05.2021 12:07:50 | Автор: admin

Я системный администратор, более 20 лет занимаюсь управлением и мониторингом критичной в масштабах страны инфраструктуры. Услуги, которые я администрирую, предоставляются по модели SaaS (Software as a Service аренда ПО). Это моя первая публикация, я решил поделиться своими наработками в этой области, возможно кому-то это будет полезно.

ALEPIZ распространяется бесплатно по лицензии GPL v3ALEPIZ распространяется бесплатно по лицензии GPL v3

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

Хочу заметить, что эта статья не является рекламой. Я пишу ее как частное лицо и не представляю какую-либо организацию. Решение доступно вместе с исходным кодом и находится в свободном доступе. Вы можете использовать его совершенно бесплатно по своему усмотрению.

История

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

В начале 2000 мы начали внедрять, как тогда казалось подходящую нам и довольно распространенную систему мониторинга. В процессе её адаптации через некоторое время стало понятно, что использовать систему как есть не получится. Пришлось заниматься доработкой. В результате, за 10 лет эксплуатации и разработки мы получили систему по управлению и мониторингу с организацией рабочих процессов между подразделениями. В качестве ядра системы использовалась выбранная нами система мониторинга и ее БД.

Обновить ее мы не могли, потому что разработчики системы мониторинга меняли структуру БД, к которой было жестко привязано наше ПО. Несколько лет назад производительности системы стало существенно не хватать. Появилось много неудобств, связанных с недостаточно проработанной архитектурой как системы мониторинга, так и наших доработок.

Я решил учесть ошибки и разработать новую систему. Большинство продуктов создаются разработчиками ПО, а я системный администратор. Я хуже знаю процесс разработки, но проектирование и реализация системы для системных администраторов в данном случае сделана системным администратором, с учетом нюансов нашей работы. Считаю, что это положительно сказалось на конечном результате

В своей организации я разрабатывать систему не мог, потому что у меня на это нет времени и в мои обязанности не входит разработка какого-либо ПО. Я решил сделать создание системы своим хобби и занимался ей в свободное от работы время. Начал заниматься разработкой в 2014 году. Когда я все это планировал, я не думал, что это хобби потребует от меня столько времени и ресурсов. Несмотря на все сложности, я все-таки смог довести процесс до конца. В настоящее время у системы есть реальные внедрения и большая часть запланированных функций реализована.

ALEPIZ

Новая система получила название ALEPIZ. Я не планировал ее распространять, но создание системы затянулось. Чтобы не платить за средства разработки я выполнил условия для их бесплатного использования: выложил ПО на GitHub под лицензией GPL v3 и создал сайт alepiz.com.

Data Browser служит для отображения собранных исторических данныхData Browser служит для отображения собранных исторических данных

Архитектура системы

Для того, чтобы не столкнуться с проблемами масштабируемости, архитектура системы построена вокруг микроядра, для которого разрабатываются различные модули.

Тестирование и эксплуатация ведется под ОС Microsoft Windows. Выбор ОС продиктован архитектурой программного обеспечения, которое используется в моей организации.

Для возможности портирования в будущем на другие архитектуры, в качестве платформы были выбраны JavaScript и NodeJS. Это так же позволило унифицировать разработку backend и frontend и использовать асинхронность JavaScript для достижения требуемой производительности. Применение потоков (threads) в NodeJS невозможно из-за отсутствия поддержки во многих модулях, поэтому используется схема с запуском нескольких процессов.

В ALEPIZ встроен Web сервер и сервер БД на основе быстрой и простой SQLITE. При развертывании системы нет необходимости в установке дополнительного ПО: ALEPIZ включает все требуемые компоненты. Для ускорения работы с БД реализована система кэширования, разработанная специально для ALEPIZ.

Есть периодическая очистка старых исторических данных, которая позволяет сделать размер БД близким к постоянному. Реализованы встроенная репликация и резервное копирование БД, система интеллектуального пропуска похожих данных, автоматическая ротация логов, система настройки прав ролевого доступа для пользователей и многое другое.

Сейчас ALEPIZ обслуживает одновременно более 250 000 метрик. Их количество постоянно увеличивается. Сбор данных по метрике происходит примерно раз в 3060 секунд. Исторические данные хранятся три месяца и база данных занимает около 1Тб. Для работы используется сервер с двумя процессорами Intel, по двенадцать ядер в каждом. Суммарная загрузка процессоров около 40% и зависит от количества расчетов, выполняемых ALEPIZ. Потребление памяти 64Gb. В качестве дисковой подсистемы используется RAID10 из 8 HDD 10 000 Rpms. Репликация и резервное копирование БД производится по сети на другой сервер.

Системные требования

Для работы ALEPIZ требуется компьютер архитектуры Intel x64 с установленной ОС Microsoft Windows версии не ниже Windows Server 2012 или Windows 10. После установки ALEPIZ использует 200Mb дискового пространства. Потребление оперативной памяти на сервере с 12 ядрами CPU составляет 1Gb. При меньшем количестве ядер потребление памяти будет уменьшено.

Описание возможностей

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

Кроме сбора данных ALEPIZ позволяет генерировать события. Обычно это какие-то пороговые значения. Например, мало свободной памяти или повышенное использование процессора. Это стандартная функция для большинства систем мониторинга. В случае с ALEPIZ, модуль для обработки событий реализован так, чтобы обеспечить организацию рабочих процессов в подразделениях компании.

Dashboard позволяет обрабатывать произошедшие событияDashboard позволяет обрабатывать произошедшие события

ALEPIZ является не только системой мониторинга, но и системой для управления инфраструктурой. Для этого существуют специальные модули - действия. Например, действием может быть запуск или остановка внешнего сервиса, редактирование файла настроек, выполнения запросов к БД или копирование файлов для обновления ПО. Можно разрабатывать собственные действия.

Действия можно объединять в задачи и запускать их в определенное время, либо в зависимости от различных условий. Например, обновление сервиса должно запускаться только если он остановлен. Таким образом можно автоматизировать управление инфраструктурой.

Описание возможностей системы есть на сайте ALEPIZ и доступно на русском языке.

Сущности системы

Чтобы получить больше информации о принципах работы системы и ее возможностях, немного погрузимся в ALEPIZ.

Коллекторы

Для сбора данных используются модули, которые называются коллекторами (collectors). Например, коллектор PING используется для проверки доступности хостов по протоколу ICMP. Коллектор SNMP необходим для сбора данных по одноименному протоколу. MSSQL служит для выполнения запросов к БД MSSQL и т.п. На момент написания статьи в ALEPIZ реализован 21 коллектор. Можно разработать собственный. Информация о разработке коллектора и средства для разработки встроены в ALEPIZ.

Counter settings служит для настройки каунтераCounter settings служит для настройки каунтера

Каунтеры

Каунтеры (counters) это коллекторы с параметрами, которые определяют, какие данные необходимо собирать. Например, для того чтобы коллектор PING начал собирать информацию, ему в качестве параметра необходимо передать имя хоста, доступность которого требуется проверять. Параметры для коллекторов настраиваются в каунтерах.

Также, в каунтерах настраиваются зависимости от других каунтеров, рассчитываются переменные и условия для их работы.

Активные и пассивные коллекторы. Зависимости в каунтерах

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

Например, каунтер с активным коллектором Timer генерирует данные через определенные интервалы времени. Если от него сделать зависимым каунтер с пассивным коллектором SNMP, то данные по протоколу SNMP будут собираться через определенные каунтером интервалы времени. Если от каунтера с SNMP сделать зависимым каунтер с коллектором Events generator, то в случае превышения установленного порогового значения, в Dashboard появится предупреждение о возможной проблеме.

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

Объекты

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

Object editor необходим для редактирования объектов и их привязки к каунтерамObject editor необходим для редактирования объектов и их привязки к каунтерам

Связь объектов и каунтеров

Каунтеры не могут существовать сами по себе. Каждый каунтер должен быть привязан к одному или нескольким объектам. У объектов можно настроить свойства, которые будут использовать каунтеры для сбора или генерации информации. Например, объект хост может содержать свойство IP адрес, который будет использован каунтером с коллектором PING для проверки доступности этого хоста. Каунтер с коллектором PING можно привязать к нескольким объектам- хостам и он будет собирать данные в зависимости от настроенных свойств (IP адреса) для каждого из объектов.

Действия

Действия (actions) это модули ALEPIZ, которые используются для управления как непосредственно сущностями ALEPIZ, так и внешней инфраструктурой. Например, действием может быть модуль для создания нового объекта или каунтера ALEPIZ, или для запуска и остановки сервиса Windows, или для просмотра собранной исторической информации, или данных по различным событиям и т. п.

Можно разработать собственные действия. Информация и средства для разработки встроены в ALEPIZ.

Задачи

Задачи (tasks) это несколько действий, объединенных в группу. Задачи могут запускаться вручную, или в определенное время. A так же в зависимости от состояния определенных каунтеров и даже непосредственно из каунтеров.

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

Tasks maker используется для управления задачамиTasks maker используется для управления задачами

Остальные возможности

Кроме того, в ALEPIZ есть такие модули, как лаунчеры для различных способов запуска действий, средства связи для передачи информации по email, SMS и т.п. Есть встроенный процессор с набором функций для обработки полученных данных, условий в каунтерах и формирования зависимостей на основе этих условий, система обработки произошедших событий с возможностью организации рабочих процессов в организации, средства отладки и т.д. Полное описание возможностей есть на сайте или в справке по ALEPIZ на русском языке.

Заключение

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

Не обязательно использовать сразу все возможности ALEPIZ. Если у Вас небольшая инфраструктура, или в настоящее время нет потребности в автоматическом управлении, можно использовать только часть функций, например, только мониторинг. В дальнейшем у Вас будет возможность расширения и внедрения автоматизации в систему управления инфраструктурой.

Хотел бы еще раз повторить: ALEPIZ распространяется бесплатно по лицензии GPL v3. Вы можете использовать его на свое усмотрение. Я не знаю способов монетизации системы, поэтому принял решение сделать его доступным для всех.

Если Вы решили поставить систему у себя, проще всего скачать и запустить установочный пакет для ОС Microsoft Windows со страницы https://alepiz.com/help/download.pug. В этом случае установка и первичная настройка системы произойдет автоматически. ALEPIZ можно поставить даже на персональный компьютер или ноутбук под управлением Windows 10.

Несмотря на то, что ALEPIZ эксплуатируется, он продолжает разрабатываться и находится в статусе beta тестирования. Если Вы обнаружите дефект или у Вас будут какие-либо пожелания к дальнейшему развитию системы, можете написать мне.

У меня не много времени для полноценной поддержки системы. Поэтому, возможно, буду отвечать не сразу. Но я постараюсь реагировать на сообщения и учитывать пожелания.

Спасибо за прочтение, надеюсь, ALEPIZ поможет Вам и Вашему бизнесу в достижении новых целей.

Подробнее..

Аварии как опыт 3. Как мы спасали свой мониторинг во время аварии в OVH

09.06.2021 12:21:23 | Автор: admin

В данной статье я поделюсь опытом, как недавняя авария в OVH отразилась на нашей инфраструктуре мониторинга, как мы решали проблему и какие уроки из этого извлекли.

О мониторинге у нас

Начать стоит с того, как во Фланте вообще устроен мониторинг клиентских приложений и инфраструктуры в целом. Для этих целей задействованы три разных вида мониторинга:

1. Blackbox-мониторинг для проверки состояния сайтов. Цель проста собирать статистику с определенных endpointов и проверять их состояние по тем условиям, которые требуется установить. Например, это может быть health page в виде JSON-страницы, где отражено состояние всех важных элементов инфраструктуры, или же мониторинг отдельных страниц сайта. У нас принято считать, что данный вид мониторинга самый критичный, так как следит за работоспособностью сайта/сервисов клиента для внешних пользователей.

Вкратце о технической стороне этого мониторинга: он выполняет запросы разного уровня сложности по HTTP/HTTPS. Есть возможность определять размер страницы, ее содержимое, работать с JSON (они обычно используются для построения status page-страниц приложений клиента). Он географически распределен для повышения отказоустойчивости и во избежание всевозможных блокировок (например, от РКН).

Работа данного мониторинга не была затронута аварией благодаря геораспределенности (к тому же, у него вообще нет инсталляций в OVH).

2. Мониторинг Kubernetes-инфраструктуры и приложений клиента, запущенных в ней. С технической точки зрения этот мониторинг основан на связке Prometheus + Grafana + Alertmanager, которые устанавливаются локально на кластеры клиента. Часть данных, собираемых на данных системах мониторинга (например, метрики, напрямую связанные с Kubernetes и Deckhouse), по умолчанию отправляется в нашу общую систему, а остальные могут отправляться опционально (например, для мониторинга приложений и реакции от наших дежурных инженеров).

3. Мониторинг ресурсов, которые находятся вне кластеров Kubernetes. Например, это железные (bare metal) серверы, виртуальные машины и СУБД, запущенные на них. Данную зону мониторинга мы покрываем с помощью стороннего сервиса Okmeter (а с недавних пор уже не очень-то для нас и стороннего). Именно его работа была фатально нарушена в момент аварии OVH.

(А о том, как осуществляется дальнейшая обработка инцидентов, поступающих от всех упомянутых систем, мы рассказывали в этом докладе.)

Таким образом, все проблемы, описанные ниже, связаны с недоступностью одной из используемых систем Okmeter. То есть на некоторое время мы потеряли информацию о некоторой инфраструктуре (вне Kubernetes-кластеров), сохранив при этом доступность blackbox-мониторинга (который гарантирует нам, что главные бизнес-функции работают).

Как мы справлялись с этой аварией? Какие шаги предпринимали во время инцидента? И какие после?

Первые признаки аварии

Проверка доступности внешних средств мониторинга осуществляется с применением метода Dead mans switch (DMS). По своей сути это мониторинг, который работает наоборот:

  • Создается поддельный алерт OK, означающий, что всё хорошо, и он постоянно отправляется с локальных мониторингов (Prometheus, Okmeter и т.п.) в нашу систему инцидент-менеджмента.

  • Пока с мониторингом действительно всё хорошо, алерт OK активен, но в системе не показывается.

  • В обратной ситуации, когда возникают проблемы с мониторингом, алерт OK перестает быть активным, из-за чего автоматически создаётся алерт ERROR о неработающем мониторинге. И вот уже на него надо реагировать.

Данная проверка очень эффективна в ситуациях, которая произошла в роковой день (10 марта): первый алерт о проблеме (ERROR) мы получили как раз от DMS.

События разворачивались следующим образом:

  • Первое сообщение о проблеме алерт от DMS, полученный приблизительно в 3:20 ночи по Москве.

  • Связываемся с коллегами из Okmeter и узнаем, что они испытывают проблемы с ЦОД, в котором расположены. Детальной информации на данный момент не получаем, из-за чего масштабы аварии нам неизвестны. Кроме того, дежурный инженер видит, что у нас корректно работают другие системы мониторинга (blackbox и Kubernetes). Поэтому принимается решение отложить инцидент до утра.

  • Утром (в 8:14) становится известно, что ЦОД сгорел, а Okmeter не будет доступен до тех пор, пока не восстановит свою инфраструктуру в другом ЦОД.

Здесь также стоит остановиться подробнее на том, как была устроена инфраструктура у Okmeter. Основные её компоненты находились в дата-центрах OVH:

  • SBG-2 который был полностью уничтожен пожаром;

  • SBG-1 который был частично поврежден и обесточен.

Так уж получилось, что два формально разных дата-центра OVH оказались соседними зданиями. И пожар, случившийся в одном из них, в скором временем затронул и другое здание тоже.

Руководствуясь этой информацией утром 10 марта, мы сделали вывод, что нужно срочно замещать важные для нас функции Okmeter хоть какими-то решениями на временной основе.

Первые действия

В компании была собрана специальная команда, основными целями которой являлись:

  1. Определение масштабов аварии;

  2. Поэтапное планирование, как устранять последствия инцидента;

  3. Дальнейшее внедрение полученных решений.

В неё вошли тимлиды наших DevOps-команд, инженеры нашей платформенной команды и CTO компании. Позже к ней также добавились отдельные инженеры, помогавшие со срочной разработкой и тестированием новых инструментов, заменивших критичные проверки от Okmeter.

Как уже упоминалось, Okmeter использовался у нас как одно из средств мониторинга. Какую же роль он занимал в общей системе, насколько критичен был? Для определения критичности инцидентов мы опираемся на следующую матрицу:

Матрица критичности алертовМатрица критичности алертов

Эта матрица распространяется на события из всех 3 используемых у нас систем мониторинга. Каждому инциденту, зафиксированному в любой из систем, назначается критичность от S1 (полная потеря работоспособности компонента системы) до S9 (диагностическая информация). Большая часть алертов с критичностью S1 это blackbox-мониторинг, который проверяет состояние сайтов клиента. Однако также к этой категории относится и незначительная часть алертов, отправляемых со стороны Okmeter (подробнее о них см. ниже). Другая незначительная часть приходится на S2, а все остальные имеют более низкую критичность (S3 и т.п.).

Проведя учет количества и видов алертов с S1 и S2 от Okmeter, мы приняли очевидное решение заняться ими в первую очередь, полностью компенсировав другим временным решением. А уже после этого можно было переходить на алерты с меньшей критичностью.

Оповестив всех клиентов, инфраструктуру которых задела авария у Okmeter, мы приступили к составлению плана восстановления.

Порядок и план восстановления алертов от Okmeter

Первая очередь алертов: S1-S2

Итак, какие именно критичные алерты мы потеряли с недоступностью Okmeter? Чтобы оперативно собрать эту информацию, каждая команда инженеров тех, что сопровождают проекты с мониторингом от Okmeter, подготовила статистику алертов, приходивших с 1 июля 2020 года.

Получился следующий список:

  1. Различные алерты для СУБД.

    1. Проверка работоспособности СУБД в целом (запущен ли процесс).

    2. Состояние репликации.

    3. Состояние запросов к БД (например, сколько запросов находятся в ожидании).

  2. Дисковое потребление на виртуальных машинах.

  3. Доступность виртуальных машин в целом.

Вторая очередь алертов: S3 и далее

Ситуация с алертами категории S3 была проще: их меньше, они менее критичные, да и вообще эта категория оказалась не у всех команд.

По итогам этого аудита получилась вторая очередь. Она в основном состояла из проверок доступности менее критичных серверных приложений, таких как ZooKeeper.

Немного магического Bash

Чтобы реализовать замену проверкам и алертам Okmeter, требовалось уметь деплоить на все серверы актуальные скрипты мониторинга, чтобы поддерживать их в актуальном состоянии. Реализация: с помощью Ansible-плейбуков мы задеплоили все необходимые скрипты, среди которых был скрипт автообновления. Последний раз в 10 минут загружал новые версии других скриптов. Из-за очень сжатых сроков основную часть скриптов мы писали на Bash.

Общий подход получился следующим:

  1. Сделали shell-скрипты, которые запускались на виртуальных машинах и bare metal-серверах. Помимо своей основной функции (проверка работоспособности некоторых компонентов) они должны были доставлять сообщения в наш мониторинг с такими же лейблами и другими элементами, как и у Okmeter: имя триггера, его severity, другие лейблы и т.д. Это требовалось для сохранения той логики работы мониторинга, которая была и до падения. В общем, чтобы процесс работы дежурных инженеров оставался неизменным и чтобы работали прежние правила управления инцидентами.

    Быстрой реализации этого этапа способствовал тот факт, что у нас уже были готовые инструменты для работы с API мониторинга внутренний инструмент под названием flint (flant integration).

  2. С помощью Ansible-плейбуков в каждый проект и на каждый сервер, где это было необходимо, задеплоили новые скрипты мониторинга. Ansible-плейбуки пришлось писать с нуля, но благодаря нашей внутренней системе, которая хранит список всех обслуживаемых хостов, деплоить изменения на серверы оказалось просто.

  3. В течение некоторого времени мы дополнительно проверяли, что алерты корректные, а сами скрипты выполняются правильно.

Результаты

На полную реализацию этого временного решения нам понадобился один рабочий день для алертов типа S1-S2 и еще один для S3. Все остальные инциденты (с более низким приоритетом) команды добавляли в индивидуальном порядке по мере необходимости.

В общей сложности новые скрипты были задеплоены примерно на 3000 хостов.

На каждом этапе решения проблемы мы подробно информировали клиентов о ходе восстановительных работ:

Позже статус по аварии и ликвидации её последствий обновлялся как в текстовом виде, так и на регулярных еженедельных встречах. Клиенты отнеслись к происходящему с пониманием и даже уважением:

В тот момент, когда Okmeter стал доступен и функционировал полностью корректно, мы отключили свой кастомный мониторинг, после чего удалили все его следы, оставшиеся на серверах.

Выводы

Для нас данная авария стала показательным случаем и проверкой основных процессов, которые мы выстраиваем в компании: инцидент затронул все команды, практически каждого инженера и сотрудника компании. Основной вывод оказался банален: слаженная командная работа вместе с четким, структурированным планом действий (DRP) позволяет решать задачи любой сложности в очень сжатые сроки. И это по-настоящему ценно в те редкие моменты, когда разваливается гораздо больше, чем вы могли себе представить запланировать.

Более практичные выводы таковы:

  1. Если сервис требует повышенной отказоустойчивости, всегда важно разделять инфраструктуру не только на уровне разных ЦОД, но и географически. Казалось бы, разные ЦОДы у OVH? А в реальной жизни они горели вместе

  2. В процессе подобного инцидента могут возникнуть проблемы и недопонимания в коммуникациях как между Флантом и Okmeter, так и между инженерами внутри нашей компании: недостаточное информирование о масштабах инцидента, медленная реакция и т.п. Хотя в этот раз нам повезло (их не возникло), мы пересмотрели свой регламент эскалации и еще немного ужесточили его, чтобы исключить вероятность появления таких проблем в будущем.

  3. Даже столь масштабно погрузившись в спасение ситуации с технической точки зрения, очень важно не держать клиентов в информационном вакууме: мы постоянно актуализировали статус инцидента и анонсировали прогресс по его решению. На это требуются дополнительные ресурсы и время, но они того стоят.

P.S.

Читайте также в нашем блоге:

Подробнее..

Перевод Знакомство с PromQL Cheatsheet

13.06.2021 12:23:01 | Автор: admin

Скачать Cheatsheet по запросам PromQL

Начало работы с PromQL может быть непростым, если вы только начинаете свое путешествие в увлекательный мир Prometheus. Это руководство поможет понять принципы его работы, статья включает интересные и полезные советы, необходимые для начала работы.

Поскольку Prometheus хранит данные в виде временных рядов (time-series data model), запросы PromQL радикально отличаются от привычного SQL. Понимание, как работать с данными в Prometheus, является ключом к тому, чтобы научиться писать эффективные запросы.

Не забудьте скачать Cheatsheet по запросам PromQL!

Как работают time-series databases

Временные ряды это потоки значений, связанных с меткой времени.

Каждый временной ряд можно идентифицировать по названию метрики и меткам, например:

mongodb_up{}

или

kube_node_labels{cluster="aws-01", label_kubernetes_io_role="master"}

В приведенном выше примере присутствует имя метрики (kube_node_labels) и метки (cluster и label_kubernetes_io_role). На самом деле, метрики тоже являются метками. Приведенный выше запрос можно записать так:

{__name__ = "kube_node_labels", cluster="aws-01", label_kubernetes_io_role="master"}

В Prometheus есть четыре типа метрик:

  • Gauges(Измеритель) значения, которые могут меняться. Например, метрика mongodb_up позволяет узнать, есть ли у exporter соединение с экземпляром MongoDB.

  • Counters(Счетчик) показывают суммарные значения и обычно имеют суффикс _total. Например, http_requests_total.

  • Histogram (Гистограмма) это комбинация различных счетчиков, используется для отслеживания размерных показателей и их продолжительности, таких как длительность запросов.

  • Summary (Сводка)работает как гистограмма, но также рассчитывает квантили.

Знакомство с выборкой данных PromQL

Выбрать данные в PromQL так же просто, как указать метрику, из которой вы хотите получить данные. В этом примере мы будем использовать метрику http_requests_total.

Допустим, мы хотим узнать количество запросов по пути / api на хосте 10.2.0.4. Для этого мы будем использовать метки host и path из этой метрики:

http_requests_total{host="10.2.0.4", path="/api"}

Запрос вернет следующие значения:

name

host

path

status_code

value

http_requests_total

10.2.0.4

/api

200

98

http_requests_total

10.2.0.4

/api

503

20

http_requests_total

10.2.0.4

/api

401

1

Каждая строка в этой таблице представляет собой поток с последним доступным значением. Поскольку http_requests_total содержит определенное количество запросов, сделанных с момента последнего перезапуска счетчика, мы видим 98 успешных запросов.

Это называетсяinstant vector, самое раннее значение для каждого потока на указанный в запросе момент времени. Поскольку семплы берутся в случайное время, Prometheus округляет результаты. Если длительность не указана, то возвращается последнее доступное значение.

Кроме того, вы можете получить instant vector из другого отрезка времени (например, день назад).

Для этого вам нужно добавить offset (смещение), например:

http_requests_total{host="10.2.0.4", path="/api", status_code="200"} offset 1d

Чтобы получить значение метрики в пределах указанного отрезка времени, необходимо указать его в скобках:

http_requests_total{host="10.2.0.4", path="/api"}[10m]

Запрос вернет следующие значения:

name

host

path

status_code

value

http_requests_total

10.2.0.4

/api

200

641309@1614690905.515

641314@1614690965.515

641319@1614691025.502

http_requests_total

10.2.0.5

/api

200

641319@1614690936.628

641324@1614690996.628

641329@1614691056.628

http_requests_total

10.2.0.2

/api

401

368736@1614690901.371

368737@1614690961.372

368738@1614691021.372

Запрос возвращает несколько значений для каждого временного ряда потому, что мы запросили данные за определенный период времени, а каждое значение связано с отметкой времени.

Это называется range vector все значения для каждой серии в пределах указанного временного интервала.

Знакомство с агрегаторами и операторами PromQL

Как видите, селекторы PromQL помогают получить данные метрик. Но что, если вы хотите получить более сложные результаты?

Представим, что у нас есть метрика node_cpu_cores с меткой cluster. Мы могли бы, например, суммировать результаты, объединяя их по определенной метке:

sum by (cluster) (node_cpu_cores)

Запрос вернет следующие значения:

cluster

value

foo

100

bar

50

С помощью этого простого запроса мы видим, что имеется 100 ядер ЦП для кластера cluster_foo и 50 для cluster_bar.

Кроме того, мы можем использовать в запросах PromQL арифметические операторы. Например, используя метрику node_memory_MemFree_bytes, которая возвращает объем свободной памяти в байтах, мы могли бы получить это значение в мегабайтах с помощью оператора деления:

node_memory_MemFree_bytes / (1024 * 1024)

Мы также можем получить процент доступной свободной памяти, сравнив предыдущую метрику с node_memory_MemTotal_bytes, которая возвращает общий объем памяти, доступной на узле:

(node_memory_MemFree_bytes / node_memory_MemTotal_bytes) * 100

Теперь мы можем использовать этот запрос для создания оповещения, когда на узле остается менее 5% свободной памяти:

(node_memory_MemFree_bytes / node_memory_MemTotal_bytes) * 100 < 5

Знакомство с функциями PromQL

PromQL поддерживает большое количество функций, которые мы можем использовать для получения более сложных результатов. Например, в предыдущем примере мы могли бы использовать функцию topk, чтобы определить, какой из двух узлов имеет больший объем свободной памяти (в процентах):

topk(2, (node_memory_MemFree_bytes / node_memory_MemTotal_bytes) * 100)

Prometheus позволяет не только получить информацию о прошедших событиях, но даже строить прогнозы. Функция pred_linear предсказывает, где будет временной ряд через заданный промежуток времени.

Представьте, что вы хотите узнать, сколько свободного места будет доступно на диске в следующие 24 часа. Вы можете применить функцию pred_linear к результатам за прошлую неделю из метрики node_filesystem_free_bytes, которая возвращает доступное свободное место на диске. Это позволяет прогнозировать объем свободного дискового пространства в гигабайтах в ближайшие 24 часа:

predict_linear(node_filesystem_free_bytes[1w], 3600 * 24) / (1024 * 1024 * 1024) < 100

При работе со счетчиками Prometheus удобно использовать функцию rate. Она вычисляет среднюю скорость увеличения временного ряда в векторе диапазона в секунду, сбросы счетчика автоматически корректируются. Кроме того, вычисление экстраполируется к концам временного диапазона.

Что делать, если нам нужно создать оповещение, которое срабатывает, если мы не получали запрос в течение 10 минут. Мы не можем просто использовать метрику http_requests_total, потому что при сбросе счетчика в течение указанного временного диапазона результаты были бы неточными:

http_requests_total[10m]

name

host

path

status_code

value

http_requests_total

10.2.0.4

/api

200

100@1614690905.515

300@1614690965.515

50@1614691025.502

В приведенном выше примере после сброса счетчика мы получаем отрицательные значения от 300 до 50, поэтому нам недостаточно только этой метрики. Мы можем решить проблему с помощью функции rate. Поскольку он считает сбросы счетчика, результаты фиксируются, как если бы они были такими:

name

host

path

status_code

value

http_requests_total

10.2.0.4

/api

200

100@1614690905.515

300@1614690965.515

350@1614691025.502

rate(http_requests_total[10m])

name

host

path

status_code

value

http_requests_total

10.2.0.4

/api

200

0.83

Независимо от сбросов за последние 10 минут в среднем было 0,83 запроса в секунду. Теперь мы можем настроить оповещение:

rate(http_requests_total[10m]) = 0

Что дальше?

В этой статье мы узнали, как Prometheus хранит данные, рассмотрели примеры запросов PromQL для выборки и агрегирования данных.

Вы можете скачать Cheatsheet по PromQL, чтобы узнать больше об операторах и функциях PromQL. Вы также можете проверить все примеры из статьи и Cheatsheet с нашим сервисом Prometheus playground.

Подробнее..

BGPexplorer машина времени для IPMPLS сетей

10.06.2021 18:12:02 | Автор: admin
Предисловие

Бывает так что при разборе причин деградации сетевых сервисов хочется иметь машину времени. Ну или хотя бы что-то, что записывало бы историю измерений маршрутов... Если Вы попадали когда-нибудь в такую ситуацию, то, возможно, это будет интересно.

Современные сети, основанные на маршрутизации IP-пакетов, а точнее сервисы, которые они предоставляют, по факту управляются протоколом BGP. Этот протокол был спроектирован в конце 80-хх на трех салфетках. Да, с тех пор в этот протокол добавили массу возможностей, в том числе обмен маршрутной информацией VPN, правилами фильтрации трафика и всяким прочим полезным, но основа там осталась все той же, описанной на трех салфетках. И в этом есть свой плюс, потому что этот протокол в своей сути очень прост.

Но я хотел поговорить не о его простоте, а о "махании кулаками после драки", с которой частенько приходится сталкивать любой службе эксплуатации сети, или NOC - network operation centre (а может быть и center).

Поступает жалоба "а у меня вот сайт не открывается", или "вот час тому назад плохо работал сайт такой-то, а 5 минут тому назад он починился". Инженер идет на маршрутизатор и смотрит что маршрут к адресу рекомого сайта изменился 5 минут тому назад. И что с этим можно сделать? Чаще всего мало чего. Маршрутизатор знает, что вот такой маршрут "прилетел" 5 минут тому назад, а вот что было раньше? Может быть ничего существенного и не произошло, у маршрута обновились какие-нибудь информационные параметры, а пакеты как летели, так и летят в том же направлении. А может быть наоборот - маршрут изменился существенно и пакеты летят совсем в другом направлении. И узнать историю без дополнительного инструментария (или машины времени) нет возможности. И опять же - хорошо бы узнать, что же именно менялось. Да, есть глобальный инструмент bgplay. Но он рассчитан на использование в Интернете и запоминает изменения при перестроении маршрута между разными провайдерами. А вот изменения внутри сети одного провайдера он не ловит, да и не должен, так как не все то что происходит внутри автономной системы, должно быть видно снаружи.

И вот захотелось мне заиметь такой инструмент. Поиски готового ни к чему не привели (ни на что тут не претендую, может плохо искал). Соответственно, если нет готового решения - почему бы и не попробовать сделать самому? Все вроде понятно, собираем маршрутную информацию и храним историю изменений.

А вот дальше я подзавис. Самая лучшая библиотека, даже я бы сказал целый фреймворк, для обработки BGP - это пакет exabgp. Всем хорош и удобен. Один, на мой взгляд, существенный минус - он на python. Не то чтобы я был питононенавистником, отнюдь. Но каждый инструмент хорош, когда применяется по назначению. А python имеет всем известные особенности (интерпретатор, GIL), которые препятствуют эффективной обработке данных, если алгоритмы реализовывать именно на нем. И в данном случае мне хотелось бы иметь реализацию инструмента на компилируемом (как минимум) языке, с управляемыми политиками блокировок. А также иметь возможность выделить обработку протокола BGP в виде библиотеки и желательно чтобы применяемый язык мог позволить библиотеке жить без своего неотделимого и неотъемлемого рантайма (привет, golang!). Для чего? Ну, например, для того чтобы в перспективе применять эту библиотеку для других bgp-шных приложений. Ну и для скорости. Далеко не для всех видов запросов для поиска маршрутной информации возможно построить эффективный индекс.

Решил я попробовать в качестве основного языка по этой теме Rust и в общем все что хотел получилось. Работу с протоколом BGP выделил в библиотеку. В отличие от exabgp реализовывать логику работы BGP FSM в библиотеке я не стал, по той простой причине что в Rust для сети используется не одно API, std там строго синхронное, а в реальных задачах лучше иметь возможность применять по желанию и потребности асинхронные библиотеки. Библиотеку разумеется назвал zettabgp, а приложение bgpexplorer.

Принцип работы прост. Bgpexplorer может как выступать в роли bgp-спикера, то есть роутер (лучше всего route reflector) устанавливает с сервером bgp-соседство, и отдает в сторону сервера всю маршрутную информацию. Приложение накапливает в своей RIB (Routing Information Database) как актуальную маршрутную информацию, так и историческую. Для просмотра и поисковых запросов доступен веб-интерфейс. Сейчас все хранится в оперативной памяти и ее нужно достаточно много - в зависимости разумеется от того, какого объема таблицу маршрутизации нужно отслеживать.


Если интересно попробовать - то это просто. Нужна сеть, которую нужно мониторить и комп (сервер) с достаточно большим объемом ОЗУ чтобы маршрутная информация туда поместилась.

На сервере нужно взять исходники с гитхаба, предполагается что уже есть git и rust.

$ git clone https://github.com/wladwm/bgpexplorer...$ cd bgpexplorer$ cargo build...

Приложение собрано. Теперь на роутере настроим соседство с сервером.

Если это Cisco, то:

! Номер автономки тут 65535 разумеется для примера, как и адресаrouter bgp 65535 ! указываем адрес сервера с той же автономкой, чтобы сессия была IBGP neighbor 10.1.1.1 remote-as 65535 ! указываем с какого адреса соединяться neighbor 10.1.1.1 update-source Loopback0 ! будем ждать попыток соединения с сервера neighbor 10.1.1.1 transport connection-mode passive address-family ipv4 ! для паблик инета активируем  neighbor 10.1.1.1 activate ! отправляем на сервер вообще все что есть  neighbor 10.1.1.1 route-reflector-client ! Активируем если нужно ipv4 labeled-unicast  neighbor 10.1.1.1 send-label address-family vpnv4 ! включаем VPNv4  neighbor 10.1.1.1 activate  neighbor 10.1.1.1 send-community extended

Возвращаемся на сервер и подготовим конфигурационный файл для приложения

$ cat > bgpexplorer.ini <<EOF[main]httplisten=0.0.0.0:8080httproot=contribsession=s0whoisjsonconfig=whois.json[s0]mode=bmpactivebgppeer=10.0.0.1peeras=65535EOF

В секции main указываем:

  • httplisten на каком адресе и порту будет работать протокол http

  • httproot где лежит корень файлового сервиса. Там лежит index.html и все такое прочее.

  • Whoisjsonconfig указывает на файл конфигурации сервиса whois

  • Session это имя секции, описывающей режим работы bgp, в данном примере s0

В секции сессии (s0 в данном примере) указано:

  • bgppeer адрес роутера BGP для активного режима

  • Peeras номер автономной системы

  • protolisten адрес:порт, где ожидать входящего соединения по протоколу BGP или BMP

  • Mode варианты работы протокола

В mode можно указать:

  • bgppassive ждать входящего подключения от роутера

  • bgpactive инициировать подключение к роутеру

  • bmpactive инициировать подключение к роутеру по протоколу BMP

  • bmppassive ждать входящего подключения от роутера по протоколу BMP

После написания ini-файла можно запустить bgpexplorer, например, командой

cargo run

После чего можно открыть браузер и направить его на адрес сервера с указанием порта.

На самом верху будет выбор RIB для просмотра - IPv4, IPv6, VPN разные всякие и т.п.

Далее строка для фильтра, а уже после нее - пейджинг и собственно маршрутная информация.

Неактивные маршруты будут отображены серым курсивом. У маршрутов, у которых есть история изменений будет кнопка разворачивания истории.

В фильтре можно задавать кроме собственно подсетей фильтрацию по community, aspath, nexthop, route-target, route-distinguisher.

При наведении курсора на ASn, адреса роутеров будет выполняться запрос к whois или DNS, и полученная информация будет отображаться в попапе. Иногда это долго, но бывает полезно.


Буду рад, если этот инструмент пригодится еще кому-нибудь. Найденные проблемы, пожелания, идеи, конструктивная критика приветствуется.

Подробнее..

Кому-то Okmeter даже сможет заменить людей. Как будет развиваться сервис мониторинга после его покупки Флантом

31.05.2021 10:13:24 | Автор: admin

Флант и Okmeter сотрудничают с 2017 года. Для Фланта Okmeter один из основных инструментов мониторинга инфраструктуры клиентов; на протяжении этих лет компании сообща улучшают его возможности.

В середине мая Флант объявил о покупке Okmeter. Несмотря на то, что для некоторых участников DevOps-рынка сделка стала новостью, во многом это естественный результат плодотворного сотрудничества двух компаний.

Чтобы ответить на накопившиеся в сообществе вопросы, мы представляем интервью с Николаем Сивко, сооснователем и теперь уже бывшим владельцем Okmeter, и Андреем Колаштовым, совладельцем и управляющим партнёром Фланта, который будет заниматься развитием проекта Okmeter. Николай и Андрей рассказали, почему компании решились на эту сделку, как она повлияет на существующих и будущих клиентов Okmeter, а также о том, в каком направлении теперь будет развиваться сервис и какую функциональность получит в ближайшее время.

Николай Сивко выступает на одной из конференций HighLoad++Николай Сивко выступает на одной из конференций HighLoad++

О сделке и немного предыстории

Как компании к этому пришли?

Николай: Началось всё с того, что года тричетыре назад Флант пришли к нам и сказали: Вы бежите быстро, мы вас устанем догонять. И мониторинг не наш фокус.

Андрей: В то время у нас был фокус на платформу. То есть на то, чтобы делать свою работу хорошо, именно ее DevOps-часть. Нам нужно было эффективно обслуживать клиентов, и закрыть направление мониторинга готовым решением. Для обеих компаний это было стратегическое сотрудничество.

Андрей: Мы тогда очень устали от того, чтобы настраивать разные небезызвестные системы мониторинга, приделывать к ним какие-то экспортеры и ждать, что у нас что-то будет действительно замониторено. И у нас не было команды, которая бы занималась сутью мониторинга: какую метрику замониторить, как это реализовать, как ее вывести на графики и так далее. Конечно, собственный мониторинг у нас как-то развивался и работал, но сказать, чтобы это было сделано круто, нет. А у ребят это было именно так.

А как появилась сама идея сделки?

Николай: Флант был у нас самым большим клиентом. В какой-то момент им стало интереснее больше влиять на продукт, быстрее закрывать конкретно свои потребности. Они захотели контролировать Okmeter. Нам эта идея понравилась.

Андрей: Всё так. Ну, и направление мониторинга для компании, которая занимается обслуживанием инфраструктуры, довольно важное. Мониторинг помогает вовремя замечать проблемы клиентов, предупреждать их. Нам хотелось, чтобы у нас был свой мониторинг, хотелось полностью на него влиять. Например, если что-то нужно, то быстро и без проблем добавить это, изменить.

Плюс, с точки зрения бизнеса, это дает Фланту возможность получать продуктовую выручку. То есть продавать не только услуги, но и продукт. И этот продукт теперь будет содержать в себе еще больше нашей экспертизы.

Андрей Колаштов (в центре) на HighLoad++ Весна 2021Андрей Колаштов (в центре) на HighLoad++ Весна 2021

Николай как-то будет участвовать в дальнейшем развитии Okmeter?

Андрей: Мы бы хотели использовать огромный опыт Николая для помощи в реализации некоторых функций мониторинга. На начальном этапе точно будем прибегать к его консультациям, и достаточно часто.

Николай: Сейчас мы с командой передаем Фланту все дела так, чтобы сервис для всех клиентов оставался непрерывным. Также мы передаем бэклог нашего видения развития Okmeter. Но дальше Флант будет развивать продукт самостоятельно.

Дело в том, что Флант уже многое умеет и многое знает про Okmeter. Это для них не новые ворота, не blackbox какой-то. У Фланта сформировалось собственное видение того, как развивать сервис, и они уже начали его воплощать. Скажем так, у них уже руки чешутся сделать всё как надо.

Как сделка повлияет на рынок и на клиентов

Этот кейс может как-то повлиять на местный рынок мониторинга?

Андрей: Сейчас на рынке мало игроков, которые делают мониторинг и при этом имеют огромный опыт в эксплуатации, игроков, которые понимают, как делать мониторинг правильно. Сделка даст рынку возможность получить реальный опыт людей, эксплуатирующих серверы.

Николай: Я думаю, сделка повлияет не столько на рынок мониторинга, сколько на рынок эксплуатации и всего, что связано с DevOps. Потому что часть того, что делает сейчас Флант как сервисная компания эту экспертизу, можно заложить в продукт. И экспертиза будет, естественно, дешевле, чем люди. Кому-то Okmeter даже сможет заменить людей.

Андрей: Да, потому что Okmeter это мониторинг, который многое делает сам. Допустим, вы поставили 5 нод, и Okmeter вам сразу всё сам замониторил. Он автоматически нашел какой-нибудь Postgres, нарисовал по нему графики, тут же зажег алерты, что у вас есть какие-то проблемы. То есть это не вы создаете и добавляете эти алерты. За вас уже подумали, в какие точки стукнуться, чтобы проверить, что у вас всё хорошо или наоборот, и почему.

Николай: Можно привести пример известного в России сервиса мониторинга, который многие используют. И все знают, что эта штука, которую вы ставите, по своей сути пустая. Пока вы сами там всё не настроите в ней, она бесполезна. То есть это лопата, которая задачу никак не решает: она просто позволяет вам самому копать.

А Okmeter делает решение, которое самостоятельно работает, причем из коробки. Это то же самое, как если бы опытный человек взглянул на графики, на алерты, и сказал: болит вот здесь.

А что касается существующих клиентов Okmeter, как продажа сервиса скажется на них?

Николай: Положительно, конечно. У Фланта есть экспертиза, которой у Okmeter не было, и клиенты теперь смогут ее получать. Флант сидит на таком потоке знаний, которого в России реально ни у кого нет. Если всю эту экспертизу привнести в мониторинг, он станет квадратично более классным.

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

Связь с инцидентом OVH

Были слухи, что продажа Okmeter связана с недавним пожаром в дата-центрах французского провайдера OVH, когда мониторинг на некоторое время вышел из строя. Насколько это близко к реальности?

Николай: Это просто совпало по времени, инцидент никак не повлиял на решение о продаже. Да, это была неприятная история для Okmeter и для наших клиентов. Но мы выстроили нормальную коммуникацию, нам удалось почти всех клиентов сохранить. Ни по бизнес-показателям, ни по репутации Okmeter этот инцидент не нанес какого-то значительного ущерба.

Пожар в дата-центрах OVH в марте этого года; автор фото Xavier GarreauПожар в дата-центрах OVH в марте этого года; автор фото Xavier Garreau

В чем была главная проблема с OVH?

Николай: В том, что OVH особо не рассказывал про свои дата-центры. Мы считали, что три дата-центра, в которых была размещена инфраструктура Okmeter в Страсбурге, это настоящая availability-зона, что дата-центры независимые. Мы на это полагались, и это было главной нашей ошибкой.

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

Прим. ред.: кстати, о событиях этого пожара и вынужденных действиях инженеров компании Флант мы ещё планируем опубликовать статью в скором времени.

Ближайшие планы

Как будет развиваться сервис?

Андрей: Мы видим Okmeter как несколько взаимодополняющих продуктов: хранилище, платформа и insights (идеи).

Хранилище будет обеспечивать высокопроизводительное и экономически эффективное хранение метрик, алертов, логов и трейсов. Планируется, что в него можно будет загружать не только метрики из Okmeter, но и метрики сторонних сервисов мониторинга; пользователи смогут подключить, например, Grafana и смотреть свои метрики, пользуясь нашим хранилищем.

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

Insights это история про готовые метрики, дашборды и алерты для популярных технологий и частых кейсов. Мы создадим удобную базу из коробки. Можно сказать, что команда insights будет заниматься смыслом. Она будет разбираться с тем, что именно нужно замониторить так, чтобы действительно понимать, что происходит в сервисах, корректно ли они работают и не собираются ли упасть. Плюс эта команда будет заниматься тем, чтобы правильно строить дашборды так, чтобы была нормальная наблюдаемость (observability). Чтобы можно было посмотреть на проблему и сразу понять, как это починить, не залезая в логи. То есть, чтобы максимально ускорить процесс решения проблем.

Расскажите чуть подробнее о платформе и, в частности, об интерфейсе Okmeter: что планируете улучшить в первую очередь?

Андрей: Мы планируем сделать более современные способы визуализации тех или иных компонентов, в зависимости от того, что потребуется нам и нашим клиентам. Также расширим интеграцию с Open Source-сервисами мониторинга, добавим возможность подключать к Okmeter сторонние плагины, добавлять в интерфейс графики и дашборды из других инструментов. По сути, в Okmeter уже есть почти все графики и всё, что нужно для мониторинга, но нам самим нужно больше, и мы это сделаем.

В командах будут только разработчики?

Андрей: В командах хранилища и платформы да. В insights и разработчики, и опытные SRE-инженеры; они будут разбираться, что у клиентов упало, почему мы не смогли вовремя это спрогнозировать и что надо замониторить, чтобы подобные проблемы предотвращать. Это будет большая команда, которая займется доработками как интерфейса, так и агента (пользовательская программа-клиент Okmeter прим. ред.), и которая будет помогать быстрее находить проблемы.

То есть это будут действующие инженеры?

Андрей: Не совсем. Они будут приходить на аварию, но не для того, чтобы починить ее, а чтобы проанализировать, почему Okmeter не предсказал эту аварию. Допустим, лежала база данных. У нее постепенно переполнялся некоторый буфер. Но графика и алертов на это переполнение не было, хотя мы могли бы за неделю до этого узнать, что буфер начал переполняться. И вот команда insights разбирается с этим, думает, как этот буфер замониторить и в итоге помочь администраторам базы сделать так, чтобы база потом не упала.

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

Андрей: Конечно. Будет очень хорошее расширение. Мы будем добавлять всё самое популярное, чего сейчас нет: MongoDB, ClickHouse, ProxySQL, HAProxy, Ceph и расширять функционал существующих. И не только базы данных. Также будем сильно расширять историю с мониторингом Kubernetes.

У Фланта, кажется, уже достаточно много наработок по мониторингу Kubernetes? Как это теперь будет совмещаться с Okmeter?

Андрей: Да, Kubernetes у нас уже замониторен своими силами. Это сделано на базе Prometheus и кучи кастомных и собственных экспортеров, чем занималась специальная команда внутри Фланта, отвечающая за платформу Kubernetes. Много сил было вложено в правильный мониторинг Kubernetes. В то же время своя интеграция с Kubernetes есть и у Okmeter. Okmeter уже работает с Kubernetes аналогично тому, как с другими сервисами и софтом на обычных узлах. То есть его можно поставить внутрь Kubernetes, он сам определит весь софт и попытается к нему подключиться, чтобы снимать метрики. Мы будем объединять эту интеграцию и наши наработки в более мощное и универсальное решение на базе Okmeter, добавляя в него наши дашборды, экспортеры и опыт в целом.

Наша детальная статистика потребления трафика по конкретному пространству имен Kubernetes-кластераНаша детальная статистика потребления трафика по конкретному пространству имен Kubernetes-кластера

А что касается инсталляций on-premises какие здесь планы?

Андрей: Это направление мы тоже будем активно развивать. Okmeter раньше был почти для всех облачным, сейчас же появилась возможность устанавливать его on-premises силами Фланта. У нас уже есть опыт в таких инсталляциях Okmeter.

То есть будет два варианта установки?

Андрей: Да, можно будет выбирать облачную или on-premises-версию. Если вам надо, например, замониторить пару серверов и у вас нет жестких требований по безопасности, оптимальный вариант облачная версия. Если требования по ИБ высокие, можно установить Okmeter on-premises в свой закрытый контур. Хотя принцип работы тот же: ставится агент, который отправляет данные не в облако, а в локальное хранилище.

Планируете ли создание Open Source-компонентов Okmeter?

Андрей: Да. Хранилище Okmeter с большой вероятностью будет основано на Open Source-компонентах. Соответственно, все эти компоненты мы будем выкладывать на GitHub, будем в них контрибьютить и добавлять что-то, что нам помогает улучшать хранилище. Планов по открытию кода платформы и Insights в настоящий момент нет, но всё может измениться. И, конечно, это не касается тех компонентов, которые уже являются Open Source-проектами и в upstream которых мы будем приносить свои улучшения.

Николай упоминал о планах по повышению отказоустойчивости инфраструктуры Okmeter. Как именно это будет реализовано?

Андрей: Это одна из первоочередных наших задач, мы очень сфокусированы на том, чтобы сделать отказоустойчивый storage.

В первую очередь планируем сделать так, чтобы при выходе из строя основного дата-центра не позже, чем через 30 минут, Okmeter поднимался в другом дата-центре уже со всеми дашбордами, графиками, алертами, настройками. То есть всё уже будет сразу мониториться, и постепенно из бэкапа будут подтягиваться метрики. Это будет реализовано с помощью скриптов оркестрации, которые позволяют быстро создать новую инфраструктуру и накатить на нее софт.

Второй шаг разместить инфраструктуру в нескольких ЦОДах, в разных странах. Клиенты смогут сами выбирать уровень отказоустойчивости, то есть сколько копий данных хранить, в каких ЦОДах.

Глобальные планы

Какова стратегия Фланта в плане повышения конкурентоспособности Okmeter на международном рынке?

Андрей: Во-первых, расширение функциональности. Обязательно будем улучшать UХ, чтобы сделать платформу реально удобной и функциональной, дополнить всем, что у нас самих болит, всем, что мы хотим замониторить.

Во-вторых, активный маркетинг по всем направлениям. У Okmeter уже есть английская версия сайта и зарубежные клиенты, но этого явно недостаточно. Маркетинг будет очень серьезно усилен.

Также будем искать партнеров, которые бы помогали дорабатывать мониторинг конкретных сервисов например, баз данных. Нам интересны компании, у которых глубокая экспертиза в каком-то определенном софте. В этом плане мы открыты к сотрудничеству.

P.S.

Читайте также в нашем блоге:

Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru