Programiranje

Obvladovanje Spring Spring 5, 2. del: Spring WebFlux

Spring WebFlux uvaja reaktivni spletni razvoj v pomladanski ekosistem. V tem članku boste začeli z reaktivnimi sistemi in reaktivnim programiranjem z Spring. Najprej boste ugotovili, zakaj so reaktivni sistemi pomembni in kako jih izvajajo v Spring framework 5, nato pa boste dobili praktičen uvod v gradnjo reaktivnih storitev z uporabo Spring WebFlux. S pomočjo opomb bomo zgradili svojo prvo reaktivno aplikacijo. Pokazal vam bom tudi, kako zgraditi podobno aplikacijo z uporabo novejših funkcionalnih funkcij Spring.

Pomladne vaje o JavaWorldu

Če ste v pomladanskem ogrodju prvič, priporočam, da začnete z eno od prejšnjih vadnic v tej seriji:

  • Kaj je pomlad Komponentni razvoj za Javo
  • Mastering Spring framework 5: Spring MVC

Reaktivni sistemi in Spring WebFlux

Izraz reaktivni je trenutno priljubljen pri razvijalcih in menedžerjih IT, vendar sem opazil nekaj negotovosti glede tega, kaj to dejansko pomeni. Če želite bolj jasno razumeti, kaj so reaktivni sistemi, je koristno razumeti temeljni problem, ki so ga zasnovali za reševanje. V tem poglavju bomo govorili o reaktivnih sistemih na splošno in predstavil bom API za reaktivne tokove za aplikacije Java.

Razširljivost v spomladanskem MVC

Spring MVC si je prislužil mesto med najboljšimi izbirami za izdelavo spletnih aplikacij in spletnih storitev Java. Kot smo odkrili v Mastering Spring framework 5, 1. del, Spring MVC neopazno vključuje pripise v robustno arhitekturo aplikacije, ki temelji na Springu. To razvijalcem, ki poznajo Spring, omogoča hitro izdelavo zadovoljivih, zelo funkcionalnih spletnih aplikacij. Razširljivost pa je izziv za Spring MVC aplikacije. To je težava, ki jo želi rešiti Spring WebFlux.

Blokiranje in neblokiranje spletnih okvirov

V tradicionalnih spletnih aplikacijah, ko spletni strežnik prejme zahtevo od odjemalca, sprejme to zahtevo in jo postavi v čakalno vrsto. Nit v naboru niti izvedbene čakalne vrste nato prejme zahtevo, prebere svoje vhodne parametre in ustvari odgovor. Če mora niti za izvajanje poklicati vir za blokiranje - na primer bazo podatkov, datotečni sistem ali drugo spletno storitev - ta nit izvede zahtevo za blokiranje in čaka na odgovor. V tej paradigmi je nit učinkovito blokirana, dokler se zunanji vir ne odzove, kar povzroča težave z zmogljivostjo in omejuje razširljivost. Za boj proti tem težavam razvijalci ustvarijo velikodušno področje niti, tako da lahko ena nit še naprej obdeluje zahteve, medtem ko je ena nit blokirana. Na sliki 1 je prikazan postopek izvajanja za tradicionalno blokirajočo spletno aplikacijo.

Steven Haines

Neblokirajoči spletni okviri, kot sta NodeJS in Play, imajo drugačen pristop. Namesto da izvršijo zahtevo za blokiranje in počakajo, da se dokonča, uporabljajo V / I, ki ne blokira. V tej paradigmi aplikacija izvede zahtevo, zagotovi kodo, ki se izvede, ko se vrne odgovor, in nato svojo nit vrne strežniku. Ko zunanji vir vrne odgovor, se izvede izvedena koda. Notranji neblokirajoči okviri delujejo z uporabo zanke dogodkov. Znotraj zanke koda aplikacije zagotavlja povratni klic ali prihodnost, ki vsebuje kodo, ki jo je treba izvesti, ko se asinhrona zanka zaključi.

Po naravi so neblokirajoči okviri po dogodkih. To zahteva drugačno programsko paradigmo in nov pristop k razmišljanju o tem, kako bo izvedena vaša koda. Ko si glavo ovijete, lahko reaktivno programiranje privede do zelo razširljivih aplikacij.

Povratni klici, obljube in terminske pogodbe

V zgodnjih dneh je JavaScript obvladoval vso asinhrono funkcionalnost prek povratne klice. V tem primeru se povratni klic izvede, ko pride do dogodka (na primer, ko je na voljo odgovor na klic storitve). Medtem ko so povratni klici še vedno razširjeni, se je asinhrona funkcionalnost JavaScript pred kratkim preselila v obljube. Z obljubami se funkcijski klic takoj vrne in vrne obljubo, da bo rezultate dal v prihodnosti. Namesto obljub Java izvaja podobno paradigmo z uporabo terminske pogodbe. Pri tej uporabi metoda vrne prihodnost, ki bo imela vrednost nekoč v prihodnosti.

