Telegram Web Link
Буду немножко рассказывать про нашу EVA ICS, потому что про внутренности больше рассказывать негде, клиентам главное чтобы работало. Год назад вышла уже 4я версия, и это первая версия которая делалась именно под хотелки больших ентерпрайзов и первая версия на Rust.

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

- K8S - это система, которая раскрывается, когда имеет как минимум два компьютера (плюс мастер-ноду). про minikube я конечно знаю, но он дальше не скейлится да и для прода не подходит. EVA ICS прекрасно работает на одном компьютере, что критично когда целый узел (у нас узел - это то что у куба кластер, а то что у куба узел у нас - secondary point) ставят куда-то в электро-шкаф на одну машину

- При этом да, мы тоже умеем скейлиться на secondary points, но это не особо критично

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

- Из предыдущего - K8S заточен для работы с разношерстными приложениями. У нас все сервисы пишутся конкретно под нашу платформу

- Все сервисы имеют прямой доступ к IPC-шине узла (BUS/RT). Именно не общаются через HTTP с вебсокетами - мы уже это проходили в v3. А имеют полноценный IPC, с pub/sub, RPC и прочим. На шине нет понятия клиент-сервер, каждый, кто к ней подключается, может быть как тем, так и другим

Дальше интересное

- Узлы имеют локальный контекст переменных, который реплицируется и принимает команды на изменение извне (мы называем их actions). Тоесть, если вы создали группу объектов для регистров локального PLC, оператор за океаном на своем узле (если мы уберем все ACLs) будет видеть этот PLC так же, как оператор локальный. И естественно, не только оператор, а любой локальный софт, скрипты, интерфейсы и прочее подобное

- Репликация пробрасывается через обычный Pub/Sub, в том числе можно MQTT, и может иметь сколько угодно уровней вверх, вбок, взад, вперед и как хочется

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

- Это в первую очередь сильно расширяет возможности deployment - в кубе вы можете деплоить из коробки только на один кластер. У нас вы можете обновлять конфигурацию, добавлять и убирать сервисы и объекты контекста на любом количестве узлов за один раз

- Во вторую очередь это удобно для всяких разных скриптов и утилит - для того чтобы вызвать RPC-метод сервиса, достаточно указать узел, ID сервиса и что мы вызываем. И нам абсолютно всё равно, где оно находится физически. если скрипт не может подключиться к шине напрямую - конечно же есть и HTTP (и любимые вебсокеты)
🔥11👍6
Если в LinkedIn прилетает запрос от красивой девушки - естественно сразу бан.

