То, что в Java не поддерживается модульность, известно всем. Проблема существует давно, и было немало попыток исправить ситуацию. Этой цели посвящен проект Jigsaw. В 2011 планировалось добавить поддержку модульности в Java 7, в 2014 – в Java 8, наконец, было анонсировано, что в конце июля 2017 выйдет Java 9 с возможностью модуляризации. Но что же делать в ожидании этого прекрасного мига?

OSGi спешит на помощь


Для создания по-настоящему модульной архитектуры на языке Java можно воспользоваться OSGi (Open Services Gateway Initiative) – спецификацией динамической модульной системы и сервисной платформы для Java-приложений (разработчик OSGi Alliance). Она описывает модель разработки ПО, при которой компоненты обладают тремя основными признаками модульного приложения. Речь об инкапсуляции (каждый модуль скрывает свою реализацию от внешнего окружения), слабой связности (модули взаимодействуют только с помощью заранее оговоренных контрактов) и динамичности (компоненты можно замещать на лету, без остановки всего приложения). Основой концепции OSGi являются 2 сущности: наборы (Bundles) и сервисы (Services).

Bundles


При разработке ПО на Java, как правило, используются сторонние библиотеки. В мире Java-библиотеки упаковываются в файлы с расширением JAR (Java ARchive) ? обыкновенный ZIP-архив, содержащий Java-классы (файлы с расширением .class). При этом использование библиотек может быть сопряжено с определенными сложностями.

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

Другая проблема – так называемый JAR Hell, об который разработчики сломали немало копий. Суть его в следующем: как только вы начинаете использовать разные версии одной библиотеки (такое случается в больших проектах, которые эволюционируют со временем), вы можете столкнуться с тем, что один и тот же класс имеет разные методы в разных версиях библиотеки. Java же устроена так, что будет использована первая версия библиотеки, которую найдет загрузчик классов. Тем самым, обратившись в коде к какому-либо классу во время выполнения программы, вы получите ошибку, что метод, к которому вы обращаетесь, не существует. Связано это с тем, что на этапе выполнения Java ничего не знает о версии библиотеки, которая должна использоваться в том или ином случае.

Разработчики OSGi не стали менять структуру JAR-файлов для обеспечения модульности, а просто добавили в них дополнительную информацию, которая используется средой OSGi. Причем, информация эта никак не влияет на использование JAR-файлов в обычных Java-приложениях. Итак, чтобы JAR-файл стал OSGi-набором, в него добавляются данные, которые определяют Export-Package (пакеты этого набора, доступные для использования вне его) и Import-Package (пакеты других наборов, требующиеся для работы этого набора). При этом возможно задать как версию API, которую набор предоставляет для других наборов, так и версию или диапазон версий API, которые набор требует для своей работы от них же. Все классы набора, которые не находятся в его экспортируемой секции, не доступны вне набора (Private). Таким способом OSGi-набор выполняет требование слабой связности.

Сегодня большинство Java-библиотек уже OSGi ready, т.е. содержат информацию для возможности выполнения в OSGi-контейнере. Кроме того есть немало инструментов и утилит, с помощью которых можно создать модули для OSGi из обычных JAR-файлов.

Рис. 1.

В OSGi можно легко избегать ситуаций JAR Hell, так как зависимости между наборами и интерфейсы, предоставляемые этими наборами, имеют четкие версии. Можно динамически загружать и выгружать новые наборы во время выполнения. OSGi отслеживает зависимости между наборами и динамически разрешает их.

Services


Итак, с помощью OSGi-наборов мы можем разрабатывать модульные приложения, которые взаимодействуют посредством интерфейсов (API). Но где взять класс, который реализует требуемый интерфейс? Вариант «добавить в API набора» не подходит – в рамках модульной архитектуры мы договорились не использовать внутренние классы наборов вне этих наборов. Другое решение ? применить шаблон «фабрика», реализуя интерфейс, и добавить его в API набора. Но и оно не слишком удачно, т.к. для сокрытия реализации интерфейса придется каждый раз разрабатывать новый класс.

