Написание резюме выступлений на конференциях – лучший способ сосредоточиться на выступлении и активно слушать. До того, как выступления на конференциях стали частью моей работы, я делал это. Однако сейчас я не так часто посещаю конференции, а когда посещаю, то не делаю записей.
jPrime – это конференция в Болгарии, и после двух отмен из-за Ковида, они провели свою конференцию на этой неделе. Вероятно, по этой причине атмосфера вполне подражательная: Я посетил пару докладов; вот мои заметки.
- Репликация производства на вашем ноутбуке с помощью магии контейнеров Джейми Ли Коулман
- Docker Who: маленькие контейнеры сквозь время и пространство Дмитрий Чуйко
- Интеграционное тестирование с Spring Boot от Catalin Tudose
- Демистификация концепций и методологий программного обеспечения, связанных с “событиями”, Милен Дянков
- DiscoAPI – дистрибутивы OpenJDK как сервис от Геррита Грюнвальда
- Эволюция ваших API с помощью вашего покорного слуги
- Заключение
Репликация производства на вашем ноутбуке с помощью магии контейнеров Джейми Ли Коулман
Технология контейнеров действительно имеет старые корни.
- 1979 –
chroot
- 2006 –
cgroups
- 2008 – LXC
- 2013 – Docker
- 2014 – Kubernetes
Контейнеры обеспечивают много “волшебства”, которого нет у других технологий:
- Виртуализация на уровне ОС
- Переносимость с помощью образов
- Запуск в любом месте
- Изоляция
Конечно, контейнеры добавляют некоторую сложность, но в этом нет вины контейнеров. Они расширяют возможности пользователей, чтобы мы могли разрабатывать более сложные архитектуры.
Вот некоторые возможности, предоставляемые контейнерами:
- Изолированные среды разработки
- Портативный
- Предварительно сконфигурированные образы доступны в публичных реестрах
- Быстрый запуск приложений
- Не так много предварительных требований по сравнению с пустым программным обеспечением
- Контроль версий зависимостей
- Возможность разработки в облаке
- Тестирование в реальных условиях
Давайте сосредоточимся на тестировании. Чем ближе тестирование к производственной среде, тем оно надежнее. Контейнеры могут помочь устранить несколько пробелов:
- Доступ к данным, например, доступ к базам данных.
- Интеграционное тестирование
- Автоматическое обновление и контроль версий
- Сложная настройка на машинах для разработки
- Портативная среда тестирования
Testcontainers – это проект, представленный в 2015 году. Это фреймворк с открытым исходным кодом, который позволяет разработчикам преодолеть разрыв между средами разработки и производства.
- Интеграционные тесты – доступ к данным, интеграция приложений, тесты UI/приемки
- Дополнительная мощность за счет вносимых модулей
- Поддерживает JUnit 4/5 и Spock
Testcontainers также позволяет проводить наиболее “интегрированную” форму тестирования – сквозное браузерное тестирование:
- Вы можете создать свежий экземпляр браузера
- Состояние не сохраняется во время выполнения
- Видеозапись обязательна, если что-то пойдет не так
Вот пример настройки базы данных PostgreSQL в контейнере с помощью Testcontainers.
@Container
public static GenericContainer<?> postgres = new GenericContainer<>("postgres")
.withNetwork(network)
.withExposedPorts(5432)
.withNetworkAliases(postgresNetwork)
Тестирование MicroShed интегрируется с экосистемой Jakarta EE для использования Testcontainers.
Она предлагает несколько реализаций:
- OpenLiberty
- Payara Micro
- Payara Server
- Wildfly
- Quarkus
Остальная часть презентации была представлена кодом и живыми демонстрациями
Docker Who: маленькие контейнеры сквозь время и пространство Дмитрий Чуйко
Докладчик вводит понятия Docker и Docker-образов, выделяя часть, связанную с размерами.
Образ Docker в своей основе представляет собой архив – коллекцию байтов. Однако образы состоят из слоев, упорядоченных по принципу “родитель-ребенок”. И образы, и слои хранятся в реестрах.
Возможны различные топологии вокруг реестра и хоста: доверенные реестры, прокси, зеркала, реестры PaaS и т.д.
Извлечение изображения не является бесплатным. В зависимости от реестра, например, поставщик облака может выставить вам счет. Например, Docker ввел ограниченные тарифы на извлечение. За превышение этих норм нужно платить. По этой причине меньшие образы снижают затраты.
В связи с этим выбор базового образа имеет большое значение. Напоминание: базовый образ начинается FROM scratch
.
Сделать образ маленьким можно несколькими способами:
- Сделать само приложение маленьким
- Использовать меньшее количество зависимостей
- Выбрать правильную ОС и зависимости
Для Java-приложений это означает следующее:
- Используйте небольшой JRE
- Рассмотрите нативный образ
- “Без ОС”, т.е. без дистрибутива
Alpine Linux – это легкий дистрибутив Linux, основанный на musl libc и busybox. Пакет занимает менее 3 МБ “на проводе” – в 10 раз меньше, чем Ubuntu! С помощью Alpine можно создать образ контейнера с JDK 17, который весит менее 100 МБ на диске. Это экономит много времени и снижает сопутствующие расходы.
Основополагающие принципы musl libc:
- Простота
- Эффективность использования ресурсов
- Внимание к корректности
- Простота развертывания
- Первоклассная поддержка UT8-теста
Обратите внимание, что libc имеет несколько реализаций помимо musl: uClibc, dictlibc, glibc и т.д. Мы можем сравнить их по многим параметрам! В общем, основная больная точка musl – это унаследованные заголовки, дружественные к коду. Кроме того, разрешение DNS работает по-другому.
Другой компонент Alpine – busybox: это один исполняемый файл, который содержит множество Unix-утилит. По этой причине его размер невелик.
Другой особенностью Alpine Linux является то, что он поставляется с выделенным менеджером пакетов – apk
и не имеет графического интерфейса. В целом, Alpine идеально подходит для контейнеров.
Хотя различия между musl и glibc невелики, они существуют. Поставщики JDK хотели устранить этот пробел. Проект Portalla, он же JEP 386, направлен на перенос Alpine Linux на архитектуры x64 и AArch64. Portalla сталкивается с парой проблем, но разработчики работают над ними.
Интеграционное тестирование с Spring Boot от Catalin Tudose
Стратегия пирамиды тестирования состоит из нескольких уровней.
- Приемочное тестирование: что ожидает пользователь.
- Системное тестирование: тестирование системы в целом
- Интеграционное тестирование: тестирование взаимодействия с “чем-то” извне, например, базами данных, работой
- Единица: методы, классы
На уровне единиц вы ни от чего не зависите. Если ваш тест не работает, вы знаете, что это ошибка в вашем коде. Мы хотим довести интеграционные тесты до такого же уровня уверенности.
Представьте себе тест, который вставляет сущность в базу данных и проверяет, что последняя содержит одну запись. Если мы повторим тест с аннотацией @RepeatedTest(2)
, то сможем показать, что тест не является идемпотентным. Следовательно, он не так безопасен, как модульный тест.
Чтобы решить эту проблему, мы можем использовать @DirtiesContext
. Эта аннотация информирует фреймворк Spring о том, что выполнение теста “испачкало” контекст. После выполнения Spring создает новый контекст с нуля. Расходом является дополнительное время, так как Spring необходимо инициализировать контекст.
Альтернативой является аннотирование теста с помощью @Transactional
. В конце каждого выполнения Spring откатывает транзакцию. Наряду с @Transactional
, Spring предлагает @BeforeTransaction
, @AfterTransaction
, @Commit
и @Rollback
.
Другой альтернативой является настройка @TestExecutionListener
. С его помощью вы можете напрямую подключиться к жизненному циклу теста. По умолчанию регистрация нового слушателя заменяет все слушатели по умолчанию, включая слушатель инъекции зависимостей. Вам придется либо заново вводить их вручную, либо настроить слушатель так, чтобы он объединял новый слушатель с установленным по умолчанию.
Приложения обычно должны работать в разных контекстах. Например, разработчик хочет запустить приложение локально, используя базу данных H2, а в производстве мы используем MySQL. @Profile
– ваш друг в этом случае: можно связать бобы с определенным профилем. Например, вы можете установить базу данных H2 в профиль dev
, а MySQL – в профиль prod
. Во время выполнения вы настраиваете, какие профили активны: Spring будет создавать бобы, соответствующие только активным профилям.
Для тестирования HTTP-уровня можно внедрить экземпляр MockMvc
в тест с помощью аннотации @AutoConfigureMockMvc
.
Демистификация концепций и методологий программного обеспечения, связанных с “событиями”, Милен Дянков
В программном обеспечении мы используем слово “событие”, но разные люди могут вкладывать в это слово разный смысл. Давайте погрузимся глубже.
Представьте себе дверь с идентификатором 28 и желтым цветом; затем она становится красной, но сохраняет тот же идентификатор. Если вы знаете только текущее состояние объекта, вы не можете рассуждать о предыдущем состоянии. Можно, если хранить изменения, а не состояние.
Определение события – это уведомление о том, что что-то произошло. Поскольку событие произошло – обратите внимание на прошедшее время; событие естественно неизменяемо.
Само событие – это первоклассный thingamajig.
— Мартин Фаулер
Событийный штурм – это техника обнаружения и проектирования бизнес-процессов. Идея заключается в том, чтобы построить общее понимание системы между бизнесом и разработчиками, а также всей организацией. Сессии событийного штурма направлены на составление списка всех возможных событий, которые могут произойти в рамках системы.
Моделирование событий – это план решения. Некоторые считают, что штурм и моделирование событий – это одно и то же, но это не является целью данного разговора. Моделирование событий отображает действия системы на временной шкале без разветвлений. Дополнительным преимуществом является то, что оно позволяет выявить события, которые традиционное написание спецификации не позволило бы.
![]()
Адам Димитрук 🇨🇦🇵🇱🇺🇦@adymitruk
О боже. @EventModeling зоопарк в качестве примера упражнения придумывает некоторые творческие события…14:24 PM – 30 Sep 2021![]()
![]()
![]()
Итак, что такое событийно-ориентированное управление? В основе event-driven лежат две концепции: производители выпускают события; потребители заинтересованы в конкретных событиях. Маршрутизатор – это посредник между производителями и потребителями, который знает, как направить сообщения от первых ко вторым.
И все же, в конечном счете, event-driven – это просто громкое слово! Оно отлично подходит для рекламы продукта, но это не совсем точный с технической точки зрения термин. Это ложное утверждение: если событие – это уведомление, то оно ни к чему не приводит. Движущим фактором является решение, принятое либо пользователями, либо алгоритмами.
Обратите внимание, что event-driven также является полисемией. Для более подробного объяснения посмотрите The many meanings of event-Driven architecture.
Далее следует больше определений. Уведомление о событии дает уведомление через событие. На него нет ответа, и оно не содержит много данных. Если вы хотите узнать больше, вам нужно вернуться к исходной системе.
Передача состояния с переносом событий приводит к возникновению проблемы: какой источник данных является источником истины – производитель или потребитель? При потоковой передаче событий источник истины находится не на стороне потребителя, а в промежуточном посреднике. Посредник обеспечивает сохранение и маршрутизацию сообщений. Kafka является таким посредником.
Зачем производителю хранилище данных, если у нас есть медиатор? Мы можем хранить все в медиаторе. Теперь медиатор является единственным источником истины: медиатор стал хранилищем событий.
Характеристики хранилища событий следующие:
- Только добавление: никакого удаления, никакого изменения существующего события, никакой вставки перед последним. Невыполнение этих операций позволяет оптимизировать механизм хранения.
- Полное последовательное чтение: традиционные базы данных предназначены для различных целей.
- Воспроизведение: похоже на полное последовательное чтение, но фильтруется по интересующим событиям.
- Чтение событий агрегата: с точки зрения производителя, все события, произведенные одним производителем.
- моментальный снимок: вы не хотите, чтобы клиенты восстанавливали состояние из коллекции событий. Следовательно, хранилище должно быть способно предоставить моментальный снимок состояния и все события, произошедшие после него.
- Разделение и архивирование: как и в бухгалтерском учете, события, произошедшие после определенного времени, не имеют значения. Вы не хотите удалять их в целях аудита, но вы можете выгрузить их в другие более медленные и менее дорогие системы.
Чтобы назвать себя событийно-ориентированной системой, нам все еще не хватает некоторых вещей. Команда, например, “Джо приказал покрасить дверь 28 в красный цвет”, не является событием. Аналогично, запрос информации – это запрос, а не событие. В последнем случае критическим битом являются данные, содержащиеся в ответе. Следовательно, сообщения имеют различные типы; событие – это особый тип сообщения. Когда имеется маршрутизатор сообщений, его удобно использовать для маршрутизации событий и других сообщений, таких как команды и запросы. Мы только что представили CQRS.
Грег Янг представил CQRS для разделения между чтением и записью. В то время речь шла о том, чтобы иметь разные объекты, выделенные для каждой операции. Сейчас речь идет об отдельных моделях, а не об объектах. В CQRS события обычно используются для синхронизации между моделями чтения и записи.
В завершение выступления Милен рассказал о продуктах своей компании:
- Axon Server – маршрутизатор сообщений и сервер событий.
- Axon Framework – это фреймворк с открытым исходным кодом для построения DDD и CQRS систем
DiscoAPI – дистрибутивы OpenJDK как сервис от Геррита Грюнвальда
Главный вопрос – как получить JDK: на сайте поставщика или через проприетарный API поставщика?
Ситуация сложная:
- Множество дистрибутивов: кто слышал о Tencent Kona?
- Множество версий
- Нет центрального места
- Разные виртуальные машины
Это нелегкий выбор!
Было бы здорово иметь один унифицированный API, чтобы объединить их всех: Disco API в помощь! API собирает много информации: дистрибутив, версия, платформа, ОС, архитектура, типы архивов, статус релиза, срок поддержки, типы пакетов и т.д.
API предлагает HTTP URL для вызова, но без пакетов. Вы можете найти API по адресу https://api.foojay.io/. Он также предоставляет конечную точку OpenAPI, так что вы можете работать с API в браузере.
API имеет свое мнение: он использует не имя производителя, например, Azul, а имя дистрибутива, например, Zulu.
Далее докладчик подробно описывает API.
Проект доступен на GitHub. Он также предлагает плагины:
- Для наиболее распространенных IDE: IntelliJ IDEA, Eclipse и VS Code.
-
Для браузеров:
- DiscoChrome для Google Chrome
- DiscoFox для Firefox
- DiscoSafari для Apple Safari
- DiscoEdge для Edge.
Можно также установить соответствующий CLI, discocli
, который запрашивает API.
Еще один инструмент – JDKMon для определения установленных JDK:
- Проверяет наличие обновлений.
- Перечисляет возможные альтернативы
- Читает примечания к выпуску
- Перечисляет связанные CVE. Подсказка: он проверяет не конкретный JDK, а родительский OpenJDK.
Наконец, обратите внимание, что в версии v2 setup-java GitHub Action возможные дистрибутивы JDK ограничены четырьмя вариантами. Если вам нужно использовать дистрибутив, которого нет в списке, используйте foojayio/setup-java для настройки любого дистрибутива.
Эволюция ваших API с помощью вашего покорного слуги
Я уже написал полноценный пост в блоге об Evolving your APIs. Скоро будет доступна запись выступления.
Заключение
jPrime – это отличная конференция под руководством сообщества. После двух лет проведения Covid они смогли привлечь около 1 тыс. слушателей, местных и международных докладчиков. И еще один плюс – все доклады на английском языке!
Не пропустите следующий выпуск, 30-31 мая.th, 2023!
Первоначально опубликовано на A Java Geek 29 маяth, 2022