Як Quarkus аб'ядноўвае імператыўнае і рэактыўнае праграмаванне

У гэтым годзе мы плануем сур'ёзна развіваць тэмы кантэйнераў, Cloud-Native Java и Kubernetes. Лагічным працягам гэтых тэм будзе аповяд аб фрэймворку Quarkus, ужо разгледжаным на Хабры. Сённяшні артыкул прысвечаны не столькі прыладзе "субатамнай звышхуткай Java", колькі тым перспектывам, якія Quarkus прыўносіць у Enterprise.

Як Quarkus аб'ядноўвае імператыўнае і рэактыўнае праграмаванне

Java і JVM па-ранейшаму выключна папулярныя, але пры працы з бессервернымі тэхналогіямі і воблачна-арыентаванымі мікрасэрвісамі Java і іншыя мовы для JVM ужываюцца ўсё радзей, бо займаюць занадта шмат месца ў памяці і занадта павольна загружаюцца, з-за чаго дрэнна падыходзяць для выкарыстання з караткажывучымі кантэйнерамі. На шчасце, у цяперашні час гэтая сітуацыя пачынае мяняцца дзякуючы Quarkus.

Звышхуткая субатамная Java выйшла на новы ўзровень!

42 рэлізы, 8 месяцаў працы супольнасці і 177 узрушаючых распрацоўшчыкаў - вынікам усяго гэта стаў выпуск у лістападзе 2019 года Кваркус 1.0, рэлізу, які азначае сабой важную вяху ў развіцці праекта і прапануе масу класных функцый і магчымасцяў (падрабязней пра іх можна прачытаць у анонсе).

Сёння мы раскажам, як Quarkus аб'ядноўвае мадэлі імператыўнага і рэактыўнага праграмавання на базе адзінага рэактыўнага ядра. Мы пачнем з кароткага экскурсу ў гісторыю, а затым дэталёва разбяром, у чым заключаецца дуалізм рэактыўнага ядра Quarkus і як ява-распрацоўшчыкі могуць скарыстацца гэтымі перавагамі.

Мікрасэрвісы, кіраваныя падзеямі архітэктуры и бессерверной-функцыі - усё гэта сёння, што называецца, на ўздыме. З нядаўніх часоў стварэнне воблачна-арыентаваных архітэктур стала значна прасцей і даступней, аднак праблемы засталіся - асабліва ў Java-распрацоўшчыкаў. Напрыклад, у выпадку serverless-функцый і мікрасэрвісаў ёсць вострая неабходнасць у тым, каб скараціць час запуску, зменшыць выдатак памяці і ткі зрабіць іх распрацоўку справай зручнейшай і прыемным. Java у апошнія гады ўнесла некалькі паляпшэнняў, накшталт дапрацаванага для кантэйнераў функцыяналу ergonomics і інш. Аднак дамагчыся звычайнай працы Java у кантэйнеры па-ранейшаму няпроста. Таму мы пачнем з таго, што разгледзім некаторыя з унутраных складанасцяў Java, якія асабліва востра выяўляюцца пры распрацоўцы кантэйнерна-арыентаваных Java-прыкладанняў.

Для пачатку звернемся да гісторыі.

Як Quarkus аб'ядноўвае імператыўнае і рэактыўнае праграмаванне

Патокі і кантэйнеры

Пачынальна з версіі 8u131, Java стала больш-менш падтрымліваць кантэйнеры за рахунак паляпшэнняў у функцыянале ergonomics. У прыватнасці, зараз JVM ведае, на колькіх працэсарных ядрах яна выконваецца, і можа якая адпавядае выявай наладжваць пулы струменяў – як правіла, пулы fork/join. Безумоўна, гэта выдатна, але, дапусцім, у нас ёсць традыцыйнае вэб-дадатак, якое выкарыстоўвае HTTP-сервлеты і якія запускаюцца ў Tomcat, Jetty і інш. У выніку гэта дадатак выдасць кожнаму запыту асобны струмень і дазволіць яму блакаваць гэты струмень пры чаканні аперацый уводу-высновы, напрыклад, пры звароце да БД, файлам ці іншым сэрвісам. Гэта значыць, памер такога дадатку залежыць не ад колькасці даступных ядраў, а ад колькасці адначасовых запытаў. Акрамя таго, гэта азначае, што квоты ці ліміты ў Kubernetes па колькасці ядраў тут не асоба дапамогуць, і справа ў выніку скончыцца тратлінгам.