Тем не менее, рекрутеры годами пытаются использовать этот "хитрый" приём. Вопрос - это они мазохисты или их на каких-то специальных курсах учат?
😁20👍4
Про необычные pub/sub. Немного расскажу про Zenoh (https://zenoh.io).

За Zenoh я давно наблюдаю, есть знакомые которые даже пытаются юзать его в проде.

Из плюсов:

- написан на Rust
- в пределах локалки - serverless-архитектура, пиры сами находят друг друга
- быстрый, с хорошей latency

Что не нравится:

- плохая документация. ребята делают нестандартную pub/sub модель, при этом нет описания архитектуры. она не просто должна быть в документации, она должна быть где-то на уровне Quick Start, а ее нет вообще. я в своё время потратил несколько дней чтобы просто понять, как оно работает
- после того как вы подняли пир, у вас нет никакой гарантии, что вас вообще кто-то слушает. от отправки первого сообщения до discovery вас остальными участниками сети может пройти иногда несколько десятков секунд. тоже самое касается и роутеров
- не понимаю, зачем встроенный storage для истории топиков. этим должны заниматься tsdb

Посмотреть в любом случае рекомендую.
👍11
Преподаватели курсов по Python жалуются, что фейсбух банит их рекламные кабинеты - недоAI соцсети считает, что они продают экзотических животных.


if (str_contains($text, "Python")) {
ban();
}
😁36👍2💩1
Сегодня расскажу про репликацию событий через pub/sub.

Классическая репликация IoT-событий ужасна - устройство долбит в топик данные каждые 5-10 секунд, а с другой стороны его слушают. Мне никогда не нравилось этих 5 секунд ждать, а на проде интернет нередко оказывался медленным и/или дорогим. Поэтому появилась идея, чтобы передавались только измененные данные и сразу. Изначально первоначальное состояние бралось из retain-топиков, но быстро выяснилось, что retain в pub/sub - бонус, а не mandatory и не надо делать круглые глаза, когда его нет. Поэтому в прод пошел вариант (и он уже 5 лет работает неизменно), когда push и pull совмещаются - события пушаются, но узел при подключении к pub/sub-серверу делает pull-запрос на всех соседей и они лично присылают ему всё, что он запросил, большим пакетом, ну или несколькими. Для надежности, pull повторяется, скажем каждые 5 минут - мало ли чего.

Такой подход убивает очередность событий - пока вы делаете pull, вам уже могут наслать push'ей. Но очередность в pub/sub тоже бонус - никто и никогда вам ее не гарантирует. Изначально очередность событий решалась их timestamp'ом, но поскольку время умеет на серверах ходить назад, остановились на варианте, который мы называем IEID (incremental event id) - 128-битное число, в котором младшие 64 бита - monotonic узла, а старшие - счётчик, который увеличивается при каждой перезагрузке системы. Такое ID дает 100% гарантию, что каждое следующее будет больше предыдущего, при этом его не нужно нигде хранить.

Следующая проблема, с которой быстро столкнулись - 90% pub/sub годятся только для home-инсталляций (даже платные-дорогие!), а когда количество подписок на топики приближается к 100к, всё это радостно начинает дохнуть. Поскольку pub/sub - выбор клиента, появилась фича включать один-пару балк-топиков, в которые отправитель отсылал пакет данных, скажем каждые 300-500ms. Это, в свою очередь, совершенно убивало ACL model pub/sub сервера, но законичилось оно в целом хорошо - пакет можно не только подписывать, а и дополнительно шифровать, что полезно - полностью убирается фактор контроля всей сети через взлом pub/sub. Также бонус балк-пакетов - их можно сжимать, а сжимаются IoT-данные просто замечательно.

Оставалась одна проблема, которую решили только в прошлом году, и это одна из немногих фич, которая в EVA ICS платная. Если узел отправляет данные - он не знает, были ли они получены. В результате, если получатель был оффлайн, на графиках образуются дыры, а дата-инженеры воют кипятком. Тут на помощь пришел опыт из 90х и была внедрена технология, которую мы называем zero-failure replication - второй слой репликации, в котором узел собирает данные в пакеты и хранит определенное время. Получатель, в свою очередь, по RPC (у нас же есть RPC over pub/sub) периодически запрашивает пакеты и разрешает отправителю их удалить только после подтверждения, что пакет обработан. В общем, всё как в старом-добром FIDO.
👍11🔥7
Кстати как работают нормальные TSDB а не всякие кастомные самоделки. Сегодня на одной машине заметил, что Timescale сжала базу в 4521(!) раз.
🔥13👍1
Я когда вижу "использование IoT для измерения температуры и влажности", хочется взять и отвести за руку в детский сад.

Но Grafana пошли еще дальше. Представьте себе, 2023й год, компания, недавно получившая 240 миллионов инвестиций от JP Morgan, предлагают делать это на Raspberry Pi + DHT22.

Всё-таки в любой компании ОЧЕНЬ важно, не что вы делаете, а кому вы это продаете. А продавать можно и говно на палке. Мы когда-то в начале нулевых лицензию на squid продавали, который был как настоящий примерно на 99%.

https://grafana.com/blog/2023/10/23/monitor-temperature-and-humidity-with-grafana-and-raspberry-pi/?utm_source=grafana_news&utm_medium=rss
😁13👍2
Хороший вопрос задали в комментариях, насчёт репликации переменных и actions.

Как это реализовано у 90% платформ - да никак, данные идут снизу вверх и никакой обратной связи нету. Суровая правда жизни - в IoT системах отсутствует контроль, а то что они пишут control - это маркетинг и то что вы визуально контролируете состояние.

Как это реализовано у нас в EVA ICS (уже 6 лет и не менялось, потому что реализовано весьма удачно):

- у каждой переменной есть source - узел, на котором она объявлена, он ее и апдейтит

- остальные узлы имеют readonly-копию этой переменной и знают source-узел

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

- source-узел проверит, имеет ли право ваш локальный узел давать такую команду, и если да - обработает ее

Далее, у нас есть read-write переменные двух типов: lvar - абстрактная переменная логики, которая не замаплена на оборудование. и unit - изменяемая переменная, например регистр на PLC.

- в случае lvar, есть несколько команд: set, reset, clear и toggle, с разной логикой, их обрабатывает сам source-узел атомарно

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

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

- у микросервиса может быть очередь из actions а может и не быть - это уже конкретная реализация, как правило очередь имеется

- микросервис может разрешать остановить/отменить action, если это возможно

- микросервис рапортует source-узлу несколько вариантов состояний action, последнее - completed/failed/canceled/terminated, в свою очередь caller периодически опрашивает это состояние (в v3 был пуш состояний, но мы его дропнули по причине невостребованности)

- то что на unit идет action, видят все, кто реплицирует эту переменную (но не видят, что именно, просто мета-поле act становится > 0). это полезно, например временно заблокировать кнопку в гуях.

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

- через пару (милли)секунд цикл пройдет и все увидят новое значение переменной, которое реально стоит на PLC

Учитывая, что мы требуем от микросервиса только общую совместимость, action может быть что угодно. Например микросервис может уметь сам открывать и закрывать двери, дергая 2 релейки с паузой, узел же будет видеть всю дверь как один unit и про релейки может не знать вообще ничего.
👍7🔥5
Наши сегодняшние реалии
- добрый день, вам посылка. но выберите другое место выдачи, то, куда она шла - переполнено
- а почему я могу опять выбрать то, куда она шла?
- ну понимаете, база в облаке имеет актуальность с задержкой на пару часов, ещё пару часов работал скрипт, который проверял capacity, ещё пару часов шли письма. прошло пол дня, место наверное освободилось, а вообще это все такой magic, эти компьютеры...
😁24👍2
Наши будни

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

- уважаемый синьер DevOps инженер с 10 годами опыта и уклоном в облака, у вас в деплой скрипте везде CRLF...
😁32👍10
Разбираюсь, через какую задницу вплили в браузеры поддержку тачскринов. На примере нажатия.

В современном JS есть два ивента, которые реагируют на нажатие пальцем - onTouchStart и onMouseDown. Причем, если вы нажмете пальцем и проведете его по экрану - сработает только onTouchStart. А вот если вы просто нажмете на экран - сработают, внезапно, оба. Потому что вначале тачскрины сидели на onMouseDown, чтоб быть совместимыми со старыми сайтами. Но потом завезли "родной" onTouchStart, который тоже хочет себя показать.

Это необходимо учитывать, если вы вручную программируете логику double-click (точнее double-touch) - если у вас, как сейчас часто принято, onTouchStart и onMouseDown замаплены на один хендлер - он будет выдавать "дабл-тач" даже при единственном нажатии, поскольку всегда вызовется минимум дважды.

Соответственно, если пишете универсальный хендлер - из логики дабл-кликов/тачей все тач-ивенты вы убираете. К счастью, их можно легко различить.
👍15💩3
Сегодня в ночном эфире разбираем системы мониторинга. Я видел десятки систем мониторинга, в том числе несколько серьезных разрабатывал, но клиенты постоянно хотели какой-то кастомный велосипед.

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

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

Интересны состояния alarm'а, которые вводит стандарт, они описывают примерно всё, что можно вообразить и что может понадобиться хорошей системе мониторинга:

Normal - процесс функционирует в штатном режиме

Unacknowledged - активный сигнал о неисправности, неподтвержденный оператором

Acknowledged - активный сигнал о неисправности, подтвержденный оператором

Returned-to-Normal - процесс опять вошел в штатный режим (например автоматика аварийно сбросила давление и оно опять в норме)

Latched - похож на Returned-to-Normal, но требует подтверждения оператора (например, давление пришлось аварийно сбрасывать второй раз за час и это уже не случайность)

Shelved - временно отключен оператором

Suppressed by design - отключен автоматикой намеренно (например, котел отключен, значит давление не мониторится. не показывайте оператору Normal - какое normal, если оно сейчас вообще не мониторится)

Out of service - alarm перестал функционировать (например вышел из строя датчик давления - система мониторинга уже не знает, какое давление в котле. в свою очередь, отдельный алярм, который мониторит живучесть датчиков, может дать Unacknowledged. хотя и так понятно что надо что-то делать)

Смысл следования стандарту в том, что если мы запрограммируем в нашей системе мониторинга все 8 состояний, мы можем описать этим оператору любую ситуацию, без изобретения собственных велосипедов.
👍17🔥9
И типичные ошибки, которые я постоянно встречаю:

- неиспользование Latched + Returned-to-Normal. Либо заставляют оператора делать acknowledge каждому алярму (этим когда-то сильно грешила VMware VSphere, не знаю как сейчас), либо вообще забивают на acknowledge, если всё ушло в норму

- вместо Out of service делают отдельный алярм на живучесть каждого датчика - зачем?

- не используют suppressed by design - оно либо орет, когда что-то выключили, либо нужно выключать вручную (потом всегда забывают включить). еще часто с любимой кнопкой "выключить на 10-20-30 минут", в которые обязательно случается какая-нибудь херня.
👍13
Первое, что я делаю на Linux, особенно на всяких слабеньких ембедах - сношу mandb. Потому что initrd апдейтится только когда ставите что-то системное, а эта зараза - на каждый чих.

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

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

А вы еще читаете маны? А может даже пишете?
👎25👍15😁7💩2🔥1
Поработав с файловой системой напрямую в наше время, понимаешь, почему народу так быстро зашел формат S3 и прочие бакеты, и дело тут даже не в распределенности. Они банально гораздо ближе к БД, чем к ФС.

Файловые системы делались для пользователей, а не для машин. Для машин они ужасны:

- прежде чем положить файл в /some/folder, нужно этот путь создать
- после того, как файл удалили, нужно руками подчистить пустые каталоги
- большинство ЯП не дают из коробки вменяемые функции получить файлы рекурсивно
- ФС может содержать симлинки. для машины штука жуткая - большинство ЯП не дают из коробки resolve ссылки на реальный объект, только на parent
- в untrusted environments - постоянно проверять, не вставил ли юзер конструкции типа /../, чтобы заинжектить ваш код

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

Но есть и хорошие новости. Рядовой юзер стремительно тупеет и чем дальше, тем меньше пользуется фичами ФС, ему достаточно "мои фото", "мои видео" и "мои документы". Придет время, и полноценные ФС останутся только на всяких специализированных рабочих станциях.
👍15💩4😁3🔥1
Внезапно понял, почему мне так зашли хуки в реакте. Реакт, с его хуками, гораздо ближе к программированию циклов ПЛК, чем к традиционным "линейным" программам.

Надо провести эксперимент и попробовать дать ПЛК-кодеру писать фронт. Ну или наоборот.
👍11👎1
В этом году у нас, в честь Black Friday, цена на QLC SSD от самсы упала до 300 евро за 8Тб.

В soho NAS и в прочих местах, где tbw не критично, жёсткие диски в принципе больше не нужны.

Даже для бекапов.
🔥18👍2
😁36👍4💩1
Как уже говорил, у нас типичный менеджмент задач - чат в телеге и текстовый файлик.

Начинали новый проект, "девелоперы" - говорю: "текстовый файлик - несолидно"
"Несолидно" - соглашаются девелоперы: "21й век на дворе".

Дал полный карт-бланш действий. Выбрали Trello. Красиво, богато, kanban. Набили юзеров, задач, раскрасили в цвета.

Целый месяц продержался Trello. Сначала перестали в цвета задачи красить. Потом новые заводить. Когда вернулись в чат в телеге, я стал что-то подозревать. Но когда завели текстовый файлик - понял, что всё.
😁43👍7🔥5💩3
И типичное code review:
- ты чего такое говно пишешь?
- обижаешь начальник, сейчас все такое говно пишут. обнови форматтер-компайлер-автокомплитер, всё заработает
- ух, нихера себе, уже 10я версия вышла! а я еще на 0.2.2 сидел...
😁27👍5
2025/09/16 15:27:09
Back to Top
HTML Embed Code: