Ohjelmointi

Mastering Spring framework 5, Part 2: Spring WebFlux

Spring WebFlux tuo reaktiivisen verkkokehityksen Spring-ekosysteemiin. Tästä artikkelista pääset alkuun reaktiivisten järjestelmien ja reaktiivisen ohjelmoinnin kanssa Springin kanssa. Ensin saat selville, miksi reaktiiviset järjestelmät ovat tärkeitä ja miten ne pannaan täytäntöön Spring Framework 5: ssä. Sitten saat käytännön johdannon reaktiivisten palvelujen rakentamiseen Spring WebFlux -sovelluksella. Rakennamme ensimmäisen reaktiivisen sovelluksemme käyttämällä merkintöjä. Näytän myös, kuinka voit rakentaa samanlaisen sovelluksen Springin uudemmilla toiminnallisilla ominaisuuksilla.

Kevätoppaat JavaWorldissa

Jos kevätkehys on sinulle uusi, suosittelen aloittamista yhdellä tämän sarjan aikaisemmista opetusohjelmista:

  • Mikä on kevät? Komponenttipohjainen Java-kehitys
  • Mastering Spring framework 5: Spring MVC

Reaktiiviset järjestelmät ja Spring WebFlux

Termi reaktiivinen on tällä hetkellä suosittu kehittäjien ja IT-johtajien keskuudessa, mutta olen huomannut epävarmuutta siitä, mitä se todella tarkoittaa. Reaktiivisten järjestelmien selvittämiseksi on hyödyllistä ymmärtää perusongelma, jonka ne on suunniteltu ratkaisemaan. Tässä osiossa puhutaan reaktiivisista järjestelmistä yleensä ja esitän Reactive Streams API Java-sovelluksille.

Skaalautuvuus kevään MVC: ssä

Kevään MVC on ansainnut paikkansa Java-verkkosovellusten ja verkkopalveluiden rakentamisen parhaiden vaihtoehtojen joukossa. Kuten havaitsimme Mastering Spring framework 5: n osasta 1, Spring MVC integroi saumattomasti merkinnät kevään pohjaisen sovelluksen vankkaan arkkitehtuuriin. Tämä antaa Springille perehtyneille kehittäjille mahdollisuuden rakentaa nopeasti tyydyttäviä, erittäin toimivia verkkosovelluksia. Skaalautuvuus on haaste kevään MVC-sovelluksille. Tämä on ongelma, jonka Spring WebFlux pyrkii ratkaisemaan.

Estäminen vs. estämättömät verkkokehykset

Perinteisissä verkkosovelluksissa, kun verkkopalvelin vastaanottaa pyynnön asiakkaalta, se hyväksyy pyynnön ja sijoittaa sen suoritusjonoon. Suoritusjonon säiealueessa oleva säie vastaanottaa pyynnön, lukee sen syöttöparametrit ja tuottaa vastauksen. Matkan varrella, jos suorituslangan on kutsuttava estävä resurssi - kuten tietokanta, tiedostojärjestelmä tai muu verkkopalvelu -, tämä ketju suorittaa estopyynnön ja odottaa vastausta. Tässä paradigmassa säie estetään tehokkaasti, kunnes ulkoinen resurssi reagoi, mikä aiheuttaa suorituskykyongelmia ja rajoittaa skaalautuvuutta. Näiden ongelmien torjumiseksi kehittäjät luovat suurikokoiset säiejoukot, jotta vaikka toinen säie on estetty, toinen säie voi jatkaa pyyntöjen käsittelyä. Kuvassa 1 on esitetty perinteisen, estävän verkkosovelluksen suoritusvirta.

Steven Haines

Estämättömät verkkokehykset, kuten NodeJS ja Play, käyttävät erilaista lähestymistapaa. Sen sijaan, että suorittaisivat estopyynnön ja odottavat sen valmistumista, he käyttävät ei-estävää I / O: ta. Tässä paradigmassa sovellus suorittaa pyynnön, antaa koodin, joka suoritetaan, kun vastaus palautetaan, ja palauttaa sen jälkeen langan palvelimelle. Kun ulkoinen resurssi palauttaa vastauksen, annettu koodi suoritetaan. Sisäisesti ei-estävät kehykset toimivat tapahtumasilmukan avulla. Silmukan sisällä sovelluskoodi tarjoaa joko soittopyynnön tai tulevaisuuden, joka sisältää koodin suoritettavaksi, kun asynkroninen silmukka on valmis.

