Как меняется специфика работы с серверами приложений на примере OpenLiberty



    Привет, Хабр!

    Выступление Себастьяна Дашнера на java meetup в московском офисе IBM (нашел запись похожего выступления) подтолкнуло меня начать свое знакомство с легковесными серверами приложений, в частности, с OpenLiberty. И тогда я задумался:

    1. Какие преимущества дают легковесные сервера приложений?
    2. Как меняется специфика работы при их использовании?
    3. Зачем упаковывать сервер приложений в контейнер?

    Отвечая на эти вопросы, я заметил, что информации по этой теме в открытом доступе мало, потому решил собрать и систематизировать её здесь.

    Результаты выкладываю под катом.

    Какие преимущества дают легковесные сервера приложений?


    Раньше корпоративные серверы приложений Java EE (такие как JBoss AS, Oracle WebLogic, IBM WebSphere AS) считались тяжеловесной и громоздкой конструкцией, особенно, если мы говорим о времени запуска и развертывания. Но облачные технологии захватывают все большую часть индустрии и требования к серверам приложений меняются.

    И вот, на смену полнофункциональным, корпоративным серверам приложений, приходят быстрые, модульные, небольшие сервера приложений, сфокусированные на выполнение определенной задачи: Thorntail, Payara Micro – младшие братья WildFly и Payara; Meecrowave – легковесный JAX-RS+CDI+JSON сервер, KumuluzEE – сервер, позволяющий расширять Java EE с помощью Node.js, Go и прочие.

    В этот список входит и OpenLiberty — open source сервер приложений (распространяется по EPL-1.0) поддерживающий самые последние стандарты Java EE/Microprofile, на базе которого работает WebSphere Liberty.

    Вкратце об особенностях EPL-1.0 (Eclipse Public License Version 1.0)
    EPL 1.0 базируется на CPL и не совместима с GPL, разрешает соблюдать другие лицензии и патенты, которые используются в работе, и предоставляет право лицензировать продукт под любой другой лицензией, копия лицензии должна быть включена во все копии программы.

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

    Связывание программного проекта с кодом, защищённым лицензией EPL (например, использование этого кода в качестве библиотеки), в общем случае, не делает этот проект производной работой и не накладывает соответствующих обязательств.

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

    Например: Участник может включить Программу в коммерческое предложение, продукт X. Тогда этот участник является Коммерческим участником. Если этот Коммерческий участник затем делает утверждения о скорости работы или предлагает гарантии по продукту X, эти утверждения и предложения являются персональной ответственностью Коммерческого участника. В рамках данного раздела Коммерческий участник должен защищать других Участников от претензий, относящихся к производительности и гарантиям, и если суд потребует любого другого Участника оплатить какой-либо результирующий ущерб, Коммерческий участник должен оплатить эти убытки.

    Давайте посмотрим, какие преимущества мы можем получить, развернув приложение в контейнере с OpenLiberty. (У вас должна быть установлена любая версия java, дальнейшие действия необходимо выполнять, находясь в директории wlp)

    Скорость:


    Скорость — важнейший показатель для облачного приложения, ведь для того, чтобы облачное приложение быстро масштабировалось, управлялось и справлялось с растущей нагрузкой, оно должно запускаться за считанные секунды. Легковесный сервер приложений способен сделать это. Чтобы проверить — скачаем сервер OpenLiberty и выполним bin/server run (полный список команд):

    $ bin/server run
     
    Запуск defaultServer (Open Liberty 19.0.0.6/wlp-1.0.29.cl190620190617-1530) в Java HotSpot(TM) 64-Bit Server VM версии 1.8.0_212-b10 (ru_US)
    [AUDIT   ] CWWKE0001I: Сервер defaultServer запущен.
    [AUDIT   ] CWWKZ0058I: Выполняется мониторинг dropins для приложений.
    [AUDIT   ] CWWKF0012I: На сервере установлены следующие комплекты: [el-3.0, jsp-2.3, servlet-3.1].
    [AUDIT   ] CWWKF0011I: Сервер defaultServer готов к работе для разумной планеты. Сервер defaultServer запущен за 1,709 сек.
    

    Модульность и гибкость


    Большинству приложений не нужна Java EE целиком, а требуется выделенный набор стандартов, чаще всего используемый в enterprise-приложениях. Благодаря OSGI, мы можем выбрать нужный нам набор стандартов Java EE и/или MicroProfile, игнорируя все остальное.

    Например, объявим JAX-RS из Java EE и mpHealth из Microprofile, добавив пару строк в featureManager блок usr/servers/serverName/server.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <server description="new server">
     
       <!-- Enable features -->
       <featureManager>
           <feature>jsp-2.3</feature>
           <feature>mpHealth-1.0</feature>
           <feature>jaxrs-2.1</feature>
       </featureManager>
     
       <!-- To access this server from a remote client add a host attribute to the following element, e.g. host="*" -->
       <httpEndpoint id="defaultHttpEndpoint"
                     httpPort="9080"
                     httpsPort="9443" />
     
       <!-- Automatically expand WAR files and EAR files -->
       <applicationManager autoExpand="true"/>
    </server>
    

    Динамическое обновление


    В процессе разработки программный код и конфигурация постоянно изменяются.
    Сервер приложений настроен для мониторинга изменений, и при необходимости переконфигурирует и развернет приложение на лету. Вот например, реакция на последние изменения:

    [AUDIT   ] CWWKG0016I: Начато обновление конфигурации сервера.
    [AUDIT   ] CWWKG0017I: Конфигурация сервера успешно обновлена за 0,475 сек.
    [AUDIT   ] CWWKF0012I: На сервере установлены следующие комплекты: [cdi-2.0, jaxrs-2.1, jaxrsClient-2.1, jndi-1.0, json-1.0, jsonp-1.1, mpHealth-1.0, servlet-4.0].
    [AUDIT   ] CWWKF0013I: С сервера удалены следующие комплекты: [servlet-3.1].
    [AUDIT   ] CWWKF0008I: Обновление комплектов выполнено за 0,476 сек. 

    Размер и сборка образа


    Размеры серверов приложений заметно уменьшились и теперь позволяют разворачивать
    каждое приложение на отдельном сервере приложений для упаковки их в контейнеры, давая широчайшую гибкость. Более того, т.к. образ состоит из слоев, при повторной сборке и распространении артефактов, копируется только слой приложения, ОС, среда выполнения и сервер приложений кэшируются.

    В dockerhub есть готовые образы, содержащие предварительно настроенный сервер OpenLiberty. Воспользуемся одним из них и создадим Dockerfile:

    FROM open-liberty
     
    COPY usr/servers/defaultServer /opt/ol/wlp/usr/servers/defaultServer
     
    ENTRYPOINT ["/opt/ol/wlp/bin/server", "run"]
    CMD ["defaultServer"]
    

    Соберём образ:

    docker build -t app . 

    Запустим его как контейнер:

    docker run -d --name app -p 9080:9080 app

    Проверим полученный результат http://localhost:9080/health/



    Для остановки контейнера:

    docker stop app

    Дальнейших сценариев использования контейнера множество, и в целом, это повод для отдельных статей, поэтому вернемся к вопросам.

    Как меняется специфика работы?


    Комплектация


    Образ контейнера должен собираться только один раз, а затем выполняется во всех средах. Поэтому рекомендуется собирать каждое приложение вместе c сервером приложений. Это упрощает жизненный цикл и развертывание приложений и отлично вписывается в современный мир контейнерных технологий.

    Сборка


    Сейчас уже не нужно упаковывать разные технические блоки в отдельные архивы. Вся бизнес-логика вместе с веб-сервисами и сквозным функционалом упаковывается в один war-файл. Это значительно упрощает установку проекта, а также процедуру сборки. Больше не приходится упаковывать приложение в виде нескольких уровней иерархии, чтобы затем снова распаковать его в один экземпляр сервера.

    Запуск


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

    Расширение функционала


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

    Зачем упаковывать сервер приложений в контейнер?


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

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

    Больше практики вы найдете здесь
    На сайте проекта помимо документации есть большое количество обучающих руководств: как создавать web-приложения с maven/gradle, упаковывать и разворачивать приложения, разворачивать и настраивать микросервисы в kubernetes, управлять трафиком с помощью istio, выполнять развертывание в IBM Cloud, у других популярных облачных провайдеров и многом другом.

    Себастьян Дашнер (Java & OSS энтузиаст, Java Champion, IBMer, JCP member, Jakarta EE committer) в своем блоге публикует полезные статьи о том, как пользоваться OpenLiberty, например, мониторинг Open Liberty с помощью Prometheus и Grafana, а его книга Architecting Modern Java EE Applications использовалась при подготовки этой статьи.

    Liberty-maven-plugin (альтернатива для gradle) может заметно упростить вашу работу. Кстати, в руководствах есть хорошие примеры его использования.

    Вы также можете внести свой вклад в проект.
    IBM
    113,53
    Компания
    Поделиться публикацией

    Комментарии 0

    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

    Самое читаемое