Я только что начал дискуссию в своей команде о том, какую структуру мы должны использовать в будущем для наших микросервисов, применив немного науки. Но, поскольку у меня, как известно, есть несколько твердые мнения по этим вопросам, я опубликую этот пост после того, как мы, как команда, выберем путь вперед, чтобы не искажать результаты (слишком сильно!). Тем не менее, я постараюсь быть объективным. Подробнее об этом позже, сначала постановка проблемы…
Мы больше не хотим управлять собственной инфраструктурой, поэтому пакуем чемоданы и направляемся в облако. В настоящее время мы используем Spring Boot, но есть ли что-то более облачное? Мы в основном команда Java, и для облачных вычислений достаточно повысить квалификацию, не добавляя в смесь новый язык.
Итак, в двух словах, наши требования таковы:
- Ява,
- Удобный контейнер (бережливый, быстро запускается/останавливается),
- Легко подобрать,
- …и модульный тест,
- Способствует интеграции с облачными сервисами (наблюдаемость, базы данных, сети и т.д.).
Претенденты
Вероятно, их гораздо больше, но я думаю, что я уловил здесь лидеров (включая их маркетинговый слоган).:
- Dropwizard – “Java-фреймворк для разработки удобных для работы, высокопроизводительных веб-сервисов RESTful”.
Хелидон – “Легкий вес. Быстро. Создан для микросервисов.” . Это бывает в двух вариантах:
- Селена реактивная первая структура,
- Микропрофиль (MP) – Реализует спецификацию микропрофиля для API на основе стандартов,
- Micronaut – “Современная платформа полного стека на основе JVM для создания модульных, легко тестируемых микросервисных и бессерверных приложений”.
- Кварки – “Сверхзвуковая субатомная Ява”
Spring Boot – “Spring Boot упрощает создание автономных приложений на базе Spring производственного уровня, которые вы можете “просто запустить”.” . Здесь будут опробованы два аромата:
- WebMVC: более императивный стиль, использующий API сервлетов под капотом,
- WebFlux: Реактивный API REST, использующий Netty,
- Vert.x – “Реактивные приложения на JVM”.
Честно говоря, все это соответствует большинству требований, перечисленных выше, и с некоторыми изменениями можно получить их все без особых усилий. Итак, мы должны выбрать другой способ отделить зерна от плевел:
- Относительные тесты:
- Скорость сборки – возможно, вы делаете это часто, так что это может привести к утечке реального времени,
- Скорость запуска – важна для масштабируемости и восстановления,
- Размер изображения – Небольшие изображения, как правило, имеют меньшую поверхность атаки и быстрее перемещаются по помещению K8s,
- Запросить Время в оба конца (RTT) – Это служба отдыха, поэтому нам нужны быстрые ответы,
- Субъективный тест: Насколько легко с ним развиваться?
Чтобы помочь каждому из них, я разработаю простой сервис REST с двумя конечными точками и соответствующим модульным тестом:
/привет/{имя}– Это просто возвращаетПривет {имя}!/привет/ошибка– Это вызывает пользовательское исключениеRuntimeException, которое должно быть обработано как 400 Неверный запрос и возвращеноО, нет!.
Это будет встроено в изображение с использованием кливера и той же базы adoptopenjdk/openjdk16:alpine . Там, где это возможно, для проверки конечных точек будет использоваться рекомендуемый подход подразделения тестирования.
Относительно Научный
Моя методология:
- Скорость сборки: просто запустите maven, включая
jib: docker Build, 10 раз и получите среднее значение. Это будет включать тестирование для каждой из конечных точек с использованием подхода, рекомендованного в их документации, - Размер изображения: указанный размер изображения из приведенной выше сборки из
изображений docker, - Скорость запуска: запустите изображения 10 раз и возьмите среднее значение,
- RTT: вызовите конечную точку
/привет/бобс помощью JMH, используя среднее время .
Предупреждающий знак Как всегда, возьмите микропленки со щепоткой соли. Существует так много факторов, влияющих на производительность, что, хотя эти результаты могут быть ориентировочными, они также могут не соответствовать типам ваших рабочих нагрузок. Таким образом, ваш пробег может отличаться.
Результаты:
| Скорость (ы) сборки | 9.345 | 22.605 | 11.322 | 11.954 | 9.574 | 11.790 | 11.840 | 14.364 |
| Размер изображения (По) | 370 | 375 | 376 | 382 | 376 | 368 | 383 | 381 |
| Начальная скорость (мс) | 374.6 | 665.8 | 753.5 | 1665 | 1573.4 | 424.9 | 1774.5 | 1557.8 |
| RTT (США/оп) | 1513.232 ± 74.767 | 1821.905 ± 124.261 | 1730.723 ± 64.688 | 1856.903 ± 47.301 | 1986.689 ± 34.877 | 1690.168 ± 80.618 | 2045.205 ± 78.650 | 1857.136 ± 82.583 |
Давайте начнем со времени сборки: Кваркус просто медленный. Я подозревал, что это был модульный тест (их рекомендуемый подход) или автономный режим, но даже без них он был постоянно медленнее, чем все остальные. Это также может быть их оболочкой для работы, но, поскольку вы вынуждены ее использовать, мало что можно сделать. Все остальные находятся в пределах нескольких секунд друг от друга, так что из этого мало что можно извлечь.
ℹ️ Quarkus был единственным фреймворком, который требовал использования собственной оболочки Jib. Я пытался использовать кливер напрямую, но продолжал жаловаться на отсутствие pom.xml . Это также означало, что у меня возникли проблемы с настройкой автономного режима , вызывающие сбои сборки.
Далее для создания изображений: все они имеют одно и то же базовое изображение и инструмент, чтобы попытаться получить сопоставимые результаты, и победителем стал Helidon SE, что меня удивило, так как я ожидал, что Vert.x занял второе место. В середине с очень похожими результатами были Helidon MP, Quarks и Micronaut как с весенними сборками, так и с Dropwizard в хвосте. Честно говоря, все они находятся в пределах нескольких МБ, так что явного победителя нет. Возможно, было бы полезно рассмотреть возможность использования других инструментов, таких как Link или GraalVM, чтобы действительно сократить их, но не все фреймворки поддерживают это.
Теперь о времени запуска: опять же, ожидалось, что реактивные фреймворки lean будут здесь самыми быстрыми, поскольку они избегают управления жизненным циклом компонентов… и они тоже были здесь: Vert.x и Helidon SE получили два места для остановки. Для фреймворка, который управлял жизненным циклом компонентов, Quarks отлично справляется с быстрым запуском и занимает 3-е место, что может быть связано с их собственной реализацией CDI: дуга. За этим внимательно следит Micronaut. В хвосте Spring Web Flux, Helidon MP и Dropwizard с Spring WebMVC сзади, но все в пределах ~ 200 мс между также-rans. Однако, поскольку ни один из них не длится более 2 секунд, мы прошли долгий путь [Всего] от полноценных серверов приложений!
Наконец, давайте рассмотрим время RTT; они несколько неубедительны. Как и ожидалось, меньшие, более функциональные API на основе реактивных интерфейсов (Vert.x и Helidon SE), как правило, быстрее, чем более императивные подходы. Единственным выбросом, похоже, является поток веб-страниц Spring Boot, но я подозреваю, что это связано с тот ApplicationContext управление жизненным циклом компонента. В любом случае разница между лучшим и худшим составила всего 531 микросекунду (0,5 миллисекунды). Форрестский трафик, вы вряд ли заметите какую-либо разницу, если только вы не обслуживаете огромное количество трафика.
Субъективно Анекдотический
Прежде всего: с кварками просто трудно работать по сравнению с другими. Код довольно чистый и простой, но на каждом шагу вам нужно предпринимать специальные шаги, чтобы заставить его встроиться или встроиться в изображение, и это просто болезненно. Некоторые из проблем:
- Во время этого я достиг страшного Ограничения скорости докеров , и для Кливера было легко обойти (т.Е.
-- в автономном режимеили с использованием зеркал ). Однако с кварками, с их собственной оболочкой стрелы, это невозможно, - Он ведет себя очень по-разному между IDE и контейнером, что делает отладку непоследовательной. Их режим отладки – это их способ решения этой проблемы, но он просто кажется чрезмерно продуманным “исправлением” проблемы, которой не должно быть,
- Тестовый жгут просто медленный по сравнению с остальными,
- Почему мне нужно использовать плагин maven для добавления функций/расширений? И он переформатировал
pom.xmlиспользовать пробелы (да, я тот самый отступник-индивидуалист, который использует табуляции!), - Почему мне нужно использовать пользовательские инструменты для создания проектов? Почему для этого нет архетипов Maven, как у всех остальных?
Следующим по сложности был Vert.x, в основном из-за тестовой обвязки. Меня беспокоит, что вам нужно обратиться к третьей стороне, чтобы получить другую библиотеку , которая решает все проблемы, созданные вашими собственными тестовыми приборами. После запуска и запуска он был довольно прост в использовании, но, безусловно, не был удобен для разработчиков в начале.
Функциональные/реактивные шаблоны имеют несколько крутую кривую обучения, поэтому изящный, простой в использовании API значительно помогает внедрению. Я не мог бы назвать Spring Boot Web Flux изящным … на самом деле, совсем наоборот, это настоящий собачий обед! Действительно многословное, запутанное именование, сложная обработка ошибок и просто ужасно выглядит в конце. Потребовалось немало времени, чтобы все заработало, но я не завидую человеку, который должен это поддерживать.
Все остальные были довольно простыми, и я не мог провести между ними существенных различий.
ℹ️ Код для этого доступен здесь . Если я допустил какие-то вопиющие упущения, пожалуйста, укажите на них.
Давайте начнем с более слабого конца: два, которые занимают наибольшее количество столбцов в блогах и новостных сайтах, – это те два, которых я бы избегал:
- Кварки – это просто сводит с ума и поэтому расстраивает в использовании. Я не понимаю, зачем им нужно придумывать решения проблем, которые они сами создают!? Если я не могу доверять поведению локально, оно будет таким же, как в тесте или в контейнере, я не могу доверять ему в производстве. Его единственным преимуществом является то, что он запускается быстрее, чем другие фреймворки, реализующие микропрофиль,
- Spring Boot – им нужно просто положить его в корзину и начать снова; WebFlux сложен в использовании, Web MVC – плохая версия JAX-RS, конфигурация XML должна была быть удалена много лет назад, а магия автоконфигурации Spring Boot просто бессмысленна для чего-либо, кроме очень базового приложения. У меня были проблемы, когда инициализировались совершенно несвязанные вещи, потому что он нашел библиотеку на пути к классу… это слишком легко сделать и вызывает огромную озабоченность в области безопасности.
Я знаю, что многие не согласятся со мной в этом, особенно если они уже купились на любой из них, но я не вижу никакой пользы в их использовании по сравнению с другими вариантами, которые гораздо проще использовать. Вероятно, это была бы другая история, если бы у них была какая-то значительная выгода (например, проще в использовании или значительно быстрее), но это не так.
Я изо всех сил пытаюсь выбрать здесь явного победителя. На верхнем конце у нас есть:
- Helidon – почти на вершине в каждом тесте, и его гибкие режимы SE и MP (которые также могут смешиваться и сочетаться) являются отличной функцией,
- Micronaut – Просто очень хорошо продуманный и простой в использовании,
- Dropwizard – Самый большой сюрприз здесь. Несколько наворотов и свистков, но выполняет свою работу без лишней суеты,
- Верт.х – Несмотря на то, что Vert.x несколько сложно протестировать, он получает похвалу за то, что он действительно худой и просто чертовски быстрый!
Со всем этим вы будете готовы и запущены за очень короткое время и не потребуете специальных приспособлений для их встраивания в изображения контейнеров, но если бы мне пришлось выбрать одно из них, это был бы Helidon. Я был фанатом некоторое время (и, полное раскрытие, также внес свой вклад в код), и выполнение этих тестов показало, что это, безусловно, лучшее. Внешний вид проекта и поддержка io_during является захватывающей, которая должна привести к серьезным улучшениям производительности. Тем не менее, в то же время я собираюсь гораздо внимательнее присмотреться к Micronaut и Dropwizard, если только я не покажу производительность, которая Vert.x будет занимать первое место в моем списке.
Что касается моей команды, то что они выбрали? Микронавт.
Оригинал: “https://dev.to/dansiviter/opinionated-take-on-java-microservices-frameworks-4ebh”