Luonnostaan ​​estämättömät kehykset ovat tapahtumavetoinen. Tämä edellyttää erilaista ohjelmointiparadigmaa ja uutta lähestymistapaa siihen, miten koodisi suoritetaan. Kun olet kietonut pään sen ympärille, reaktiivinen ohjelmointi voi johtaa erittäin skaalautuviin sovelluksiin.

Takaisinkutsut, lupaukset ja futuurit

Alkuvuosina JavaScript käsitteli kaikki asynkroniset toiminnot kautta soittopyynnöt. Tässä tilanteessa, kun tapahtuma tapahtuu (esimerkiksi kun vastaus palvelupuhelusta tulee saataville), takaisinsoitto suoritetaan. Vaikka soittopyynnöt ovat edelleen yleisiä, JavaScriptin asynkroniset toiminnot ovat viime aikoina siirtyneet lupauksia. Lupauksilla funktiokutsu palaa välittömästi, ja palauttaa lupauksen tuottaa tulokset myöhemmin. Lupausten sijaan Java toteuttaa samanlaisen paradigman käyttämällä futuurit. Tässä käyttötavassa menetelmä palauttaa tulevaisuuden, jolla on arvo jossakin vaiheessa tulevaisuudessa.

Reaktiivinen ohjelmointi

Olet ehkä kuullut termin reaktiivinen ohjelmointi liittyvät verkkokehityksen kehyksiin ja työkaluihin, mutta mitä se todella tarkoittaa? Termi, jonka olemme oppineet tuntemaan, on peräisin reaktiivisesta manifestista, jossa reaktiivisilla järjestelmillä on neljä perusominaisuutta:

  1. Reaktiiviset järjestelmät ovat reagoiva, mikä tarkoittaa, että he vastaavat oikeaan aikaan kaikissa mahdollisissa olosuhteissa. Ne keskittyvät tarjoamaan nopeat ja yhdenmukaiset vasteajat, luomalla luotettavat ylärajat, jotta ne tarjoavat tasaisen palvelun laadun.
  2. Reaktiiviset järjestelmät ovat joustava, mikä tarkoittaa, että he pysyvät reagoivina epäonnistumisten edessä. Joustavuus saavutetaan replikointitekniikoilla, eristämisellä, eristämisellä ja delegoinnilla. Eristämällä sovelluskomponentit toisistaan, voit estää vikoja ja suojata järjestelmää kokonaisuutena.
  3. Reaktiiviset järjestelmät ovat joustava, mikä tarkoittaa, että he pysyvät reagoivina vaihtelevalla työmäärällä. Tämä saavutetaan skaalaamalla sovelluskomponentit joustavasti vastaamaan nykyistä kysyntää.
  4. Reaktiiviset järjestelmät ovat viestiohjattu, mikä tarkoittaa, että he luottavat asynkroniseen viestien välitykseen komponenttien välillä. Tämän avulla voit luoda löysän kytkennän, eristämisen ja sijainnin läpinäkyvyyden.

Kuvassa 2 on esitetty, kuinka nämä piirteet virtaavat yhteen reaktiivisessa järjestelmässä.

Steven Haines

Reaktiivisen järjestelmän ominaisuudet

Reaktiiviset järjestelmät rakennetaan luomalla eristettyjä komponentteja, jotka kommunikoivat keskenään asynkronisesti ja voivat skaalata nopeasti vastaamaan nykyistä kuormitusta. Komponentit epäonnistuvat edelleen reaktiivisissa järjestelmissä, mutta on olemassa määriteltyjä toimintoja, jotka suoritetaan tämän vian seurauksena, mikä pitää järjestelmän kokonaisuutena toimivana ja reagoivana.