Reaktivno programiranje

Mogoče ste že slišali izraz reaktivno programiranje povezane z okviri in orodji za spletni razvoj, kaj pa to v resnici pomeni? Izraz, kot smo ga spoznali, izvira iz reaktivnega manifesta, ki opredeljuje reaktivne sisteme kot štiri bistvene lastnosti:

  1. Reaktivni sistemi so odziven, kar pomeni, da se odzovejo pravočasno v vseh mogočih okoliščinah. Osredotočajo se na zagotavljanje hitrih in doslednih odzivnih časov, vzpostavitev zanesljivih zgornjih meja, tako da zagotavljajo stalno kakovost storitev.
  2. Reaktivni sistemi so vzdržljiv, kar pomeni, da ob neuspehu ostanejo odzivni. Odpornost dosežemo s tehnikami replikacije, zadrževanja, izolacije in prenosa. Če med seboj ločite komponente aplikacije, lahko preprečite napake in zaščitite sistem kot celoto.
  3. Reaktivni sistemi so elastična, kar pomeni, da ostanejo odzivni pri različnih delovnih obremenitvah. To dosežemo z elastičnim spreminjanjem komponent aplikacije, da zadostimo trenutnim potrebam.
  4. Reaktivni sistemi so na podlagi sporočil, kar pomeni, da se zanašajo na asinhrono sporočilo, ki prehaja med komponentami. To vam omogoča, da ustvarite ohlapno spenjanje, izolacijo in preglednost lokacije.

Slika 2 prikazuje, kako te lastnosti tečejo skupaj v reaktivnem sistemu.

Steven Haines

Značilnosti reaktivnega sistema

Reaktivni sistemi so zgrajeni tako, da ustvarjajo izolirane komponente, ki asinhrono komunicirajo in se lahko hitro prilagodijo trenutni obremenitvi. Komponente v reaktivnih sistemih še vedno ne uspejo, vendar so zaradi te okvare določena dejanja, ki ohranjajo sistem kot celoto funkcionalen in odziven.

The Reaktivni manifest je abstraktna, vendar so za reaktivne aplikacije običajno značilne naslednje komponente ali tehnike:

  • Podatkovni tokovi: A tok je zaporedje časovno razvrščenih dogodkov, kot so interakcije uporabnikov, klici storitve REST, sporočila JMS in rezultati iz baze podatkov.
  • Asinhrono: Dogodki toka podatkov se zajemajo asinhrono in vaša koda določa, kaj storiti, ko se dogodek odda, ko pride do napake in ko se tok dogodkov zaključi.
  • Brez blokade: Med obdelavo dogodkov vaša koda ne sme blokirati in izvajati sinhronih klicev; namesto tega mora izvajati asinhrone klice in se odzivati, ko se vrnejo rezultati teh klicev.
  • Protitlak: Komponente nadzorujejo število dogodkov in pogostost oddajanja. V reaktivnem smislu je vaša komponenta imenovana naročnik in dogodke oddaja a založnik. To je pomembno, ker naročnik nadzoruje, koliko podatkov bo prejel in se tako ne bo preobremenil.
  • Sporočila o napakah: Namesto komponent, ki vržejo izjeme, se napake pošljejo kot sporočila funkciji upravljavca. Medtem ko metanje izjem prekine tok, definiranje funkcije za obvladovanje napak, ko se pojavijo, ne.

API za reaktivne tokove

Novi API za reaktivne tokove so med drugim ustvarili inženirji iz Netflix, Pivotal, Lightbend, RedHat, Twitter in Oracle. API Reactive Streams, objavljen leta 2015, je zdaj del Jave 9. Določa štiri vmesnike:

  • Založnik: Odda naročniku zaporedje dogodkov.
  • Naročnik: Prejema in obdeluje dogodke, ki jih oddaja založnik.
  • Naročnina: Določi razmerje ena na ena med založnikom in naročnikom.
  • Procesor: Predstavlja fazo obdelave, ki jo sestavljata tako naročnik kot založnik in spoštuje pogodbe obeh.

Slika 3 prikazuje razmerje med založnikom, naročnikom in naročnino.

Steven Haines

Naročnik v bistvu ustvari naročnino na založnika in ko ima založnik na voljo podatke, naročniku pošlje dogodek s tokom elementov. Upoštevajte, da naročnik nadzoruje protitlak znotraj naročnine na založnika.