Вычарпанне памяці

Струмені - гэта памяць. І ўнутрыкантэйнерныя абмежаванні на памяць зусім не панацэя. Проста пачніце павялічваць колькасць прыкладанняў і патокаў, і рана ці позна вы сутыкнецеся з крытычным ростам частаты пераключэнняў і, як следства, з дэградацыяй прадукцыйнасці. Акрамя таго, калі прыкладанне выкарыстоўвае традыцыйныя мікрасэрвісныя фрэймворкі ці падлучаецца да БД, ці задзейнічае кэшаванне, ці неяк яшчэ дадаткова расходуе памяць, вам цалкам відавочна патрэбен прылада, які дазваляе зазірнуць унутр JVM і паглядзець, як яна кіруе памяццю, і пры гэтым не забіць саму JVM (напрыклад, XX:+UseCGroupMemoryLimitForHeap). І нават нягледзячы на ​​тое, што, пачынальна з Java 9, JVM навучылася ўспрымаць cgroups і якая адпавядае выявай адаптавацца, рэзерваванне і кіраванне памяццю застаецца даволі складанай справай.

Квоты і ліміты

У Java 11 з'явілася падтрымка CPU-квот (накшталт PreferContainerQuotaForCPUCount). Kubernetes таксама прапануе падтрымку лімітаў і квот. Так, усё гэта мае сэнс, але, калі прыкладанне зноў выходзіць за рамкі выдзеленай квоты, мы зноў прыходзім да таго, што памер - як у выпадку з традыцыйнымі Java-прыкладаннямі - вызначаецца па колькасці ядраў і з вылучэннем асобнага патоку на кожны запыт, то ёсць толку ад усяго гэтага няшмат.
Акрамя таго, калі выкарыстоўваць квоты і ліміты ці функцыі гарызантальнага (scale-out) маштабаванні платформы, ляжалай у аснове Kubernetes, праблема таксама не вырашаецца сама сабой. Мы проста трацім больш рэсурсаў на вырашэнне зыходнай праблемы або ў выніку прыходзім да перарасход рэсурсаў. А калі гэта высоканагружаная сістэма ў публічным агульнадаступным воблаку, мы амаль напэўна пачынаем выкарыстоўваць больш рэсурсаў, чым гэта сапраўды трэба.

І што з усім гэтым рабіць?

Калі па-простаму, то выкарыстоўваць асінхронныя і неблакіруючыя бібліятэкі ўводу-вываду і фрэймворкі накшталт Netty, Vert.x ці Akka. Яны значна лепш падыходзяць для працы ў кантэйнерах з прычыны сваёй рэактыўнай прыроды. Дзякуючы неблакіруючаму ўводу-вываду, адзін і той жа струмень можа апрацоўваць адразу некалькі адначасовых запытаў. Пакуль адзін запыт чакае вынікаў уводу-высновы, які апрацоўвае яго струмень вызваляецца і бярэцца за іншы запыт. А калі вынікі ўводу-вываду нарэшце паступаюць, апрацоўка першага запыту працягваецца. Чаргуючы апрацоўку запытаў у рамках аднаго і таго ж патоку, можна скараціць агульную колькасць патокаў і знізіць расход рэсурсаў на апрацоўку запытаў.

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

Як, і гэта ўсё?

Не, ёсць яшчэ сёе-тое. Рэактыўнае праграмаванне дапамагае лепш выкарыстоўваць рэсурсы, але таксама мае свой кошт. У прыватнасці, код давядзецца перапісваць згодна з прынцыпамі неблакіраванасці і пазбягаць блакіроўкі патокаў уводу-вываду. А гэта зусім іншая мадэль распрацоўкі і выкананні. І хаця тут ёсць маса карысных бібліятэк, гэта ўсё роўна кардынальная змена прывычнага спосабу мыслення.

Па-першае, вам трэба навучыцца пісаць код, які выконваецца асінхронна. Як толькі вы пачынаеце выкарыстоўваць неблакіруючы ўвод-вывад, вам патрабуецца відавочна прапісваць, што павінна адбыцца пры атрыманні адказу на запыт. Проста блакіраваць і чакаць больш не атрымаецца. Узамен вы можаце перадаваць зваротныя выклікі, выкарыстоўваць рэактыўнае праграмаванне або continuation. Але і гэта яшчэ не ўсё: каб выкарыстоўваць неблакіруючы ўвод-вывад, вам патрэбныя і неблакіруючыя серверы і кліенты, і пажадана ўсюды. У выпадку з HTTP усё проста, але ёсць яшчэ і БД, і файлавыя сістэмы, і шматлікае іншае.

