Владимир Плизга @Toparvion
Инженер-программист
Информация
- В рейтинге
- Не участвует
- Откуда
- Новосибирск, Новосибирская обл., Россия
- Зарегистрирован
- Активность
Специализация
Backend Developer
Lead
Java
Docker
Spring Boot
Kubernetes
RabbitMQ
Инженер-программист
Вот ссылка на этот пост: https://t.me/llm_under_hood/230
Спасибо за пояснение и ссылку! Поскольку до прихода в IoT-разработку я никак не сталкивался с этой областью, реализованные здесь решения на IoT показались достаточно интересными и необычными, чтобы включить их в доклад. И да, согласен, эту тему можно хорошо раскрыть серией статей и/или докладов, и было бы здорово, если бы вы всё же приложили к этому руку.
Часть ответов на эти вопросы звучала в исходной (не текстовой) версии доклада, хотя в целом, согласен, многие важные технические подробности были упущены, причём сознательно - в противном случае намеченный материал было бы невозможно уместить в отведенные докладу 30 минут.
Кем поллить - сервером, какое устройство - ошейник в связке с базовой станцией, нафига поллить - чтобы своевременно получать с него данные на сервере.
Прочтите, пожалуйста, внимательно - не "сажать на батарейку", а "сажать батарейку". Понятно, что ошейник питается от батареи. Цель подписывания на события от устройства вместо его регулярного опроса состоит, в том числе, в экономии заряда питающего элемента.
Полагаю, здесь смутило сочетание слов "стационарные объекты" и "сообщают географическое положение". Согласен, без пояснения формулировка дурацкая. Имеются в виду суда, вставшие в порт на обслуживание/ремонт/разгрузку/... и остающиеся неподвижными 95+% времени пребывания в порту. Несмотря на это, они включаются в число отслеживаемых объектов.
С одной стороны, можно с уверенностью, что библиотеки совершенно точно будут (и уже давно начали) поддерживать реактивный подход: тот же Spring в каком-то смысле задал этот тренд, адаптировав свои фреймворки WebMVC (в виде WebFlux), Security и частично Integration; другие тоже на подхвате, например, feign-reactive и различные поставщики драйверов к БД. С другой стороны, их усилия, как правило, не нацелены именно на "скрещивание" сервлетного (а в более общем случае - императивного) подхода с реактивным; вместо этого они предлагаю самостоятельную реактивную альтернативу своим же собственным разработкам. Поэтому именно ждать N условных лет не стоит.
Однако это не значит, что ответ на вопрос:
звучит как однозначное "да", потому что этот ответ сильно зависит от того, можете ли вы позволить себе не ввязываться и не побеждать, т.е. насколько сильно ваш проект/продукт связан с сервлетным стеком. В моём случе это проникновение было очень сильным, поэтому и пришлось идти таким тернистым путём. Этот путь был пройден совсем недавно, я вижу и верю в его позитивные результаты, но объявлять их окончательными пока не тороплюсь, нужно пожить с этим подольше (это ответ на вопрос "выиграл ли ваш проект?").
Что касается более общего случая, то ваш подход с выделением микросервисов на различных стеках кажется вполне удачным; мне известен ещё один такой пример продукта, и он весьма успешен. Конечно, за такой подход приходится платить двойственностью решений одних и тех же задач (то же логирование, например). Это большой минус. Но если в команде есть понимание и объективные оценки профита, то этот минус может быть полностью оправдан.
Согласен с тем, что вваливаться в переход на реактивный драйвер к БД чаще всего необязательно, но для полноты картины замечу, что это может быть оправданно, если узким горлышком приложения оказыватся не БД (с её ограниченными, но большими ресурсами), а Java-часть с её потенциально огромным числом далеко не бесплатных потоков. Добавление блокирующего пула в таком случае только усугубит ситуацию, поэтому имеет смысл посмотреть в сторону реактивного подхода, хоть это и весьма тернистый путь. Надеюсь, никто из нас в такой ситуации не окажется.
Дело как раз в том, что далеко не всегда задача сводится к тестированию одного бина; нередко возникает потребность модификации сквозных поведений или функционала, не обёрнутого в бины. Больше того, применение Side Effect Injection отнюдь не сводится к одному лишь тестированию. Слово "тестовый" в названии доклада означает, в первую очередь, принадлежность к тестовому (не production) окружению. Например, когда нужно временно поменять что-то в библиотечном коде или на определенном этапе отключить проверки безопасности.
Если бы речь была только о тестах, то, безусловно, да, так и нужно было бы сделать. Но как я говорил в докладе и повторился чуть выше здесь, это далеко не всегда так.
Да, полностью, и да, можно (хоть и не обязательно) выделять в отдельный артефакт, так как SEI — это не разновидность тестов, а альтернативный подход к troubleshooting'у и воспроизведению сложных тестовых кейсов. Его можно использовать как в составе интеграционных тестов, так и самостоятельно.
AlexeyOs, привет!
1) Иногда кажется)) Но от идеи не отказываемся, потому что:
src/test/java
не пойдёт, потому что модифицированное поведение нам нужно не в тестах, а в обычном режиме работы приложения. Класть к основным исходникам, конечно, можно, но это возвращает нас к обычному подходу "If'ы+настройки", а значит, эти тестовые поделки снова уедут на production и защита от их случайного срабатывания снова ляжет на совесть людей, а не на формальный механизм выкашивания лишнего. Впрочем, буду честен, пару раз, в особонакуренныхнетривиальных случаях мы сами так делали, но только подключение тестового бина обеспечивали не настройкой, а дроплетом, т.е. в отсутствие модицификации тестовый бин вообще никак не попадал в IoC-контейнер и даже не загружался как класс в JVM. Это пример комбинации подходов, о которой я говорил в конце доклада. Другой пример см. на этих слайдах другой версии доклада.2) Для AspectJ и Byteman специальных тестов по этой части не делал, разве что чисто визуально кажется, что AspectJ стартует чуть медленнее. Что касается jMint, то у нас в тестовом окружении большинство приложений по умолчанию стартуют одновременно и с отладчиком (в режиме
suspend=n
, разумеется), и с Java-агентом jMint, но на времени старта это не сказывается. С точки зрения подкапотной механики, отладчик не привносит здесь ничего нового, поэтому и не вызывает задержек. Единственная особенность — в порядке подключения агентов (ведь отладчик — тоже агент, только "нативный"). Если в команде запуска JVM указать агентов не в том порядке, то отладчик не сможет ходить по исполняемому коду jMint (впрочем, вряд ли этого кого-то волнует).Согласен, всерьез полагаться на "закрытость" формата архива не стоит. Равно как и не стоит (по крайней мере, пока) ожидать от него встроенных средств защиты от модификаций. Поэтому, повторюсь, я считаю, что защищать архив нужно средствами другого уровня, и в фиксированной адресации внутри него действительно нет ничего плохого.
Что касается приведенной ссылки, то мы увидели одно и то же: "динамическая" адресация оставляет заметный негативный отпечаток на производительности CDS в целом, поэтому JVM будет избегать ее по возможности. Сравнение с вариантом без CDS здесь нерелевантно, так как этот вариант сейчас вне нашего фокуса.
Спасибо, что обратили внимание на вопрос безопасности; как обычно, он важен, но не очевиден.
Возможно, какое-то упрощение это привнесет, да. Однако, во-первых, известность базового адреса не особо проливает свет на структуру и формат остальной разделяемой области, ведь спецификация на JSA-файлы остается закрытой, что делает подмену классов в них не такой уж тривиальной. Во-вторых, даже если структура файла будет выведена эмпирически (типа реверс-инижинирингом), сам доступ нему, тем более на запись, должен остаться серьезным препятствием, потому что этот файл наверняка хранится примерно также, как исполняемые файлы приложения (JAR-архивы, например).
Другими словами, защита разделяемого архива от зловредных модификаций, на мой взгляд, должна производиться средствами другого уровня, нежели манипуляцией адресами после считывания архива. Тем более, что релокация указателей может обходиться довольно дорого, см. замеры в JDK-8231610.
Не разбор багов, конечно, но всё же кое-что накопал про JEP-350 Dynamic CDS Archives применительно к Spring Boot: https://m.habr.com/ru/post/472638/
Вот уж правда обширная тема! Особенно про LDAP — хоть в музей относи)
У меня был схожий опыт с JPA, только нужно было отвязать прикладной код от походов в БД статическими методами Play 1.x, чтобы покрыть код unit-тестами без PowerMockito. Впрочем, тогда машстаб вышел более широким — таки пришлось задеть пару сотен классов. К счастью, правки оказались простыми.
Зависит от проекта. В нашем случае он состоит только из Java-подпроектов, лишь один из которых не является Spring Boot приложением. А всё, что не на Java, мы держим в других репозиториях.
А что конкретно не дает переехать? Интересно узнавать о новых граблях от коллег по цеху.
Насчёт транзакций сам с таким не сталкивался, но уже не в первый раз слышу о подобных проблемах. Я бы в первую очередь выяснил, заходит ли выполнение в метод
rollbackOn
, чтобы разбить область поиска на два взаимоисключающих участка:CustomAttributeSource
: точно ли его видят регистрирующие бины (в том числе самописные), и точно ли эти бины сами активны (намекаю на соответствующие классы*AutoConfiguration
).instanceof
не само исключение, а его корень, например, через Throwables#getRootCause() из Guava.Та работа, о которой сказано в заключении, как раз и имеет целью создание некой утилитки, которая сможет принять на вход любой лог, а на выходе выдать готовый NSS-файл для предоставления Wireshark'у. Только это будет не скрипт, а именно программка (исполняемый JAR), так как, во-первых, мне по профессии ближе Java, во-вторых, я хочу научить ее учитывать возможные отклонения в форматах логов (от версии JVM к версии), а также разные режимы логирования (значения опции javax.net.debug). Все это позволит сделать ее пригодной не только нам с Вами, но и, надеюсь, многим другим. Планирую закончить работу над ней в течение ближайших 1-2 недель.