Reaktiivinen manifesti on abstrakti, mutta reaktiivisille sovelluksille on tyypillistä seuraavat komponentit tai tekniikat:

  • Tietovirrat: A virta on ajoissa järjestetty tapahtumasarja, kuten käyttäjän vuorovaikutus, REST-palvelupuhelut, JMS-viestit ja tulokset tietokannasta.
  • Asynkroninen: Datavirtatapahtumat siepataan asynkronisesti ja koodisi määrittää, mitä tehdä, kun tapahtuma lähetetään, kun tapahtuu virhe ja kun tapahtumavirta on valmis.
  • Estämätön: Kun käsittelet tapahtumia, koodisi ei pitäisi estää ja soittaa synkronoituja puheluja. sen sijaan sen pitäisi soittaa asynkronisia puheluita ja vastata, kun näiden puheluiden tulokset palautetaan.
  • Vastapaine: Komponentit hallitsevat tapahtumien määrää ja kuinka usein ne lähetetään. Reaktiivisesti komponenttisi kutsutaan komponentiksi tilaaja ja tapahtumia lähettää a kustantaja. Tämä on tärkeää, koska tilaaja hallitsee saamansa datan määrää eikä siten rasita itseään.
  • Virheilmoitukset: Sen sijaan, että komponentit heittäisivät poikkeuksia, viat lähetetään viesteinä käsittelijätoiminnolle. Poikkeusten heittäminen rikkoo virran, mutta toimintojen määritteleminen virheiden käsittelemiseksi niiden tapahtuessa ei.

Reactive Streams -sovellusliittymä

Uuden Reactive Streams -sovellusliittymän ovat luoneet muun muassa Netflixin, Pivotalin, Lightbendin, RedHatin, Twitterin ja Oraclen insinöörit. Vuonna 2015 julkaistu Reactive Streams -sovellusliittymä on nyt osa Java 9: ​​ää. Se määrittelee neljä käyttöliittymää:

  • Kustantaja: Lähettää tilaajille tapahtumasarjan.
  • Tilaaja: Vastaanottaa ja käsittelee julkaisijan lähettämiä tapahtumia.
  • Tilaus: Määrittelee henkilökohtaisen suhteen julkaisijan ja tilaajan välillä.
  • Suoritin: Edustaa käsittelyvaihetta, joka koostuu sekä tilaajasta että julkaisijasta ja noudattaa molempien sopimuksia.

Kuva 3 esittää julkaisijan, tilaajan ja tilauksen välistä suhdetta.

Steven Haines

Pohjimmiltaan tilaaja luo tilauksen julkaisijalle, ja kun julkaisijalla on käytettävissä tietoja, se lähettää tapahtuman tilaajalle elementtivirran kanssa. Huomaa, että tilaaja hallitsee vastapainetta julkaisijan tilauksensa sisällä.

Nyt kun tiedät vähän reaktiivisista järjestelmistä ja Reactive Streams -sovellusliittymästä, kiinnitämme huomiomme työkaluihin, joita Spring käyttää reaktiivisten järjestelmien toteuttamiseen: Spring WebFlux ja Reactor-kirjasto.

Projektireaktori

Project Reactor on kolmannen osapuolen kehys, joka perustuu Java: n Reactive Streams -määritykseen, jota käytetään rakentamaan estämättömiä verkkosovelluksia. Project Reactor tarjoaa kaksi julkaisijaa, joita käytetään voimakkaasti Spring WebFluxissa:

  • Mono: Palauttaa 0 tai 1 elementin.
  • Flux: Palauttaa vähintään 0 elementtiä. Flux voi olla loputon, mikä tarkoittaa, että se voi edelleen lähettää elementtejä ikuisesti, tai se voi palauttaa sarjan elementtejä ja lähettää sitten ilmoituksen valmistumisesta, kun se on palauttanut kaikki elementit.

Monot ja juoksut ovat käsitteellisesti samanlaisia ​​kuin futuurit, mutta voimakkaampia. Kun kutsut toiminnon, joka palauttaa mono- tai vuon, se palaa välittömästi. Toimintakutsun tulokset toimitetaan sinulle mono- tai flux-yhteyden kautta, kun ne tulevat saataville.