Поиск реализации интерфейса в OSGi осуществляется с помощью реестра сервисов. В этом реестре набор может зарегистрировать реализацию с описывающим её интерфейсом. Набор, использующий интерфейс из другого набора, может найти в реестре требуемую реализацию нужного ему интерфейса. Как правило, наборы регистрируют сервисы при запуске в OSGi-контейнере. Плюс ко всему в реестре сервисов могут быть зарегистрированы одни и те же интерфейсы с разными реализациями и дополнительными идентификационными данными. Используя фильтрацию, набор может выбрать в реестре наиболее подходящий из представленных сервисов.

Рис. 2.

Микросервисы Java Virtual Machine


Микросервисная архитектура представляет собой набор независимых модулей – отдельных приложений. Взаимодействие между ними происходит посредством четко определенных интерфейсов с применением легковесных протоколов (REST, Protocol Buffers, MQ и т.д.). По факту каждый модуль – это микросервис, выполняющий одну конкретную задачу и содержащий, как правило, минимальное количество кода. Преимущества этого подхода к разработке ПО:

  • легкость (при разработке микросервиса реализуется лишь одна часть функциональности программы).
  • простота замены (если сервис не справляется со своей задачей, его можно переписать и заменить на новую версию без остановки текущего ПО).
  • повторное использование (микросервис может многократно использоваться там, где он подходит).

Разработчики модульных приложений с применением OSGi давно пользуются всеми этими преимуществами, но только в рамках виртуальной машины Java. Каждый набор с OSGi, который публикует сервис в реестр, является микросервисом внутри Java Virtual Machine, JVM (в мире OSGi такие микросервисы называются µServices).

Red Hat JBoss Fuse


Мы в «Джете» используем все преимущества OSGi при разработке ПО для телеком-операторов, страховых, процессинговых компаний. Для этого мы применяем Red Hat JBoss Fuse (конфигурация Fuse Fabric). Эта платформа предоставляет гибкую OSGi-среду для выполнения модульного приложения.

Непрерывность работы приложения, легкое горизонтальное масштабирование, простота развертывания, наличие средств управления кластером для кластерного ПО – все эти возможности доступны в Fuse Fabric. Технология позволяет развернуть несколько экземпляров Red Hat JBoss Fuse и объединить их в кластер, а также предоставляет централизованный инструмент управления получившейся средой.

В рамках Fuse Fabric существуют следующие абстракции:

Фичи (features) – совокупность OSGi-наборов, которые реализуют какой-либо функционал.
Профили (profiles) – совокупность фич, которые должны выполняться в рамках одного контейнера, и конфигурационные настройки для наборов, которые входят в фичу.
Контейнеры (containers) – отдельные JVM-процессы, которые выполняются на конкретном узле кластера Fuse Fabric под управлением контейнера Red Hat JBoss Fuse.

Рис. 3.

Любое ПО на базе технологии Fuse Fabric состоит из OSGi-наборов, которые группируются в фичи и развертываются в рамках какого-либо отдельного JVM-процесса на одном или нескольких узлах кластера в соответствии с заранее заданным профилем.

Среда Fuse Fabric дает множество инструментов для легкого управления полученным кластером. Можно создавать профили (а на их основе ? контейнеры), создавать/удалять/запускать/останавливать контейнеры на любом хосте, входящем в кластер, подключать новые узлы кластера и т.д. И все это online – без прерывания функционирования остальных узлов кластера. Есть возможность хранить несколько версий профилей, фич, OSGi-наборов.

Благодаря технологии Distributed OSGi, в полученной среде OSGi-наборы могут взаимодействовать в рамках как одного, так и разных контейнеров и даже разных хостов. Дополнительно (при минимальных затратах на разработку) каждый сервис, который предоставляет OSGi-набор, можно превратить в REST/web-сервис, который можно вызывать из внешних систем.

Таким образом, используя Fuse Fabric, мы можем создавать микросервисную архитектуру, которая поддерживает простоту настройки и развертывания, изолированное выполнение сервисов в рамках своих JVM-процессов (со своими специфичными настройками, например, разными настройками сборщика мусора), при этом сервисы взаимодействуют между собой по сети с использованием легковесного протокола.