Zdaj, ko veste nekaj o reaktivnih sistemih in API-ju za reaktivne tokove, se osredotočimo na orodja, ki jih Spring uporablja za izvajanje reaktivnih sistemov: Spring WebFlux in knjižnico Reactor.

Projektni reaktor

Project Reactor je neodvisen okvir, ki temelji na Javini specifikaciji Reactive Streams, ki se uporablja za izdelavo neblokirajočih spletnih aplikacij. Project Reactor ponuja dva založnika, ki se pogosto uporabljata v Spring WebFlux:

  • Mono: Vrne element 0 ali 1.
  • Pretok: Vrne 0 ali več elementov. Pretok je lahko neskončen, kar pomeni, da lahko večno oddaja elemente za vedno ali pa vrne zaporedje elementov in nato pošlje obvestilo o zaključku, ko vrne vse svoje elemente.

Monosi in fluksi so pojmovno podobni terminskim pogodbam, vendar močnejši. Ko prikličete funkcijo, ki vrne mono ali tok, se bo takoj vrnila. Rezultati funkcijskega klica vam bodo dostavljeni prek mono ali fluksa, ko bodo na voljo.

V Spring WebFluxu boste poklicali reaktivne knjižnice, ki vrnejo monos in flukse, vaši krmilniki pa monos in flukse. Ker se ti vrnejo takoj, bodo vaši krmilniki dejansko opustili svoje niti in omogočili Reactorju, da asinhrono obravnava odzive. Pomembno je omeniti, da lahko samo z uporabo reaktivnih knjižnic vaše storitve WebFlux ostanejo reaktivne. Če uporabljate nereaktivne knjižnice, kot so klici JDBC, bo vaša koda blokirana in počakajte, da se ti klici zaključijo, preden se vrnete.

Reaktivno programiranje z MongoDB

Trenutno ni veliko knjižnic reaktivnih baz podatkov, zato se morda sprašujete, ali je praktično pisati reaktivne storitve. Dobra novica je, da ima MongoDB reaktivno podporo in obstaja nekaj neodvisnih gonilnikov reaktivne baze podatkov za MySQL in Postgres. Za vse druge primere uporabe WebFlux ponuja mehanizem za izvajanje klicev JDBC na reaktiven način, čeprav z uporabo sekundarnega področja niti, ki blokira klice JDBC.

Začnite s Spring WebFlux

Za prvi primer, kako narediti, bomo ustvarili preprosto knjižno storitev, ki ohranja knjige do in od MongoDB na reaktiven način.

Najprej se pomaknite na domačo stran Spring Initializr, kjer boste izbrali Maven projekt z Java in izberite najnovejšo izdajo Spring Boot (2.0.3 v času pisanja tega dokumenta). Dajte svojemu projektu ime skupine, na primer "com.javaworld.webflux", in ime artefakta, na primer "bookservice". Razširite Preklopite na polno različico povezava za prikaz celotnega seznama odvisnosti. Za primer aplikacije izberite naslednje odvisnosti:

  • Splet -> Reaktivni splet: Ta odvisnost vključuje Spring WebFlux.
  • NoSQL -> reaktivni MongoDB: Ta odvisnost vključuje reaktivne gonilnike za MongoDB.
  • NoSQL -> Vdelani MongoDB: Ta odvisnost nam omogoča zagon vdelane različice MongoDB, zato ni treba namestiti ločenega primerka. Običajno se to uporablja za testiranje, vendar ga bomo vključili v našo izdajo, da se izognemo namestitvi MongoDB.
  • Jedro -> Lombok: Uporaba Lomboka ni obvezna, ker je ne potrebujete za izdelavo aplikacije Spring WebFlux. Prednost uporabe projekta Lombok je v tem, da vam omogoča dodajanje pripisov v razrede, ki bodo samodejno generirali getterje in setterje, konstruktorje, hashCode (), enako (), in več.

Ko končate, bi morali videti nekaj podobnega sliki 4.

Steven Haines

Pritisnite Ustvari projekt bo sprožil prenos zip datoteke, ki vsebuje izvorno kodo vašega projekta. Razpakirajte preneseno datoteko in jo odprite v svojem najljubšem IDE-ju. Če uporabljate IntelliJ, izberite mapa in potem Odprtoin se pomaknite do imenika, v katerem je bila prenesena datoteka zip razpakirana.

Ugotovili boste, da je Spring Initializr ustvaril dve pomembni datoteki:

  1. Maven pom.xml datoteka, ki vključuje vse potrebne odvisnosti za aplikacijo.
  2. BookserviceApplication.java, ki je začetni razred Spring Boot za aplikacijo.

Seznam 1 prikazuje vsebino ustvarjene datoteke pom.xml.

$config[zx-auto] not found$config[zx-overlay] not found