Kevään WebFluxissa soitat reaktiivisiin kirjastoihin, jotka palauttavat monot ja vuot, ja ohjaimesi palauttavat monot ja vuot. Koska nämä palaavat välittömästi, ohjaimesi luopuvat tehokkaasti ketjuistaan ​​ja antavat Reactorin käsittelemään vastauksia asynkronisesti. On tärkeää huomata, että vain reaktiivisten kirjastojen avulla WebFlux-palvelut voivat pysyä reaktiivisina. Jos käytät ei-reaktiivisia kirjastoja, kuten JDBC-puheluita, koodi estää ja odottaa puhelujen päättymistä ennen paluuta.

Reaktiivinen ohjelmointi MongoDB: n kanssa

Tällä hetkellä ei ole paljon reaktiivisia tietokantakirjastoja, joten saatat miettiä, onko käytännöllistä kirjoittaa reaktiivisia palveluita. Hyvä uutinen on, että MongoDB: llä on reaktiivinen tuki ja MySQL: lle ja Postgresille on olemassa muutama kolmannen osapuolen reaktiivinen tietokantaohjain. Kaikissa muissa käyttötapauksissa WebFlux tarjoaa mekanismin JDBC-puheluiden suorittamiseksi reaktiivisella tavalla, vaikkakin käyttämällä toissijaista säiejoukkoa, joka estää JDBC-puhelut.

Aloita Spring WebFluxin käyttö

Ensimmäiseksi ohjeeksi luomme yksinkertaisen kirjapalvelun, joka jatkaa kirjoja MongoDB: lle ja takaisin reaktiivisella tavalla.

Aloita siirtymällä Spring Initializr -kotisivulle, josta valitset a Maven projekti Java ja valitse Spring Bootin uusin julkaisu (2.0.3 tämän kirjoituksen aikaan). Anna projektillesi ryhmän nimi, kuten "com.javaworld.webflux", ja artefaktin nimi, kuten "kirjapalvelu". Laajenna Vaihda täysversioon linkki näyttääksesi täydellisen luettelon riippuvuuksista. Valitse seuraavat riippuvuudet esimerkkisovellukselle:

  • Verkko -> Reaktiivinen verkko: Tämä riippuvuus sisältää Spring WebFluxin.
  • NoSQL -> Reaktiivinen MongoDB: Tämä riippuvuus sisältää MongoDB: n reaktiiviset ohjaimet.
  • NoSQL -> upotettu MongoDB: Tämän riippuvuuden avulla voimme suorittaa upotetun MongoDB-version, joten erillistä instanssia ei tarvitse asentaa. Yleensä tätä käytetään testauksessa, mutta sisällytämme sen julkaisukoodiin välttääksesi MongoDB: n asentamisen.
  • Ydin -> Lombok: Lombokin käyttö on valinnaista, koska et tarvitse sitä Spring WebFlux -sovelluksen rakentamiseen. Project Lombok -palvelun käytön etuna on, että sen avulla voit lisätä merkintöjä luokkiin, jotka tuottavat automaattisesti hahmottimia ja asettajia, rakentajia, hash koodin(), on yhtä suuri (), ja enemmän.

Kun olet valmis, sinun pitäisi nähdä jotain samanlaista kuin kuvassa 4.

Steven Haines

Paina Luo projekti käynnistää zip-tiedoston, joka sisältää projektisi lähdekoodin, lataamisen. Pura ladattu tiedosto ja avaa se suosikki IDE: ssä. Jos käytät IntelliJ: ää, valitse Tiedosto ja sitten Avataja siirry hakemistoon, josta ladattu zip-tiedosto on purettu.

Tulet huomaamaan, että Spring Initializr on luonut kaksi tärkeää tiedostoa:

  1. Maven pom.xml tiedosto, joka sisältää kaikki sovellukselle tarvittavat riippuvuudet.
  2. BookserviceApplication.java, joka on Spring Boot -aloitusluokka sovellukselle.

Listaus 1 näyttää luodun pom.xml-tiedoston sisällön.

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