A Lite Rx API for the JVM
-
Upload
spring-by-pivotal -
Category
Technology
-
view
809 -
download
0
Transcript of A Lite Rx API for the JVM
Unless o therw ise ind ica ted , these s l ides are © 2013-2016 P ivo ta l So f tware , Inc . and l i censed under a Creat ive Commons At t r ibu t ion-NonCommerc ia l l i cense: h t tp : / / c rea t ivecommons.org / l i censes /by-nc /3 .0 /
Reactor Core 3.0 A lite Rx API for the JVMby Stéphane Maldini and Sébastien Deleuze
@smaldini / @sdeleuze
Unless o therw ise ind ica ted , these s l ides are © 2013-2016 P ivo ta l So f tware , Inc . and l i censed under a Creat ive Commons At t r ibu t ion-NonCommerc ia l l i cense: h t tp : / / c rea t ivecommons.org / l i censes /by-nc /3 .0 /
Sébastien Deleuze
• Live in Lyon • Remote worker @ Pivotal • Spring Framework and Reactor committer • Works on Spring Framework 5
upcoming Reactive support • Co-worker @ La Cordée • Mix-IT staff member • @sdeleuze on Twitter
2
Unless o therw ise ind ica ted , these s l ides are © 2013-2016 P ivo ta l So f tware , Inc . and l i censed under a Creat ive Commons At t r ibu t ion-NonCommerc ia l l i cense: h t tp : / / c rea t ivecommons.org / l i censes /by-nc /3 .0 /
Stéphane Maldini
• Survive in London • Social Engineering @ • Project Reactor lead • Reactive Streams &
Reactive Streams Commons contributor • Works on Spring Framework 5
upcoming Reactive support • @smaldini on Twitter
3
+
Unless o therw ise ind ica ted , these s l ides are © 2013-2016 P ivo ta l So f tware , Inc . and l i censed under a Creat ive Commons At t r ibu t ion-NonCommerc ia l l i cense: h t tp : / / c rea t ivecommons.org / l i censes /by-nc /3 .0 /
Why going reactive?
• More for scalability and stability than for speed • Use cases:
• Webapp calling remote web services • Lot of slow clients • Big Data • Serve more clients on the same hardware • Event based development (web, mobile)
4
Unless o therw ise ind ica ted , these s l ides are © 2013-2016 P ivo ta l So f tware , Inc . and l i censed under a Creat ive Commons At t r ibu t ion-NonCommerc ia l l i cense: h t tp : / / c rea t ivecommons.org / l i censes /by-nc /3 .0 /
Reactive, what is it?
• Reactive is used to broadly define event-driven systems
• Reactive Manifesto defines qualities of reactive systems
• Reactive programming: moving imperative logic to async, non-blocking, functional-style code, in particular when interacting with external resources
5
More details on http://fr.slideshare.net/StphaneMaldini/intro-to-reactive-programming-52821416
Unless o therw ise ind ica ted , these s l ides are © 2013-2016 P ivo ta l So f tware , Inc . and l i censed under a Creat ive Commons At t r ibu t ion-NonCommerc ia l l i cense: h t tp : / / c rea t ivecommons.org / l i censes /by-nc /3 .0 /
For reactive programming, we need tools : ☐ Reactive Streams ☐ Reactive APIs
6
Unless o therw ise ind ica ted , these s l ides are © 2013-2016 P ivo ta l So f tware , Inc . and l i censed under a Creat ive Commons At t r ibu t ion-NonCommerc ia l l i cense: h t tp : / / c rea t ivecommons.org / l i censes /by-nc /3 .0 /
Reactive Streams
• Reactive Streams is a contract for asynchronous stream processing with non-blocking back pressure
• De facto standard for interop between reactive libraries
• To be included in Java 9 as java.util.concurrent.Flow
7
Unless o therw ise ind ica ted , these s l ides are © 2013-2016 P ivo ta l So f tware , Inc . and l i censed under a Creat ive Commons At t r ibu t ion-NonCommerc ia l l i cense: h t tp : / / c rea t ivecommons.org / l i censes /by-nc /3 .0 /
Reactive Streams principle
• Max(InflightData) <= demand • No data sent without demand • Demand can be unbounded • The recipient controls how much data it will receive
8
Publisher SubscriberData
Demand
Unless o therw ise ind ica ted , these s l ides are © 2013-2016 P ivo ta l So f tware , Inc . and l i censed under a Creat ive Commons At t r ibu t ion-NonCommerc ia l l i cense: h t tp : / / c rea t ivecommons.org / l i censes /by-nc /3 .0 /
Reactive Streams is 4 interfaces (+ a TCK)
9
publicinterfacePublisher<T>{voidsubscribe(Subscriber<?superT>s);}
publicinterfaceSubscriber<T>{voidonSubscribe(Subscriptions);voidonNext(Tt);voidonError(Throwablet);voidonComplete();}
publicinterfaceSubscription{voidrequest(longn);voidcancel();}
publicinterfaceProcessor<T,R>extendsSubscriber<T>,Publisher<R>{}
Unless o therw ise ind ica ted , these s l ides are © 2013-2016 P ivo ta l So f tware , Inc . and l i censed under a Creat ive Commons At t r ibu t ion-NonCommerc ia l l i cense: h t tp : / / c rea t ivecommons.org / l i censes /by-nc /3 .0 /
For reactive programming, we need tools : ☑ Reactive Streams ☐ Reactive APIs
10
Unless o therw ise ind ica ted , these s l ides are © 2013-2016 P ivo ta l So f tware , Inc . and l i censed under a Creat ive Commons At t r ibu t ion-NonCommerc ia l l i cense: h t tp : / / c rea t ivecommons.org / l i censes /by-nc /3 .0 /
Reactive APIs
• Buffer, merge, concatenate, or apply a wide range of transformations to your data
• On the JVM: • Reactor 3.0 is 4th generation* and based on Reactive Streams • RxJava 1.x: 2nd generation* and most used implementation • Akka Stream 2.x: Lightbend 3rd generation* Reactive API
• Also for other languages, for example RxJS, MostJS
11
* Based on http://akarnokd.blogspot.fr/2016/03/operator-fusion-part-1.html
Unless o therw ise ind ica ted , these s l ides are © 2013-2016 P ivo ta l So f tware , Inc . and l i censed under a Creat ive Commons At t r ibu t ion-NonCommerc ia l l i cense: h t tp : / / c rea t ivecommons.org / l i censes /by-nc /3 .0 /
Reactor Core 3.0
• Built with major contributions from Dávid Karnok (RxJava lead) and from some Spring Framework committers
• Natively based on Reactive Streams, RSC* and Java 8+ • Strong focus on efficiency • Powerful Mono API • Ever-improving debugging, logging, testing capabilities
* ReactiveStreamsCommons is a research effort about reactive flows
12
Unless o therw ise ind ica ted , these s l ides are © 2013-2016 P ivo ta l So f tware , Inc . and l i censed under a Creat ive Commons At t r ibu t ion-NonCommerc ia l l i cense: h t tp : / / c rea t ivecommons.org / l i censes /by-nc /3 .0 /
Reactor 3.0 ecosystem
13
Unless o therw ise ind ica ted , these s l ides are © 2013-2016 P ivo ta l So f tware , Inc . and l i censed under a Creat ive Commons At t r ibu t ion-NonCommerc ia l l i cense: h t tp : / / c rea t ivecommons.org / l i censes /by-nc /3 .0 /
Flux (0..N elements) with ReactiveX compliant API
14
Unless o therw ise ind ica ted , these s l ides are © 2013-2016 P ivo ta l So f tware , Inc . and l i censed under a Creat ive Commons At t r ibu t ion-NonCommerc ia l l i cense: h t tp : / / c rea t ivecommons.org / l i censes /by-nc /3 .0 /
Mono (0..1 element)
15
Unless o therw ise ind ica ted , these s l ides are © 2013-2016 P ivo ta l So f tware , Inc . and l i censed under a Creat ive Commons At t r ibu t ion-NonCommerc ia l l i cense: h t tp : / / c rea t ivecommons.org / l i censes /by-nc /3 .0 /
Reactor Web Console
16
Unless o therw ise ind ica ted , these s l ides are © 2013-2016 P ivo ta l So f tware , Inc . and l i censed under a Creat ive Commons At t r ibu t ion-NonCommerc ia l l i cense: h t tp : / / c rea t ivecommons.org / l i censes /by-nc /3 .0 /
Type comparaison
• Lite API • Reactor Flux = 78 methods • RxJava Observable = 337 methods
• Small Jar • reactor-core-2.5.0.M1 = 412 Kbytes • rxjava-1.1.0 = 878 Kbytes • rxjava2-backport-2.0.0 = 1572 Kbytes
• Performance
17
No value Single value Multiple values
Blocking void T Future<T>
Iterable<T> Collection<T> Stream<T>
Non-blocking
CompletableFuture<Void> CompletableFuture<T> CompletableFuture<List<T>>
Reactive Streams
Publisher<Void> Publisher<T> Publisher<T>
RxJava Completable Single<T> Observable<T>
Reactor Mono<Void> Mono<T> Flux<T>
Unless o therw ise ind ica ted , these s l ides are © 2013-2016 P ivo ta l So f tware , Inc . and l i censed under a Creat ive Commons At t r ibu t ion-NonCommerc ia l l i cense: h t tp : / / c rea t ivecommons.org / l i censes /by-nc /3 .0 /
https://spring.io/blog/2016/04/19/understanding-reactive-types
• Lite API • Reactor Flux = 78 methods • RxJava Observable = 337 methods
• Small Jar • reactor-core-2.5.0.M1 = 412 Kbytes • rxjava-1.1.0 = 878 Kbytes • rxjava2-backport-2.0.0 = 1572 Kbytes
• Performance
18
Unless o therw ise ind ica ted , these s l ides are © 2013-2016 P ivo ta l So f tware , Inc . and l i censed under a Creat ive Commons At t r ibu t ion-NonCommerc ia l l i cense: h t tp : / / c rea t ivecommons.org / l i censes /by-nc /3 .0 /
Reactive Spring
• Spring projects are going reactive • Reactor Core is the reactive foundation • RxJava adapters provided • You will be able to choose your web engine:
Tomcat, Jetty, Undertow or Netty • Most impact on Web and Data support (IO intensive)
• Spring Reactive experiment • Spring Reactive Playground sample application
19
Unless o therw ise ind ica ted , these s l ides are © 2013-2016 P ivo ta l So f tware , Inc . and l i censed under a Creat ive Commons At t r ibu t ion-NonCommerc ia l l i cense: h t tp : / / c rea t ivecommons.org / l i censes /by-nc /3 .0 /
Well known Controller example
20
@RestControllerpublicclassUserController{ privateBlockingRepository<User>repository;
@RequestMapping(path="/save-capitalized",method=RequestMethod.POST) publicvoidsaveCapitalized(@RequestBodyList<User>users){ users.forEach(u->u.setName(u.getName().toUpperCase())); repository.save(users); }}
publicinterfaceBlockingRepository<T>{ voidsave(List<T>elements); Iterable<T>findAll();}
Unless o therw ise ind ica ted , these s l ides are © 2013-2016 P ivo ta l So f tware , Inc . and l i censed under a Creat ive Commons At t r ibu t ion-NonCommerc ia l l i cense: h t tp : / / c rea t ivecommons.org / l i censes /by-nc /3 .0 /
Controller with Reactive types
21
@RestControllerpublicclassUserController{
privateReactiveRepository<User>repository;
@RequestMapping(path="/save-capitalized",method=RequestMethod.POST) publicMono<Void>saveCapitalized(@RequestBodyFlux<User>users){ returnrepository.save(users.map(u->newUser(u.getName().toUpperCase())); }}
publicinterfaceReactiveRepository<T>{ Mono<Void>save(Publisher<T>elements);
Flux<T>findAll();}
Unless o therw ise ind ica ted , these s l ides are © 2013-2016 P ivo ta l So f tware , Inc . and l i censed under a Creat ive Commons At t r ibu t ion-NonCommerc ia l l i cense: h t tp : / / c rea t ivecommons.org / l i censes /by-nc /3 .0 /
Blocking vs Reactive: memory consumption
22
Mem
ory
cons
umpt
ion
Time
Blocking Reactive
Unless o therw ise ind ica ted , these s l ides are © 2013-2016 P ivo ta l So f tware , Inc . and l i censed under a Creat ive Commons At t r ibu t ion-NonCommerc ia l l i cense: h t tp : / / c rea t ivecommons.org / l i censes /by-nc /3 .0 /
Blocking vs Reactive: streaming updates
23
Num
ber o
f use
rs s
aved
in
the
data
base
Time
Blocking Reactive
Unless o therw ise ind ica ted , these s l ides are © 2013-2016 P ivo ta l So f tware , Inc . and l i censed under a Creat ive Commons At t r ibu t ion-NonCommerc ia l l i cense: h t tp : / / c rea t ivecommons.org / l i censes /by-nc /3 .0 /
Controller with Reactive return values
24
@RestControllerpublicclassUserController{
privateReactiveRepository<User>repository;
@GetMapping("/") publicFlux<User>findAll(){ returnrepository.findAll(); }}
• Optimized serialization when using Flux instead of List • Also perfectly suitable for Server-Sent Events
Unless o therw ise ind ica ted , these s l ides are © 2013-2016 P ivo ta l So f tware , Inc . and l i censed under a Creat ive Commons At t r ibu t ion-NonCommerc ia l l i cense: h t tp : / / c rea t ivecommons.org / l i censes /by-nc /3 .0 /
Reactive HTTP client with Mono
25
importstaticorg.springframework.web.client.reactive.HttpRequestBuilders.*;importstaticorg.springframework.web.client.reactive.WebResponseExtractors.*;
Mono<Person>result=webClient.perform(get("http://localhost:8080/person").header("X-Test-Header","testvalue").accept(MediaType.APPLICATION_JSON)).extract(body(Person.class));
Unless o therw ise ind ica ted , these s l ides are © 2013-2016 P ivo ta l So f tware , Inc . and l i censed under a Creat ive Commons At t r ibu t ion-NonCommerc ia l l i cense: h t tp : / / c rea t ivecommons.org / l i censes /by-nc /3 .0 /
Reactive HTTP client with Flux
26
importstaticorg.springframework.web.client.reactive.HttpRequestBuilders.*;importstaticorg.springframework.web.client.reactive.WebResponseExtractors.*;
Flux<Person>response=webClient.perform(get("http://localhost:8080/persons").accept(MediaType.APPLICATION_JSON)).extract(bodyStream(Person.class));
Works for: • JSON array [{"foo":"bar"},{"foo":"baz"}]
• JSON Streaming {"foo":"bar"}{"foo":"baz"}
• SSE with something like .extract(sseStream(Person.class))
Unless o therw ise ind ica ted , these s l ides are © 2013-2016 P ivo ta l So f tware , Inc . and l i censed under a Creat ive Commons At t r ibu t ion-NonCommerc ia l l i cense: h t tp : / / c rea t ivecommons.org / l i censes /by-nc /3 .0 /
Perfect fit for Microservices
27
Can handle bidirectional stream processing
Unless o therw ise ind ica ted , these s l ides are © 2013-2016 P ivo ta l So f tware , Inc . and l i censed under a Creat ive Commons At t r ibu t ion-NonCommerc ia l l i cense: h t tp : / / c rea t ivecommons.org / l i censes /by-nc /3 .0 /
Now let’s go to the code!
28
https://github.com/reactor/lite-rx-api-hands-on/!