- Добро пожаловать в ад. За твои грехи ты будешь вечно кодить на жяваскрипте под django
- Она же на питоне?...
- Мы портировали
- Она же на питоне?...
- Мы портировали
Когда говоришь, что пишешь всё в VIM, тут же первый вопрос - а как там с отладкой? А ответ в том, что я традиционной отладкой типа step-next не пользовался уже лет 25, наверное со времен MS-DOS.
Возможно начинающим кодерам такая отладка будет полезна, просто посмотреть визуально, а куда же ходит программа. Но если вы умеете читать код, то отладка нужна только для наблюдения за переменными и поиска ошибок.
Современное ПО - это обычно монстр с кучей потоков или асинхронных воркеров. И значение переменной в определенный момент времени, если другие потоки уже убежали вперед, мне обычно не скажет совершенно ничего. Более того - останавливать поток чтобы "посмотреть что там внутри" часто вредно или даже критично. Если нужно постоянно наблюдать за переменными - они пишутся в трейс-логи. А если существует вероятность, что софт поведет себя как-то не так на продакшне и непонятно почему - вы в продакшн этот ваш IDEA всё равно не потащите и вам всё равно придётся писать специальные инжекторы и анализаторы.
Второй пункт - поиск ошибок. Тут всё просто, как 5 копеек - с изобретением человекочитаемых экзепшнов и стек-трейсов в них, классический дебаггер стал ненужен. Экзепшны есть везде - и в Java/JS, и в Python, и даже успешно перекочевали в некотором виде в Rust.
Остаются некоторые специфические случаи, когда мы создаём совершенно новый алгоритм и еще не знаем, как он поведет себя на практике. Правило хорошего тона - обкатывать такие алгоритмы отдельно, а не совать сразу в большой проект. И тут уже никто не мешает обвешать их со всех сторон принтами, сколько вам будет угодно.
Возможно начинающим кодерам такая отладка будет полезна, просто посмотреть визуально, а куда же ходит программа. Но если вы умеете читать код, то отладка нужна только для наблюдения за переменными и поиска ошибок.
Современное ПО - это обычно монстр с кучей потоков или асинхронных воркеров. И значение переменной в определенный момент времени, если другие потоки уже убежали вперед, мне обычно не скажет совершенно ничего. Более того - останавливать поток чтобы "посмотреть что там внутри" часто вредно или даже критично. Если нужно постоянно наблюдать за переменными - они пишутся в трейс-логи. А если существует вероятность, что софт поведет себя как-то не так на продакшне и непонятно почему - вы в продакшн этот ваш IDEA всё равно не потащите и вам всё равно придётся писать специальные инжекторы и анализаторы.
Второй пункт - поиск ошибок. Тут всё просто, как 5 копеек - с изобретением человекочитаемых экзепшнов и стек-трейсов в них, классический дебаггер стал ненужен. Экзепшны есть везде - и в Java/JS, и в Python, и даже успешно перекочевали в некотором виде в Rust.
Остаются некоторые специфические случаи, когда мы создаём совершенно новый алгоритм и еще не знаем, как он поведет себя на практике. Правило хорошего тона - обкатывать такие алгоритмы отдельно, а не совать сразу в большой проект. И тут уже никто не мешает обвешать их со всех сторон принтами, сколько вам будет угодно.
Я обожаю, когда миллениалы выдумывают эти "быстрые" протоколы over UDP, добавляя ACK от получателя, для надежности. Поздравляю, вы опять изобрели TCP.
Позвольте, а как же тогда такой мастодонт как TFTP? Ведь там же как раз UDP и acknowledge от получателя?
А ответ прост- TFTP был разработан в 1981 году. В то время сетевой стек был у каждого свой, а UDP был дешев в имплементации и чаще встречался. И изначально TFTP придумывался не как протокол загрузки (BOOTP появился только спустя 4 года), а именно как протокол передачи файлов. Между машинами, которые уже имплементировали UDP, но еще не успели TCP.
Так когда же использовать UDP? А есть всего три варианта:
- когда вам плевать, получил адресат пакет или нет. Если это компьютерная игра, голосовой или видео звонок, стрим киношки (и в некоторых случаях передача телеметрии устройств) - от потери одного фрейма из тысяч, которые идут непрерывным потоком, юзер ничего не заметит.
- когда у вас уютная локалочка, в которой пакеты никогда не теряются, а вы любите скорость.
- когда устанавливать TCP-соединение дорого - данные планируется передать 1-2 пакетами, с acknowledge получения каждого (привет SNMP).
Во всех остальных случаях - берите TCP и не выёбуйтесь.
Позвольте, а как же тогда такой мастодонт как TFTP? Ведь там же как раз UDP и acknowledge от получателя?
А ответ прост- TFTP был разработан в 1981 году. В то время сетевой стек был у каждого свой, а UDP был дешев в имплементации и чаще встречался. И изначально TFTP придумывался не как протокол загрузки (BOOTP появился только спустя 4 года), а именно как протокол передачи файлов. Между машинами, которые уже имплементировали UDP, но еще не успели TCP.
Так когда же использовать UDP? А есть всего три варианта:
- когда вам плевать, получил адресат пакет или нет. Если это компьютерная игра, голосовой или видео звонок, стрим киношки (и в некоторых случаях передача телеметрии устройств) - от потери одного фрейма из тысяч, которые идут непрерывным потоком, юзер ничего не заметит.
- когда у вас уютная локалочка, в которой пакеты никогда не теряются, а вы любите скорость.
- когда устанавливать TCP-соединение дорого - данные планируется передать 1-2 пакетами, с acknowledge получения каждого (привет SNMP).
Во всех остальных случаях - берите TCP и не выёбуйтесь.
Да, еще частный случай, когда мобильный клиент постоянно роумится и постоянно меняет IP. Но это уже не мой огород.
Программить блокируемые (да и неблокируемые тоже) сокеты на питоне - еще тот адок. На дворе конец 2021 года, а вам предлагаются из коробки сугубо биндинги на recv().
Кто далек от темы - recv(N) позволяет прочитать из сокета N байт, но совершенно не факт, что она прочитает именно N байт - а вдруг там сейчас столько нету? Поэтому правило дедовское - читаем не всё сразу, а recv(BUF_SIZE), причем последнюю часть естественно уменьшаем BUF_SIZE на сколько-там недочитано, а то влезем уже в следующий пакет.
В других языках естественно эти велосипеды давно изобрели, в виде всяких там этих ваших read_exact() и прочих recvall(), которые внутри у себя гоняют буферы, а вам выдают ровно столько, сколько вы запросили.
Но в питоне этого нету, а пара попыток имплементировать recvall() в коробку почему-то закончились провалом.
Зато мля в коробке есть встроенный JSON. Который, естественно, все тут же меняют на какой-нибудь rapidjson, потому что коробочным пользоваться под нагрузками нереально.
Кто далек от темы - recv(N) позволяет прочитать из сокета N байт, но совершенно не факт, что она прочитает именно N байт - а вдруг там сейчас столько нету? Поэтому правило дедовское - читаем не всё сразу, а recv(BUF_SIZE), причем последнюю часть естественно уменьшаем BUF_SIZE на сколько-там недочитано, а то влезем уже в следующий пакет.
В других языках естественно эти велосипеды давно изобрели, в виде всяких там этих ваших read_exact() и прочих recvall(), которые внутри у себя гоняют буферы, а вам выдают ровно столько, сколько вы запросили.
Но в питоне этого нету, а пара попыток имплементировать recvall() в коробку почему-то закончились провалом.
Зато мля в коробке есть встроенный JSON. Который, естественно, все тут же меняют на какой-нибудь rapidjson, потому что коробочным пользоваться под нагрузками нереально.
Я: мне нужен раст-крейт, который авторизирует юзера по паролю через htpasswd
Авторы крейтов: вон держи десяток
Крейты: дайте нам &str, а мы его разобьем на Map<&str, &str> и будем так хранить
Я: А как же мне один раз загрузить из файла данные и юзать потом готовый map из любого потока?
Крейты: Никак. У вас же lifetime данных тю-тю
Я: А других крейтов нету?
Авторы крейтов: нет, мы хотим чтобы все заебались!
Авторы крейтов: вон держи десяток
Крейты: дайте нам &str, а мы его разобьем на Map<&str, &str> и будем так хранить
Я: А как же мне один раз загрузить из файла данные и юзать потом готовый map из любого потока?
Крейты: Никак. У вас же lifetime данных тю-тю
Я: А других крейтов нету?
Авторы крейтов: нет, мы хотим чтобы все заебались!
Европейские ковид-пасы и их безопасность.
В Европе единую базу привитых от COVID19 сделать нельзя - потому что GDPR. Поэтому у каждой страны база своя. И как же ездить туда-сюда?
Долго не думали - взяли старую добрую x509. Итак, есть некая CA в Брюсселе, которая раздала subCA минздраву каждой страны и некоторым партнерам, кто захотел участвовать в едином формате. Они, в свою очередь, раздали конечные сертификаты айболитам и прочим прививающим организациям. А те уже клепают ковид-пасы для граждан.
На моменте клепания для граждан стройная х509 заканчивается. Сертификат привитого - это самодельный CBOR, подписанный приватным ключем лекаря и способный валидироваться через CA/subCA. Почему пошли на такой шаг - ну тут понятно, во-первых чтобы врачи не клепали свои subCA, во-вторых - потому что влом было в x509-поля писать через сплиты дозы и прочие файзеры.
В общем и целом, проблема есть - поскольку ковид-пас это уже не х509, CRL для конечных ковид-пасов отсутствует. И отозвать код привитого гражданина просто нельзя.
Только отзывая сертификат врача, который его подписал. Если врач - жулик, который только и делал что продавал пасы, то тут проблемы нету. Но врачи обычно своей репутацией дорожат и не будут таким заниматься. Поэтому в основном для продажи пасов "налево" используют пизженные ключи больниц, которые прививают сотнями тысяч, и если отозвать ключ такой больницы - начнется паника и пиздец. Хотя, был случай - Германия один раз всунула в CRL айболита со 100к привитыми, но это случай из ряда вон выходящий.
Точнее, случай не совсем выходящий. Самый цимес - когда хакеры пиздят приватный ключ минздрава и таким образом могут сами генерить себе айболитов. А пока минздрав сует в CRL одного - они генерят еще 10.
Мораль сей басни такова. x509, стройно работающая в айтишном мире, где ключи крупных CA охраняются как зеница ока, а корневые вообще достаются из сейфа раз в год, совершенно не работает с гражданами, близкими к стетоскопу, но далекими от способности отличить AES от RSA и относящимися к приватному ключу, как к фотке кота из инстаграма.
Ну и добро пожаловать в кибер-панк, начало.
В Европе единую базу привитых от COVID19 сделать нельзя - потому что GDPR. Поэтому у каждой страны база своя. И как же ездить туда-сюда?
Долго не думали - взяли старую добрую x509. Итак, есть некая CA в Брюсселе, которая раздала subCA минздраву каждой страны и некоторым партнерам, кто захотел участвовать в едином формате. Они, в свою очередь, раздали конечные сертификаты айболитам и прочим прививающим организациям. А те уже клепают ковид-пасы для граждан.
На моменте клепания для граждан стройная х509 заканчивается. Сертификат привитого - это самодельный CBOR, подписанный приватным ключем лекаря и способный валидироваться через CA/subCA. Почему пошли на такой шаг - ну тут понятно, во-первых чтобы врачи не клепали свои subCA, во-вторых - потому что влом было в x509-поля писать через сплиты дозы и прочие файзеры.
В общем и целом, проблема есть - поскольку ковид-пас это уже не х509, CRL для конечных ковид-пасов отсутствует. И отозвать код привитого гражданина просто нельзя.
Только отзывая сертификат врача, который его подписал. Если врач - жулик, который только и делал что продавал пасы, то тут проблемы нету. Но врачи обычно своей репутацией дорожат и не будут таким заниматься. Поэтому в основном для продажи пасов "налево" используют пизженные ключи больниц, которые прививают сотнями тысяч, и если отозвать ключ такой больницы - начнется паника и пиздец. Хотя, был случай - Германия один раз всунула в CRL айболита со 100к привитыми, но это случай из ряда вон выходящий.
Точнее, случай не совсем выходящий. Самый цимес - когда хакеры пиздят приватный ключ минздрава и таким образом могут сами генерить себе айболитов. А пока минздрав сует в CRL одного - они генерят еще 10.
Мораль сей басни такова. x509, стройно работающая в айтишном мире, где ключи крупных CA охраняются как зеница ока, а корневые вообще достаются из сейфа раз в год, совершенно не работает с гражданами, близкими к стетоскопу, но далекими от способности отличить AES от RSA и относящимися к приватному ключу, как к фотке кота из инстаграма.
Ну и добро пожаловать в кибер-панк, начало.
Вдогонку к предыдущему посту. Меня тут спрашивают - а как же отозвали ковид-пасы Адольфа Гитлера и Микки Мауса?
В каждой стране ЕС есть API, которое дергает местная читалка - эдакое очень кривое, самопальное подобие CRL. Поскольку централизированного стандарта API нету (в Чехии например этот "CRL" - JSON, где все поля на чешском) - ковидпас могут отозвать в одной стране, но при этом он вполне прекрасно работает в другой - там ведь читалка-приложение совершенно своя.
В общем, вот такой бардак. Чешская читалка кстати хорошая - расшифровывает все поля полностью, включая служебные. Ну у нас тут про GDRP слышали, но не видели. А нидерландская, например - показывает только первые буквы имени-фамилии и дату рождения.
В каждой стране ЕС есть API, которое дергает местная читалка - эдакое очень кривое, самопальное подобие CRL. Поскольку централизированного стандарта API нету (в Чехии например этот "CRL" - JSON, где все поля на чешском) - ковидпас могут отозвать в одной стране, но при этом он вполне прекрасно работает в другой - там ведь читалка-приложение совершенно своя.
В общем, вот такой бардак. Чешская читалка кстати хорошая - расшифровывает все поля полностью, включая служебные. Ну у нас тут про GDRP слышали, но не видели. А нидерландская, например - показывает только первые буквы имени-фамилии и дату рождения.
А ну, и чтобы совсем смешно было - у Хорватии, например, национальный CRL есть, но не работает. А у Италии его вообще нет.
Дополненная реальность на службе электриков и прочих сантехников.
Есть у меня дорогая термокамера от Seek, но ей как ни странно довольно сложно пользоваться - в 320х240, да еще и в IR, любой знакомый электрощиток выглядит загадочным.
Но счастье есть - в телефоны стали ставить "дешевые" (150-200$) термокамеры с разрешением до 100х50 точек, при этом AR-софт снимает всё основной, а с термической добавляет только инфу по температуре. Логика есть - если провод нагрет, то достаточно снять с него пару точек, да и соседние тоже будут нагреты плюс-минус автобус.
Не смотря на меньшую точность - такой камерой намного приятнее работать. При таком подходе, при желании даже видно текст на документах.
Есть у меня дорогая термокамера от Seek, но ей как ни странно довольно сложно пользоваться - в 320х240, да еще и в IR, любой знакомый электрощиток выглядит загадочным.
Но счастье есть - в телефоны стали ставить "дешевые" (150-200$) термокамеры с разрешением до 100х50 точек, при этом AR-софт снимает всё основной, а с термической добавляет только инфу по температуре. Логика есть - если провод нагрет, то достаточно снять с него пару точек, да и соседние тоже будут нагреты плюс-минус автобус.
Не смотря на меньшую точность - такой камерой намного приятнее работать. При таком подходе, при желании даже видно текст на документах.
Как уже говорил, я много лет занимаюсь, люблю и иногда воюю с MQTT. И было бы странно, если бы мы не сделали свой Pub/Sub сервер, но поскольку задачи у нас иногда очень специфические, а в MQTT много лишнего, и наоборот, того что нужно - нету - то и протокол. О pub/sub сервере и протоколе будет чуть позже, а пока небольшое HOWTO зарегистрировать свой настоящий протокол и порт в IANA.
Поскольку у нас клиенты в основном кровавый ынтырпрайз, решили идти официальным путем. Для регистрации протокола вам не нужен RFC draft, хотя это и плюс.
Процесс регистрации следующий:
- Вы выбираете пустой порт и заполняете форму на сайте IANA. Если вам всё равно какой порт дадут, или порт не нужен - номер не даёте
- Описываете протокол в анкете, чем подробнее - тем лучше. Идеально иметь ссылки на спецификации и примеры использования.
- IANA не занимается рассмотрением протоколов, они только присваивают вам номер. Рассмотрение протоколов идет в IESG (Internet Engineering Steering Group, совет экспертов при ICANN)
Что будет требовать IESG:
- практически нереально получить аппрув протокола без TLS или другого шифрования
- нереально получить аппрув без versioning. в приветствии клиент/сервер обязательно должны устаканивать рабочую версию. плодить порты под разные версии протоколов - неприлично
- четкое описание, почему вы решили сделать свой протокол, чем он лучше других, идеально - рабочую версию (клиент/сервер). причем это реально очень подробно читают и смотрят
- если вы запросили fixed port(s) - IESG очень сильно будет вас допрашивать, почему они вам нужны. тут я ступил/не знал - нужно было сделать простенький discovery, пришлось импровизировать и уговаривать.
- допрос IESG в целом очень подробный, и защита может занять несколько недель.
Но у меня получилось. Теперь 2873 TCP/UDP официально за PSRT (PubSub Realtime Telemetry Protocol). Во всех справочниках и на всех системах.
С чем нашу лавку и поздравляю.
Поскольку у нас клиенты в основном кровавый ынтырпрайз, решили идти официальным путем. Для регистрации протокола вам не нужен RFC draft, хотя это и плюс.
Процесс регистрации следующий:
- Вы выбираете пустой порт и заполняете форму на сайте IANA. Если вам всё равно какой порт дадут, или порт не нужен - номер не даёте
- Описываете протокол в анкете, чем подробнее - тем лучше. Идеально иметь ссылки на спецификации и примеры использования.
- IANA не занимается рассмотрением протоколов, они только присваивают вам номер. Рассмотрение протоколов идет в IESG (Internet Engineering Steering Group, совет экспертов при ICANN)
Что будет требовать IESG:
- практически нереально получить аппрув протокола без TLS или другого шифрования
- нереально получить аппрув без versioning. в приветствии клиент/сервер обязательно должны устаканивать рабочую версию. плодить порты под разные версии протоколов - неприлично
- четкое описание, почему вы решили сделать свой протокол, чем он лучше других, идеально - рабочую версию (клиент/сервер). причем это реально очень подробно читают и смотрят
- если вы запросили fixed port(s) - IESG очень сильно будет вас допрашивать, почему они вам нужны. тут я ступил/не знал - нужно было сделать простенький discovery, пришлось импровизировать и уговаривать.
- допрос IESG в целом очень подробный, и защита может занять несколько недель.
Но у меня получилось. Теперь 2873 TCP/UDP официально за PSRT (PubSub Realtime Telemetry Protocol). Во всех справочниках и на всех системах.
С чем нашу лавку и поздравляю.
И первый публичный анонс нашего pub/sub-сервера. Сервер - PubSubRT, протокол - PSRT (IESG approved, port 2873)
В чем особенности сервера:
1) Минимально простая конфигурация. На производительность влияет только один параметр - data queue. Чем он меньше - тем меньше latency, но клиент может дольше ждать перед отправкой сообщения
2) Работает максимально быстро, даже с большими пейлоадами. И да, latency на хорошей сети редко поднимается выше 0,5 ms (для мелких пейлоадов - в пределах 30-40 микросекунд)
3) Это не "черный ящик". максимальный мониторинг всего, что происходит внутри
4) Жесткое слежение за latency, warnings в логи, как только превышается допустимый параметр
5) Никаких "таблиц подписки" - только b-trees. Клиенты могут задать миллионы подписок на разные топики, но если сообщения не ходят сразу в миллион клиентов бродкастом - сервер этого не замечает.
Latency между паблишером и конкретным подписчиком мы считаем, как время с момента получения от паблишера первого байта OP_PUBLISH и до ухода последнего байта в дата-сокет подписчика
В чем особенности протокола. Основная особенность одна - мы использовали два сокета (на один порт) и отказались от карусели OP-ACK. Аргумент против один: это усложняет написание надежного клиента, впрочем клиенты на Rust и Python уже вполне надежные. Теперь аргументы в пользу:
- В Pub/Sub пуши от сервера приходят только когда вы получаете сообщение. поэтому пусть себе и ходят по выделенному сокету данных
- По сокету управления все операции - атомарные. Карусель OP-ACK на клиенте тоже не нужна, что намного облегчает логику
- Благодаря двум сокетам, сервер может посылать ACK на операции контроля прямо в то время, пока клиент по второму сокету скачивает большой пейлоад
- Внезапно, но есть куча клиентов, которые просто отправляют данные и ни на что не подписываются. В PSRT данные на сервер можно пушить хоть UDP-фреймами, с ACK или без
- Нет retains. На высоконагруженных Pub/Sub от них всё равно рано или поздно отказываются, потому что это обычно операции с диском
- Очень жесткий контроль таймаутов. Дохлый клиент будет с сервера немедленно выброшен. Дохлый сервер будет немедленно переподключен клиентом
- Максимально простой запуск TLS
- Репликация и HA из коробки. В сервере мы ее пока не открывали, но в будущем думаю да. Протокол репликации открыт
- Логическая совместимость с MQTT - те же топики, те же маски
Все это уже работает в продакшне у клиентов. Реальное ускорение с пейлдоадами >10kb на медленных каналах (нестабильный 1Mbit) - в 5-10 раз быстрее, чем MQTT. Наша EVA ICS уже получила поддержку PSRT в дополнение к MQTT, релиз выйдет примерно через месяц.
https://github.com/alttch/psrt
В чем особенности сервера:
1) Минимально простая конфигурация. На производительность влияет только один параметр - data queue. Чем он меньше - тем меньше latency, но клиент может дольше ждать перед отправкой сообщения
2) Работает максимально быстро, даже с большими пейлоадами. И да, latency на хорошей сети редко поднимается выше 0,5 ms (для мелких пейлоадов - в пределах 30-40 микросекунд)
3) Это не "черный ящик". максимальный мониторинг всего, что происходит внутри
4) Жесткое слежение за latency, warnings в логи, как только превышается допустимый параметр
5) Никаких "таблиц подписки" - только b-trees. Клиенты могут задать миллионы подписок на разные топики, но если сообщения не ходят сразу в миллион клиентов бродкастом - сервер этого не замечает.
Latency между паблишером и конкретным подписчиком мы считаем, как время с момента получения от паблишера первого байта OP_PUBLISH и до ухода последнего байта в дата-сокет подписчика
В чем особенности протокола. Основная особенность одна - мы использовали два сокета (на один порт) и отказались от карусели OP-ACK. Аргумент против один: это усложняет написание надежного клиента, впрочем клиенты на Rust и Python уже вполне надежные. Теперь аргументы в пользу:
- В Pub/Sub пуши от сервера приходят только когда вы получаете сообщение. поэтому пусть себе и ходят по выделенному сокету данных
- По сокету управления все операции - атомарные. Карусель OP-ACK на клиенте тоже не нужна, что намного облегчает логику
- Благодаря двум сокетам, сервер может посылать ACK на операции контроля прямо в то время, пока клиент по второму сокету скачивает большой пейлоад
- Внезапно, но есть куча клиентов, которые просто отправляют данные и ни на что не подписываются. В PSRT данные на сервер можно пушить хоть UDP-фреймами, с ACK или без
- Нет retains. На высоконагруженных Pub/Sub от них всё равно рано или поздно отказываются, потому что это обычно операции с диском
- Очень жесткий контроль таймаутов. Дохлый клиент будет с сервера немедленно выброшен. Дохлый сервер будет немедленно переподключен клиентом
- Максимально простой запуск TLS
- Репликация и HA из коробки. В сервере мы ее пока не открывали, но в будущем думаю да. Протокол репликации открыт
- Логическая совместимость с MQTT - те же топики, те же маски
Все это уже работает в продакшне у клиентов. Реальное ускорение с пейлдоадами >10kb на медленных каналах (нестабильный 1Mbit) - в 5-10 раз быстрее, чем MQTT. Наша EVA ICS уже получила поддержку PSRT в дополнение к MQTT, релиз выйдет примерно через месяц.
https://github.com/alttch/psrt
История рождения PSRT.
Один наш крупный клиент поставил несколько точек в местах весьма отдаленных, где интернеты по 300 килобит, с пингом в пол-секунды и дропом в 30-40%. Огромные пейлоады телеметрии, собираемые с PLC, достигали 1-2 мегабайта (это в msgpack) и естественно ничего быстро не передавалось. Было принято логичное решение - врубить клиенту компрессию и пусть радуется. Телеметрия вообще обычно хорошо компрессируется, ибо в основном состоит из одинаковых названий полей, групп и похожих ID датчиков/тэгов/регистров/устройств, а самих данных не так уж и много. Тот же MessagePack или CBOR легко сжимается еще в 20-30 раз gzip-ом на normal compression.
Тем не менее, компрессия не помогала, было решено плюнуть в ту сторону и копать в другую - оптимизировать Pub/Sub протокол и сервер. Так родился PSRT, потом его сертифицировали в ICANN и получили порт в IANA, потом был релизнут PubSubRT server и клиент получил скорость в 3-4 раза выше, чем имел с MQTT. Но счастлив всё равно не был и пришел к нам с просьбой "оптимизируйте еще что-то".
Мы начали копать в сторону совсем странных решений и протоколов 40-летней давности, которые привыкли работать на нестабильных каналах, чтобы передавать через них основную часть данных, а по PubSub уже доливать какой-то минимум. Наконец получив доступ по ssh в приватное облако на продакшн (это огромная корпорация, где доступ апрувят неделю), я обратил внимание, что данные собственно передаются в разы быстрее, чем по MQTT, и даже быстрее чем по PSRT, что невозможно, сокет - он везде сокет.
Тогда я решил внимательно посмотреть на компрессию. Посмотрел и всё понял - конечно же она не работала... И не работала по простой причине - телеметрия у нас перед отправкой шифруется AES256. И в функции отправки почему-то стояло compress(encrypt(payload)). Что в принципе бесполезно, ибо шифрованные данные компрессии не поддаются.
Вот так случайная ошибка в порядке вызова encrypt-compress родила новый Pub/Sub протокол. Там, наверху, умеют пошутить.
Один наш крупный клиент поставил несколько точек в местах весьма отдаленных, где интернеты по 300 килобит, с пингом в пол-секунды и дропом в 30-40%. Огромные пейлоады телеметрии, собираемые с PLC, достигали 1-2 мегабайта (это в msgpack) и естественно ничего быстро не передавалось. Было принято логичное решение - врубить клиенту компрессию и пусть радуется. Телеметрия вообще обычно хорошо компрессируется, ибо в основном состоит из одинаковых названий полей, групп и похожих ID датчиков/тэгов/регистров/устройств, а самих данных не так уж и много. Тот же MessagePack или CBOR легко сжимается еще в 20-30 раз gzip-ом на normal compression.
Тем не менее, компрессия не помогала, было решено плюнуть в ту сторону и копать в другую - оптимизировать Pub/Sub протокол и сервер. Так родился PSRT, потом его сертифицировали в ICANN и получили порт в IANA, потом был релизнут PubSubRT server и клиент получил скорость в 3-4 раза выше, чем имел с MQTT. Но счастлив всё равно не был и пришел к нам с просьбой "оптимизируйте еще что-то".
Мы начали копать в сторону совсем странных решений и протоколов 40-летней давности, которые привыкли работать на нестабильных каналах, чтобы передавать через них основную часть данных, а по PubSub уже доливать какой-то минимум. Наконец получив доступ по ssh в приватное облако на продакшн (это огромная корпорация, где доступ апрувят неделю), я обратил внимание, что данные собственно передаются в разы быстрее, чем по MQTT, и даже быстрее чем по PSRT, что невозможно, сокет - он везде сокет.
Тогда я решил внимательно посмотреть на компрессию. Посмотрел и всё понял - конечно же она не работала... И не работала по простой причине - телеметрия у нас перед отправкой шифруется AES256. И в функции отправки почему-то стояло compress(encrypt(payload)). Что в принципе бесполезно, ибо шифрованные данные компрессии не поддаются.
Вот так случайная ошибка в порядке вызова encrypt-compress родила новый Pub/Sub протокол. Там, наверху, умеют пошутить.
Если вы думаете что пинг пол-секунды и 300 килобит - это в наше время редкость и ужас-ужас, то спешу обрадавать - это еще хорошо.
Сегодня имел честь иметь ssh-сессию далеко за полярный круг, где-то там, где уже из Канады в Гренланию пешком вброд ходят.
Пинг - секунда. Скорости - мой модем на 33600 лучше работал. Завершает картину внутресетевой полуглобальный корпоративный RIP, который от такого сходит с ума и держит системы под перманентным ддосом.
Сегодня имел честь иметь ssh-сессию далеко за полярный круг, где-то там, где уже из Канады в Гренланию пешком вброд ходят.
Пинг - секунда. Скорости - мой модем на 33600 лучше работал. Завершает картину внутресетевой полуглобальный корпоративный RIP, который от такого сходит с ума и держит системы под перманентным ддосом.