Spring WebClient vs. RestTemplate

REST Top

Ik heb zojuist het nieuwe aangekondigd Leer de lente natuurlijk, gericht op de basisprincipes van Spring 5 en Spring Boot 2:

>> BEKIJK DE CURSUS

1. Inleiding

In deze tutorial gaan we twee van Spring's webclientimplementaties vergelijken: RestTemplate en het reactieve alternatief van de nieuwe Spring 5 Web cliënt.

2. Blokkerende vs. niet-blokkerende client

Het is een algemene vereiste in webtoepassingen om HTTP-oproepen naar andere services te maken. Daarom hebben we een webclienttool nodig.

2.1. RestTemplate Blokkerende client

Spring biedt al een lange tijd aan RestTemplate als abstractie van een webclient. Onder de motorkap, RestTemplate maakt gebruik van de Java Servlet API, die is gebaseerd op het thread-per-request-model.

Dit betekent dat de thread wordt geblokkeerd totdat de webclient het antwoord ontvangt. Het probleem met de blokkeercode is te wijten aan het feit dat elke thread een bepaalde hoeveelheid geheugen en CPU-cycli verbruikt.

Laten we overwegen om veel inkomende verzoeken te hebben, die wachten op een trage service die nodig is om het resultaat te produceren.

Vroeg of laat zullen de verzoeken die wachten op de resultaten zich opstapelen. Bijgevolg zal de applicatie veel threads maken, die de threadpool zullen uitputten of al het beschikbare geheugen in beslag zullen nemen. We kunnen ook prestatievermindering ervaren vanwege de frequente CPU-context (thread) -wisselingen.

2.2. Web cliënt Niet-blokkerende client

Aan de andere kant, Web cliënt maakt gebruik van een asynchrone, niet-blokkerende oplossing van het Spring Reactive-framework.

Terwijl RestTemplate gebruikt de beller-thread voor elke gebeurtenis (HTTP-oproep), Web cliënt zal voor elk evenement zoiets als een "taak" creëren. Achter de schermen zal het Reactive-framework die "taken" in de wachtrij plaatsen en ze alleen uitvoeren als het juiste antwoord beschikbaar is.

Het Reactive-framework maakt gebruik van een gebeurtenisgestuurde architectuur. Het biedt middelen om asynchrone logica samen te stellen via de Reactive Streams API. Als gevolg hiervan kan de reactieve benadering meer logica verwerken terwijl er minder threads en systeembronnen worden gebruikt, vergeleken met de synchrone / blokkeermethode.

Web cliënt maakt deel uit van de Spring WebFlux-bibliotheek. Daarom we kunnen bovendien klantcode schrijven met behulp van een functionele, vloeiende API met reactieve typen (Mono en Flux) als een declaratieve compositie.

3. Vergelijkingsvoorbeeld

Om de verschillen tussen deze twee benaderingen aan te tonen, moeten we prestatietests uitvoeren met veel gelijktijdige clientverzoeken. We zouden een aanzienlijke prestatievermindering zien met de blokkeermethode na een bepaald aantal parallelle clientverzoeken.

Aan de andere kant moet de reactieve / niet-blokkerende methode constante prestaties leveren, ongeacht het aantal verzoeken.

Voor de toepassing van dit artikel, laten we twee REST-eindpunten implementeren, één met RestTemplate en de andere met Web cliënt. Het is hun taak om een ​​andere langzame REST-webservice aan te roepen, die een lijst met tweets retourneert.

Om te beginnen hebben we de Spring Boot WebFlux-starter-afhankelijkheid nodig:

 org.springframework.boot spring-boot-starter-webflux 

Verder is hier ons REST-eindpunt voor trage service:

@GetMapping ("/ slow-service-tweets") privélijst getAllTweets () {Thread.sleep (2000L); // delay return Arrays.asList (nieuwe Tweet ("RestTemplate-regels", "@ user1"), nieuwe Tweet ("WebClient is beter", "@ user2"), nieuwe Tweet ("OK, beide zijn nuttig", "@ user1 ")); }

3.1. Gebruik makend van RestTemplate om een ​​trage service te bellen

Laten we nu een ander REST-eindpunt implementeren dat onze trage service via de webclient zal aanroepen.

Ten eerste gebruiken we RestTemplate:

@GetMapping ("/ tweets-blocking") openbare lijst getTweetsBlocking () {log.info ("Start BLOCKING Controller!"); laatste String uri = getSlowServiceUri (); RestTemplate restTemplate = nieuwe RestTemplate (); ResponseEntity response = restTemplate.exchange (uri, HttpMethod.GET, null, nieuw ParameterizedTypeReference() {}); Lijstresultaat = response.getBody (); result.forEach (tweet -> log.info (tweet.toString ())); log.info ("BLOKKERENDE controller verlaten!"); resultaat teruggeven; }

Wanneer we dit eindpunt noemen, vanwege de synchrone aard van RestTemplate, blokkeert de code het wachten op het antwoord van onze trage service. Pas als het antwoord is ontvangen, wordt de rest van de code in deze methode uitgevoerd. In de logboeken zien we:

BLOCKING Controller starten! Tweet (tekst = RestTemplate-regels, [e-mail beschermd]) Tweet (tekst = WebClient is beter, [e-mail beschermd]) Tweet (tekst = OK, beide zijn handig, [e-mail beveiligd]) BLOKKERENDE controller afsluiten!

3.2. Gebruik makend van Web cliënt om een ​​trage service te bellen

Ten tweede, laten we gebruiken Web cliënt om de trage service te bellen:

@GetMapping (value = "/ tweets-non-blocking", produceert = MediaType.TEXT_EVENT_STREAM_VALUE) public Flux getTweetsNonBlocking () {log.info ("Starten van niet-blokkerende controller!"); Flux tweetFlux = WebClient.create () .get () .uri (getSlowServiceUri ()) .retrieve () .bodyToFlux (Tweet.class); tweetFlux.subscribe (tweet -> log.info (tweet.toString ())); log.info ("De NIET-BLOKKERENDE controller verlaten!"); retourneer tweetFlux; }

In dit geval, Web cliënt geeft een terug Flux uitgever en de uitvoering van de methode wordt voltooid. Zodra het resultaat beschikbaar is, begint de uitgever tweets naar zijn abonnees te sturen. Merk op dat een klant (in dit geval een webbrowser) dit aanroept / tweets-non-blocking endpoint zal ook worden geabonneerd op het geretourneerde Flux voorwerp.

Laten we deze keer het logboek bekijken:

De NIET-BLOKKERENDE controller starten! De NIET-BLOKKERENDE controller verlaten! Tweet (tekst = RestTemplate-regels, [e-mail beschermd]) Tweet (tekst = WebClient is beter, [e-mail beschermd]) Tweet (tekst = OK, beide zijn nuttig, [e-mail beschermd])

Merk op dat deze eindpuntmethode is voltooid voordat het antwoord werd ontvangen.

4. Conclusie

In dit artikel hebben we twee verschillende manieren onderzocht om webclients in het voorjaar te gebruiken.

RestTemplate maakt gebruik van Java Servlet API en is daarom synchroon en blokkerend. Integendeel, Web cliënt is asynchroon en blokkeert de uitvoerende thread niet tijdens het wachten op het antwoord om terug te komen. Pas als het antwoord klaar is, wordt de melding geproduceerd.

RestTemplate wordt nog steeds gebruikt. In sommige gevallen gebruikt de niet-blokkerende benadering veel minder systeembronnen in vergelijking met de blokkerende. Vandaar dat in die gevallen Web cliënt is een keuze die de voorkeur heeft.

Alle codefragmenten die in het artikel worden genoemd, zijn te vinden op GitHub.

REST onder

Ik heb zojuist het nieuwe aangekondigd Leer de lente natuurlijk, gericht op de basisprincipes van Spring 5 en Spring Boot 2:

>> BEKIJK DE CURSUS

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