Т.к. продукт Red Hat JBoss Fuse основан на Open Source стеке технологий Apache ServiceMix, в нашем распоряжении есть такие мощные технологии, как Apache ActiveMQ (реализация спецификации JMS), Apache Camel (реализация шаблонов интеграции корпоративных приложений), Apache CXF (библиотека для разработки REST/web-сервисов), Blueprint (предоставляет возможности внедрения зависимостей), Spring и т.д. Поскольку указанные технологии бесшовно интегрируются между собой в Red Hat JBoss Fuse, это значительно снижает время разработки требуемого функционала.

Материал подготовлен экспертами Центра программных решений компании «Инфосистемы Джет».
Поделиться с друзьями
-->

Комментарии (42)


  1. Regis
    24.03.2017 17:59
    +4

    Все же в преддверии выхода Java 9 — статья имеет интерес уже больше с точки зрения истории, чем с точки зрения практического использования. Разве что модули вдруг понадобились прямо «здесь и сейчас».


    1. jetinfosystems
      24.03.2017 18:41

      У нас до сих пор есть заказчики, которые работают на Java 7 и даже на Java 6.


      1. Regis
        24.03.2017 23:07

        Java 7 — еще куда ни шло… Но Java 6? Только если разработчикам не важна ни производительность, ни безопасноть, ни новые возможности языка/платформы.


        1. sleeply4cat
          25.03.2017 23:04
          -1

          Я до ноября 2016 поддерживал тестовую систему на java 5. Потом она ушла другим разработчикам. Слава Багу :D


        1. avost
          26.03.2017 01:25
          -1

          При чём здесь разработчики? Речь о заказчиках. А связано это, как правило, с большим объёмом легаси кода. Ну, такова вот жизнь…


          1. Regis
            26.03.2017 20:37
            -1

            99% объема «легаси кода» c 1.5 (и даже 1.4!) долнжо корректно работать на JDK 1.8. Так что само наличие старого кода — не аргумент.


            1. avost
              26.03.2017 20:50
              +1

              Да не в этом дело. Заказчики. Новое ПО должно проходить серьёзный дорогостоящий аудит и кучу согласований. Зачем им это, если у них 15 лет всё работает как часы? Вы только представьте себе, что на продавливание новой версии явы у вас уйдёт год. Приблизительно. Может больше. За этт время выйдет 15 апдейтов и ещё более новая версия.


              1. Regis
                26.03.2017 21:09
                -1

                Если для заказчика аудит — это чисто денег попилить и нет понимания того, что с точки зрения безопасности новая Java без аудита может быть лучше чем версия, которая проходила аудит 15 лет назад, то тут только руками развести можно. У них, случаем, Internet Explorer 6-й не стоит? )


                1. avost
                  26.03.2017 22:00
                  +1

                  Повторяю. У них 15 лет система работает. Зачем менять? Потому что у кого-то зачесалось? Ну, пусть у кого зачесалось, оплатит эти работы. Делов-то. И, таки, да, шестой эксплорер тоже вполне может использоваться. Вы помните сколько лет после официальной "смерти" полуось использовалась в банкоматах? А может ещё где-то и осталась…
                  БОльшая часть энтерпрайзного софта не торчит наружу в понимании пхп-уеб-разработки, а безопасность там обеспечивается другими средствами.


                  1. Regis
                    27.03.2017 03:36

                    На это я уже отвечал в дургой ветке. Речь исключительно о «живых» проектах.

                    А также обратите внимание на то, что я писал здесь. Если для вашего 15-летного приложения перечисленное действительно не важно — то пусть себе работает как есть. Главное понимание рисков и упущенных возможностей.


                    1. avost
                      27.03.2017 12:05
                      -1

                      Повторяю. Разработчики здесь не при чём. Вообще.
                      Повторяю. В большой корпорации вопрос переезда на новую версию может занимать год и более. И это не просто написал бумажку и оно случилось (пусть и через год), это значит целый год вам нужно будет обоснованно доказывать с цифрами в руках неотложную необходимость всего этого. Год нервотрёпки и километровых переписок в которые вовлечены десятки человек. Зачем? Чтобы что? Чтобы там цифирька в версии сменилась?
                      Повторяю, "живой" проект — это вовсе не обязательно страничка с котиками и бложик в интернете. В "кровавом энтерпрайзе" 99% разработок не торчат наружу ни одним концом.
                      Добавляю, если заказчик упрётся в производительность, то он сам к вам придёт и сам всё сделает с версиями и апгрейдами.
                      Упущенная возможность? И что там упущено? Если вместо лямбд в приложении обычные анонимные классы — всё пропало, всё упущено? Смешно.
                      Риски? Это, скорее, с новыми версиями риски. У системы, которая 15 лет исправно работает риски известны более, чем хорошо.


              1. sshikov
                27.03.2017 22:41

                Это странно слышать, откровенно говоря. Все банковские безопасники, каких я видел за много лет, люди вполне вменяемые. Не нужно ничего продавливать — они сами к вам придут, и попросят обновить нужные версии продуктов. Другое дело, что разработчики могут им вполне сказать — вы знаете, у нас нет ресурсов, чтобы смигрировать, протестировать и так далее.

                Я могу себе представить аудит и безопасников более серьезных, чем банковские, но согласитесь, это все же не слишком типично )))


                1. avost
                  27.03.2017 23:10

                  Попросят обновить чтобы что? Чтобы то, что стабильно и безопасно работало все 15 лет перешло в непонятное состояние, которое надо тестировать заново? Ну, должна же быть какая-то причина так сделать? Если была исправлена уязвимость, позволяющая организовать атаку на конкретную систему — да, это причина. А просто потому, что это более хипстерская версия — не, не покатит.


                  1. sshikov
                    28.03.2017 08:59

                    Причина у безопасников совершенно понятная — чтобы закрыть кучу известных уязвимостей, которые были обнаружены и исправлены между выходами Java 6 и Java 8, например. А уж доказать им, что обнаруженные уязвимости к вашему приложению отношения не имеют — это как правило забота разработчиков.

                    Ну т.е. я сформулирую еще раз — я никогда не видел, чтобы миграция на новую версию Java (или скажем Linux) тормозилась согласованиями. Как правило она тормозится потому, что это работа, и не маленькая. Как сама миграция, так и регрессионное тестирование на новой версии. Возможно я просто никогда не сталкивался с реальным аудитом.


                    1. avost
                      28.03.2017 11:03

                      Я не знаю в чём тут дело, но, одно время, когда часто названивали хантеры из люксофта и я на последующих собеседованиях спрашивал про стек технологий, я не помню случая, когда говорили про что-то свежее шестой явы. Может быть что-то изменилось, но ещё год назад было так. Ну, вот такова реальность. Про апдейты безопасности я уже говорил, большинство энтерпрайзного софта не торчит наружу и безопасность там обеспечивается другими мерами.


                      1. sshikov
                        28.03.2017 11:20

                        Это потому, что люксофт ищет кого-то в UBS :) Шутка, но с большой долей правды. Есть несколько таких контор, и их все уже запомнили в лицо, которые сидят на старых версиях.

                        Тем не менее, я не видел, чтобы кто-то был против обновления. Даже если известные дырки в Java вас не коснулись — кто вам гарантирует, что завтра не найдут еще одну, которая коснется? При том что Java 7 уже два года как перестала поддерживаться — ну и кто эту дырку в Java 6 будет закрывать, если что? Это риск, и его все как правило понимают. Но все все равно упирается в трудозатраты.


            1. sshikov
              27.03.2017 10:13

              Проблема в том, что не будет работать например WebSphere старой версии. Которую нужно купить более новую. Вот на этом все и заканчивается.


        1. webmascon
          26.03.2017 04:01
          +1

          20 марта я на продакшене наконец убил приложение которое работало на java 1.4 15 лет работало без нареканий тихонько в фоне делая свою работу


          1. Regis
            26.03.2017 20:39

            Если оно работало и его никто не изменял, а также если вы были уверены, что со сторны безопасности к нему было не подступиться — то и черт с ним. Но если у вас мало-мальски живой проект, то почему бы не обновиться на актуальную JDK?


    1. Koroed
      24.03.2017 18:43
      +3

      Jigsaw не исключает использование OSGi.

      В Jigsaw реализованы только структура пакета, проверка прав доступа во время компиляции и загрузки классов. При этом непосредственно инициация загрузки модуля и горячая замена будет возможна только через сторонние средства.


      1. Regis
        24.03.2017 23:14
        +1

        Jigsaw не исключает использование OSGi.
        А я такого и не утверждал.

        Речь о том, что для многих сценариев того, что будет в Java 9 — достаточно.


        1. sshikov
          25.03.2017 22:35
          +1

          На самом деле это совсем другие сценарии, нежели те, в которых сегодня реально используется OSGI. Причем я бы так сказал — если переход на OSGI, скажем в моей личной практике, занял максимум месяц, причем в конечном счете изменения при переходе Spring -> Spring DM чуть ли не косметические, т.е. все практически знакомо, просто надо понять простую вещь — ваши зависимости могут появляться и пропадать динамически, то переход на Jigsaw, как его описывают, это серьезная смена парадигмы.


    1. sshikov
      24.03.2017 19:24
      +1

      Ничего подобного. OSGI и обещанные модули совершенно независимы друг от друга.


    1. insolite
      30.03.2017 22:06

      Какой истории, вы о чем? Java EE до сих пор не имеет вменяемых средств для модуляризации приложений. В грядущем Java EE 8 JPMS никак задействована не будет. Учитывая скорость, с которой идет развитие платформы, ждите православную модульность для Enterprise Java года через три.

      Единственный пока положительный результат финализации JPMS — модуляризация JDK. За счет существенного усложнения всей модульной системы, поскольку модульность пришлось впиливать задним числом.

      Это при всем том, что аналогичные концепции детально проработаны и реализованы в OSGi с незапамятных времен, а Enterprise OSGi существуют уже лет пять.


      1. sshikov
        31.03.2017 17:52

        Да потому что они там нафиг никому не нужны.

        Модуляризация чего? Вашего приложения? Так оно и так состоит из либо EAR/WAR/JAR, которые вполне себе модули, либо из OSGI бандлов, которые тоже модули.

        Контейнера? А зачем? Чтобы выпилить JTA, и собрать TomEE поменьше размером?

        Вы можете реальные потребности озвучить?


        1. insolite
          31.03.2017 18:38

          Не уловил пока вашу позицию. Если адекватная модульность для Java EE приложения не нужна, то для чего в нем вдруг появляются OSGi-бандлы? Может, кому-то все-таки нужна?

          EAR/WAR/JAR — это такая смешная модульность. В совокупности с иерархичными загрузчиками классов любой залетевший в нее дятел ведет к краху всего приложения. Начинать какой-то holy war не хочу, ничтоже сумнящиеся могут оценить количество вопросов на SO по [java-ee] + [classcastexception].

          PS
          У меня нет проблем с закрытием моих реальных потребностей. Это либо OSGi-контейнер, либо EAB/WAB в нормальном Java EE сервере вроде Websphere Liberty. Просто тот кровавый enterprise, в котором живет Java EE, привык следовать стандартам. Отсюда частая невозможность выбирать технологический стэк. OSGi — это не стандарт в мире Java EE и никогда им не будет. Но лично у меня нет сомнений, что JPMS пошагает в Java EE.


          1. sshikov
            31.03.2017 19:13
            +1

            Моя позиция очень простая — состояние с модульностью в JavaEE значительно лучше, чем почти везде. Если эта модульность вам кажется смешной — покажите, где она не смешная? Для справки — я на JavaEE где-то с 2000 года, а на OSGI (karaf) — с 2014, так что могу сравнить кое-что. Почти все контейнеры видел и щупал живьем, разве что в разное время. Что с чем сравнивать?

            ClassCastException? Ну так эта… как бы это помягче… тут недавно была статья на хабре, где автор предлагал положить зависимости в lib/ext. Ну вы меня поняли? Если постараться — можно сломать все что угодно. Это не довод в общем случае.

            Иерархия класс лоадеров в JavaEE требует минимального применения мозгов, причем (к большому сожалению) — включая знания о конкретном контейнере (и версии JavaEE тоже).

            OSGi лежит внутри у многих вменяемых контейнеров, так что считать его «нестандартным» по мне так даже как-то странно. Всем кому он нужен, и кому его не хватает — он доступен как дополнение.

            Скажем так — чтобы не обобщать зря: я просто никогда не видел такого кровавого энтерпрайза, как вы описываете. Вот смотрите — я в этом самом кровавом уже 12 лет с хвостиком. Где-то с 2009 мне попадается разработка на OSGI, причем раньше — голый Equinox, значительно хуже, чем это можно делать сейчас. А сейчас ни мне, ни в соседних проектах вообще никто слова не скажет, если я прикручу куда-то karaf, там где его еще нет.


  1. pmcode
    24.03.2017 20:17
    +1

    Сегодня большинство Java-библиотек уже OSGi ready, т.е. содержат информацию для возможности выполнения в OSGi-контейнере.

    Даже не верится. Когда 2-3 года назад я пробовал играться с OSGi, основным способом подружиться с Maven была сборка fat-jar со всеми зависимостями проекта, который уже в свою очередь цеплялся как модуль к основному проекту. Необходимость паковать зависимости в бандлы самому всегда была основным препятствием. Сейчас проверил commons-lang поддерживает, guava — поддерживает, jackson — поддерживает… что называется «с разморозкой» :)


    1. grossws
      25.03.2017 05:07

      Просто много куда дотянулись контрибьюторы, которым было не лень настроить мавеновский плагин org.apache.felix:maven-bundle-plugin для запуска bnd.


      Там, конечно, всё равно надо писать кусок OSGi-specific конфигурации (Import-Package, DynamicImport-Package, Export-Package, Bundle-Activator, Embed-Dependency), но с bnd оно куда проще, чем то, что было раньше.


    1. sshikov
      25.03.2017 22:27

      Это вообще в большинстве случаев не нужно. Берете karaf, берете обычный jar,

      install wrap:mvn:groupId/artifactId/version

      и все уже работает. Нет манифеста? Ну значит все экспортируется. Для случаев commons-lang этого более чем достаточно. Внутри у него видимо bnd.


  1. grossws
    25.03.2017 04:58

    файлы с расширением JAR (Java ARchive) ? обыкновенный ZIP-архив

    Не совсем корректно. Там ещё есть специальный magic 0xcafe в первой zip entry и ограничены допустимые виды сжатия.


    1. sshikov
      25.03.2017 22:32
      +1

      Насколько я помню, наличие magic необязательно. А виды сжатия… ну да, если выбрать слишком экзотический — то штатный класслоадер не сможет распаковать, с этим ничего не поделать, распаковщик — часть JRE. Так что практически — не любой, но именно что совершенно обыкновенный.


  1. webmascon
    26.03.2017 04:04

    А я вот щупал apache karaf приятный такой контейнер с osgi и всякими плюшками правда так и не придумал где и в каком приложении мне нужно все это. Разве что только есть ситуация когда надо в живом продакшен сервере подменить библиотеку на новую версию без рестарта


    1. sshikov
      26.03.2017 11:18

      Вы не представляете, насколько это реальный сценарий )

      Замените слово «библиотека» на «наше приложение», разбейте приложение на модули — и вы получите возможность деплоить в том числе и в прод среди бела дня, по мере готовности. Т.е. вы поставили новую версию своего приложения, старую остановили (а возможно даже и не останавливали), запустили, проверили что все хорошо — и пошли пить чай.

      У нас уже много лет оно живет в нескольких проектах вот таким вот образом. Сотни модулей, как минимум.


      1. webmascon
        27.03.2017 09:43

        а что используете в качестве контейнера? Karaf или Eclipse Equinox? или что-то коммерческое?


        1. sshikov
          27.03.2017 10:18

          У нас был как чистый karaf (3.x), так и Jboss Fuse (коммерческий с поддержкой, на основе karaf 2.x) или ServiceMix. Я, честно говоря, разницы не заметил. Те проблемы, которые на практике возникали, ровно также решаются сообществом karaf. Особенно если учесть, что люди за ними стоят в основном те же самые. А те, которые не решаются — они не решаются и коммерческой поддержкой. Например, довольно таки сложно смигрировать сам контейнер на более новую версию, или например обновить что-то глобальное, используемое всеми приложениями (типа Camel или скажем Spring), и сделать это так, чтобы ничего не поломать. И Fuse в этом мало чем может помочь.

          Кстати karaf сам по себе это не контейнер. У него внутри может быть Apache Felix либо Equinox.


          1. webmascon
            27.03.2017 15:15

            да. karaf не контейнер osgi, он как бы контейнер контейнеров так что-ли…


      1. Throwable
        27.03.2017 11:32

        А вот интересно, как вы все это пускаете в devmode? По стандартной схеме build-pack-deploy? Или плагин какой используете?
        И мне кажется, не совсем аргументирована модульность приложения. Внутренне — да, имеет смысл для кода и тестов. Но с точки зрения деплоя лучше иметь единственный артефакт, нежели груду джарников.
        Если необходима модульность, по-моему лучше будет разбить приложение на микросервисы и стартовать каждый в отдельной JVM/контейнере, как это делается сейчас. Единственный сценарий, который приходит на ум — платформа для деплоя различных приложений и микросервисов с разным циклом разработки. Что-то типа ESB или AppServer. Фактически там он в осносном и используется.


        1. sshikov
          27.03.2017 12:31

          Вопрос насчет того, что лучше, один контейнер или куча микросервисов — он большой и заслуживает отдельной статьи. Мне давно хочется ее написать, но она пока еще требует обдумывания.

          В моем случае это именно не приложение, а набор модулей, которые друг от друга сравнительно независимы. Каждый в отдельном контейнере? А ради чего? Ну т.е. это риторический вопрос, я и так знаю ради чего — я просто хочу заметить, что далеко не всегда то ради чего делают микросервисы, имеет место в жизни.


          1. Throwable
            28.03.2017 10:56

            Да, согласен. В этом случае OSGi действительно помогает как единая платформа для деплоя, если имеется большое число более-менее независимых модулей.


            Я сам не большой фанат контейнеров и микросервисов, поскольку в самой Java уже встроены неплохие средства виртуализации. Контейнеры сильно усложняют архитектуру и деплой и должны применяться только там, где это действительно необходимо, а не по зову моды. Также не имеет смысла искусственно дробить приложение на микросервисы, если у него единый функционал и цикл разработки.


        1. sshikov
          27.03.2017 15:37
          +1

          И да, это в общем-то и есть ESB (шина). Т.е. цикл разработки совершенно разный, и все вместе они никогда не деплоятся, скорее в одном релизе процентов 10 в лучшем случае.

          Ну и кстати, вопрос: а чем все-таки лучше разбить на микросервисы? Ну вот чем лучше не разбивать, я попробую сформулировать:

          * централизованная настройка (например, на 100 модулей у нас приходится порядка 20 разных баз данных, и в случае микросервисов мне бы пришлось настраивать url/логин
          пароль в 20 разных непонятных местах, а так они в одном месте.
          * централизованный мониторинг (одна копия JMX, и одна Hawtio консоль, откуда видно все).
          * установка и управление из одного места
          * один набор портов, торчащих наружу, для всех десятков web/rest сервисов. А точнее, один http порт и один https. И еще один набор сертификатов в одном месте.
          * я выделил всем сервисам скажем 16Gb, и они там живут, потому что потребляют память как правило в разное время и по-разному. Не факт, что это хорошо, но тем не менее — 100 отдельным JVM пришлось бы тюнить параметры для каждой.


        1. sshikov
          27.03.2017 22:37

          >Но с точки зрения деплоя лучше иметь единственный артефакт, нежели груду джарников.

          Кстати, для karaf артефакт — это в том числе и фича (см. выше с этом же посте), иначе говоря — такой xml с зависимостями.

          Т.е. karaf просто умеет деплоить такие вот множества jar-ов, взаимосвязанные друг с другом. Например, вы можете написать, что вам нужна фича «spring-jms», например, которая установится вместе с вашим модулем, и притащит с собой транзитивные зависимости. Ну типа как maven, только в OSGI runtime. И делаются они, кстати, из pom.xml при помощи karaf maven plugin, не прилагая усилий.

          Так что с точки зрения деплоя… для karaf это совершенно пофиг.