І хоць татальная скразная рэактыўнасць дае максімум эфектыўнасці, такі зрух бывае цяжка пераварыць на практыцы. Таму магчымасць спалучаць рэактыўны і імператыўны код становіцца неабходнай умовай для таго, каб:

  1. Эфектыўна выкарыстоўваць рэсурсы на найбольш нагружаных напрамках праграмнай сістэмы;
  2. Выкарыстоўваць прасцейшы па стылі код у яе астатніх частках.

Прадстаўляем Quarkus

Уласна, у гэтым і ёсць сутнасць Quarkus аб'яднаць рэактыўную і імператыўную мадэлі ў рамках аднаго асяроддзя выканання.

У аснове Quarkus ляжаць Vert.x і Netty, па-над якімі выкарыстоўваецца цэлы шэраг рэактыўных фреймворков і пашырэнняў, закліканых дапамагчы распрацоўніку. Quarkus прызначаны для пабудовы не толькі HTTP-мікрасэрвісаў, але і кіраваных падзеямі архітэктур. Дзякуючы сваёй рэактыўнай прыродзе ён вельмі эфектыўна працуе з сістэмамі абмену паведамленнямі (Apache Kafka, AMQP і г.д).

Уся хітрасць у тым, як выкарыстоўваць адзін і той жа рэактыўны рухавічок як для імператыўнага, так і для рэактыўнага кода.

Як Quarkus аб'ядноўвае імператыўнае і рэактыўнае праграмаванне

Quarkus з гэтым бліскуча спраўляецца. Выбар паміж імператыўным і рэактыўным відавочны - выкарыстоўваць і для таго, і для іншага рэактыўнае ядро. І з чым яно вельмі дапамагае, дык гэта з хуткім неблакавальным кодам, які апрацоўвае амаль усё, што праходзіць праз струмень цыклу падзей (event-loop thread, ён жа – IO thread). Але калі ў вас ёсць класічныя прыкладанні REST або прыкладанні на баку кліента, у Quarkus напагатове імператыўная мадэль праграмавання. Напрыклад, падтрымка HTTP у Quarkus будуецца на выкарыстанні неблокирующего і рэактыўнага рухавічка (Eclipse Vert.x і Netty). Усе HTTP-запыты, якія атрымліваюцца вашым дадаткам, спачатку праходзяць праз цыкл падзей (IO Thread), а затым адпраўляюцца той частцы кода, якая кіруе запытамі. У залежнасці ад кропкі прызначэння код кіравання запытамі можа выклікацца ў рамках асобнага струменя (так званы worker thread, ужываецца ў выпадку сэрвлета і Jax-RS) ці ж выкарыстоўваць зыходны струмень уводу-высновы (рэактыўны маршрут reactive route).

Як Quarkus аб'ядноўвае імператыўнае і рэактыўнае праграмаванне

Для канектараў сістэм перадачы паведамленняў выкарыстоўваюцца неблакавальныя кліенты, якія працуюць па-над рухавічком Vert.x. Таму вы можаце эфектыўна адпраўляць, атрымліваць і апрацоўваць паведамленні ад сістэм класа messaging middleware.

На сайце Quarkus.io сабрана некалькі добрых кіраўніцтваў, якія дапамогуць пачаць працу з Quarkus:

Акрамя таго, мы падрыхтавалі анлайнавыя практычныя ўрокі для знаёмства з рознымі аспектамі рэактыўнага праграмавання, прычым для іх праходжання дастаткова ўсяго толькі браўзэра, ніякая IDE для гэтага не патрабуецца, ды і кампутар не абавязковы. Знайсці гэтыя ўрокі можна тут.

карысныя рэсурсы

10 відэаўрокі па Quarkus, каб асвоіцца ў тэме

Як пішуць на сайце Quarkus.io, Кваркус - гэта Kubernetes-арыентаваны Java-стэк, заменчаны пад GraalVM і OpenJDK HotSpot і сабраны з лепшых Java-бібліятэк і стандартаў.

Каб дапамагчы вам разабрацца ў тэме, мы адабралі 10 відэаўрокі, дзе асвятляюцца розныя аспекты Quarkus і прыклады яго выкарыстання:

1. Прадстаўляем Quarkus: Java-фрэймворк новага пакалення для Kubernetes

Аўтары: Томас Кворнстром (Thomas Qvarnstrom) і Джэйсан Грын (Jason Greene)
Мэта праекта Quarkus заключаецца ў тым, каб стварыць Java-платформу для Kubernetes і serverless-асяроддзяў, а таксама аб'яднаць рэактыўную і імператыўную мадэлі праграмавання ў рамках адзінага асяроддзя выканання, каб распрацоўшчыкі маглі гнутка вар'іраваць падыход пры працы з шырокім спектрам размеркаваных архітэктур прыкладанняў. Даведайцеся больш з уступнай лекцыі ніжэй.

2. Quarkus: звышхуткая субатамная Java

Аўтар: Блюр Сатэр (Burr Sutter)
Видеоурок з інтэрнэт-лекторыя DevNation Live дэманструе, як выкарыстоўваць Quarkus для аптымізацыі карпаратыўных Java-прыкладанняў, API, мікрасэрвісаў і serverless-функцый у асяроддзі Kubernetes/OpenShift, зрабіўшы іх значна менш, хутчэй і маштабуецца.

3. Quarkus і GraalVM: разганяем Hibernate да звышхуткасцяў і уціскаем да субатамных памераў

Аўтар: Сейн Гриноверо (Sanne Grinovero)
З прэзентацыі вы даведаецеся, як з'явіўся Quarkus, як ён працуе і як дазваляе зрабіць комплексныя бібліятэкі, накшталт Hibernate ORM, сумяшчальнымі з native-вобразамі GraalVM.

4. Вучымся распрацоўваць serverless-прыкладанні

Аўтар: Марцін Лютэр (Marthen Luther)
У відэа ніжэй паказана, як стварыць простае Java-дадатак з дапамогай Quarkus і разгарнуць яго ў якасці serverless-прыкладанні на Knative.

5. Quarkus: кадуйце з задавальненнем

Аўтар: Эдсан Янага (Edson Yanaga)
Відэгайд па стварэнні вашага першага праекта Quarkus, які дазваляе зразумець чаму Quarkus заваёўвае сэрцы распрацоўшчыкаў.

6. Java і кантэйнеры - якім будзе іх сумеснае будучыню

Аўтар: Марк Літл (Mark Little)
Гэтая прэзентацыя знаёміць з гісторыяй Java і тлумачыць, чаму Quarkus - гэта будучыня Java.

7. Quarkus: звышхуткая субатамная Java

Аўтар: Дзмітрыс Адрэандзіс (Dimitris Andreadis)
Агляд пераваг Quarkus, якія атрымалі прызнанне распрацоўшчыкаў: прастата, звышвысокія хуткасці, лепшыя бібліятэкі і стандарты.

8. Quarkus і субатамныя рэактыўныя сістэмы

Аўтар: Клемент Эскаф'ер (Clement Escoffier)
Дзякуючы інтэграцыі з GraalVM Quarkus забяспечвае звышхуткі вопыт распрацоўкі і субатамнае асяроддзе выканання. Аўтар кажа пра рэактыўны бок Quarkus і пра тое, як яму карыстацца пры стварэнні рэактыўных прыкладанняў і прыкладанняў з струменевай перадачай дадзеных.

9. Quarkus і хуткая распрацоўка прыкладанняў у Eclipse MicroProfile

Аўтар: Джон Клінган (John Clingan)
Спалучаючы Eclipse MicroProfile і Quarkus, распрацоўнікі могуць ствараць поўнафункцыянальныя кантэйнерныя прыкладанні MicroProfile, якія запускаюцца за нейкія дзясяткі мілісекунд. У відэа падрабязна разбіраецца, як кадзіраваць кантэйнерны дадатак MicroProfile для разгортвання на платформе Kubernetes.

10. Java, версія «Турба»

Аўтар: Маркус Біль (Marcus Biel)
Аўтар паказвае, як выкарыстоўваць Quarkus для стварэння супермаленькіх і суперхуткіх Java-кантэйнераў, якія дазваляюць здзейсніць сапраўдны прарыў, асабліва ў serverless-асяроддзях.



Крыніца: habr.com

Дадаць каментар