reactive web applications

52
SPRINGONE2GX WASHINGTON, DC Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Reactive Web Applications Stephane Maldini Rossen Stoyanchev

Upload: rossen-stoyanchev

Post on 07-Jan-2017

6.534 views

Category:

Software


1 download

TRANSCRIPT

Page 1: Reactive Web Applications

SPRINGONE2GXWASHINGTON, DC

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Reactive Web ApplicationsStephane Maldini

Rossen Stoyanchev

Page 2: Reactive Web Applications

Unless otherwise indicated these slides are © 2013-2014 Pivotal Software Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

About the Speakers

• Stephane Maldini• Reactor Project Lead• Reactive Streams Spec contributor

• Rossen Stoyanchev• Spring Framework committer• Spring MVC• WebSocket messaging (STOMP, SockJS)

2

Page 3: Reactive Web Applications

Unless otherwise indicated these slides are © 2013-2014 Pivotal Software Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 3

Why are you here ?

Page 4: Reactive Web Applications

Unless otherwise indicated these slides are © 2013-2014 Pivotal Software Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 4

What is Reactive ?

Page 5: Reactive Web Applications

Unless otherwise indicated these slides are © 2013-2014 Pivotal Software Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 5

Why Non Blocking Matters ?

Page 6: Reactive Web Applications

Unless otherwise indicated these slides are © 2013-2014 Pivotal Software Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 6

Non Blocking = Faster ?

Page 7: Reactive Web Applications

Unless otherwise indicated these slides are © 2013-2014 Pivotal Software Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 7

Non Blocking = Internet Scale ?

Page 8: Reactive Web Applications

Unless otherwise indicated these slides are © 2013-2014 Pivotal Software Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 8

Page 9: Reactive Web Applications

Unless otherwise indicated these slides are © 2013-2014 Pivotal Software Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Reactive Web App Stack

9

Page 10: Reactive Web Applications

Unless otherwise indicated these slides are © 2013-2014 Pivotal Software Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Servlet 3.0 Async Requests

• Async HTTP requests have been possible since Servlet 3.0

• Essentially: the ability to get off the Servlet container thread • originated from Jetty continuations, CometD, etc.

• “Live” data in web apps• e.g. HTTP streaming, long polling

• Reduce burden on server thread pool• scatter-gather, external REST APIs, etc

10

Page 11: Reactive Web Applications

Unless otherwise indicated these slides are © 2013-2014 Pivotal Software Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

• A bit quirky, Servlet API wasn’t built for async

• Complex to grasp in its entirety + comes with some caveats• e.g. lack of notification when client goes away

• Spring MVC provides full support for Servlet 3 async requests• alleviates most concerns

• Effectively async can be introduced into existing applications• … and ecosystem of libraries !

Servlet 3.0 Async Requests: the bottom line

11

Page 12: Reactive Web Applications

Unless otherwise indicated these slides are © 2013-2014 Pivotal Software Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Servlet 3.1 Non-Blocking I/O

• Read and write without blocking

• Register ReadListener and WriteListener callbacks• switches to non-blocking mode

• ServletInputStream and ServletOutputStream change behavior

• Must call isReady first before read() or write() • if connection not ready (slow client), callback is scheduled

12

Page 13: Reactive Web Applications

Unless otherwise indicated these slides are © 2013-2014 Pivotal Software Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Servlet 3.1 Non-Blocking: the bottom line

• Carefully designed + it does provide non-blocking capability

• However not easy to use correctly, a number of pitfalls

• Many “innocent” looking parts of Servlet API may lead to blocking• e.g. request.getParameters()

• For a good overview and perspective see Greg Wilkins’ talk• ”Into the Wild with Servlet 3.1 Async I/O”

13

Page 14: Reactive Web Applications

Unless otherwise indicated these slides are © 2013-2014 Pivotal Software Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Reactive Streams Spec for the JVM

• Specification for non-blocking library interop• governs exchange of data across async boundaries

• Collaborative effort• Kaazing, Netflix, Pivotal, RedHat, Twiiter, Typesafe

• Momentum and growing ecosystem of libraries• network, database, etc.

• On path to adoption in JDK 9 java.util.concurrent

14

Page 15: Reactive Web Applications

Unless otherwise indicated these slides are © 2013-2014 Pivotal Software Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 15

onSubscribe

onNext*(onError|onComplete)?

PublisherSubscriber

Subscription

Reactive Streams API

request(n)cancel()

Page 16: Reactive Web Applications

Unless otherwise indicated these slides are © 2013-2014 Pivotal Software Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Reactive Back-Pressure

• A key part of Reactive Streams is back-pressure

• It’s a type of flow control

• Subscribers make requests for additional data

• Publishers abide and produce what has been requested

16

Page 17: Reactive Web Applications

Unless otherwise indicated these slides are © 2013-2014 Pivotal Software Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Reactive Streams for Network I/O

public interface ServerHttpRequest extends HttpRequest {

Publisher<byte[]> getBody();

}

public interface ServerHttpResponse extends HttpMessage {

Publisher<Void> writeWith(Publisher<byte[]> publisher);

}

17

Page 18: Reactive Web Applications

Unless otherwise indicated these slides are © 2013-2014 Pivotal Software Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Instead of...

public interface ServerHttpRequest extends HttpRequest {

InputStream getBody();

}

public interface ServerHttpResponse extends HttpMessage {

OutputStream getBody();

}

18

Page 19: Reactive Web Applications

Unless otherwise indicated these slides are © 2013-2014 Pivotal Software Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Reactive Streams over Servlet Runtime ?

• Servlet 3.1 provides the non-blocking capability

• Reactive Streams provides a non-blocking API with broad industry support

• A single Reactive Streams pipeline• back-pressure through the layers (from DB to Web server)

• Jetty is actively investigating this very option

19

Page 20: Reactive Web Applications

Unless otherwise indicated these slides are © 2013-2014 Pivotal Software Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Reactive Streams and Servlet 4.0 ???

• It is under discussion in the expert group

• It would be great if it did happen

• Potential obstacle is the Java EE 8 - JDK 8 association

• Hopefully not a show-stopper since Reactive Streams is here today

20

Page 21: Reactive Web Applications

Unless otherwise indicated these slides are © 2013-2014 Pivotal Software Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

• Netty was designed from the ground up to be non-blocking

• Easy to translate to Reactive Streams semantics

• Two ongoing experiments• RxNetty• Reactor Net

Reactive Streams Over Netty

21

Page 22: Reactive Web Applications

Unless otherwise indicated these slides are © 2013-2014 Pivotal Software Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Reactive Streams Network I/O

Akka HTTP, Vert.x, Ratpack, Reactor Net, RxNetty*

22

*(via RxJava-ReactiveStreams bridge)

Page 23: Reactive Web Applications

Unless otherwise indicated these slides are © 2013-2014 Pivotal Software Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 23

Netty, Servlet 3.1

Reactive Streams

ReactiveWeb App Stack

Page 24: Reactive Web Applications

Unless otherwise indicated these slides are © 2013-2014 Pivotal Software Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 24

Web Framework

Netty, Servlet 3.1

Reactive Streams

ReactiveWeb App Stack

Page 25: Reactive Web Applications

Unless otherwise indicated these slides are © 2013-2014 Pivotal Software Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 25

Web Framework

Application

Netty, Servlet 3.1

Reactive Streams

ReactiveWeb App Stack

Page 26: Reactive Web Applications

Unless otherwise indicated these slides are © 2013-2014 Pivotal Software Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 26

Web Framework

Application

Netty, Servlet 3.1

Reactive Streams

ReactiveStreams

HTTPDataBroker

ReactiveWeb App Stack

Page 27: Reactive Web Applications

Unless otherwise indicated these slides are © 2013-2014 Pivotal Software Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

?

27

Web Framework

Application

Netty, Servlet 3.1

Reactive Streams

ReactiveStreams

HTTPDataBroker

?

API to compose asynchronous streams?

Page 28: Reactive Web Applications

Unless otherwise indicated these slides are © 2013-2014 Pivotal Software Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Working with Streams

• Non-blocking services return Publisher<T> instead of <T>

• How do you attach further processing?

• Reactive Streams is a callback-based API• becomes very nested quickly

• Need something more declarative• it’s beyond the scope of Reactive Streams

28

Page 29: Reactive Web Applications

Unless otherwise indicated these slides are © 2013-2014 Pivotal Software Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

• Publisher represents a stream of data

• It’s natural to apply operations functional-style• like the Java 8 Stream

• Need API for composing async logic• rise above callbacks

Stream Operations

29

Page 30: Reactive Web Applications

Unless otherwise indicated these slides are © 2013-2014 Pivotal Software Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Reactor Stream

• Project Reactor provides a Stream API

• Reactive Streams Publisher + composable operations

30

Streams.just('a' 'b' 'c') .take(2) .map(Character::toUpperCase) .consume(System.out::println);

Page 31: Reactive Web Applications

Unless otherwise indicated these slides are © 2013-2014 Pivotal Software Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Reactive Extensions (Rx)

• Stream composition API based on Observer pattern• originated at Microsoft, work by Erik Meijer

• Implemented for different languages -- RxJava, RxJS, Rx.NET, …

31

Observable.just('a', 'b', 'c').take(2).map(Character::toUpperCase).subscribe(System.out::println);

Page 32: Reactive Web Applications

Unless otherwise indicated these slides are © 2013-2014 Pivotal Software Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

RxJava and Reactive Streams

• RxJava 1.x predates Reactive Streams and doesn’t implement it directly

• Very similar concepts, different names• Observable-Observer vs Publisher-Subscriber

• RxJava supports “reactive pull” back-pressure

• RxJava 1.x - Reactive Streams bridge

32

Page 33: Reactive Web Applications

Unless otherwise indicated these slides are © 2013-2014 Pivotal Software Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Demo:

HeadFirst

33

Page 34: Reactive Web Applications

Unless otherwise indicated these slides are © 2013-2014 Pivotal Software Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

RxNetty

• RxJava as the reactive bridge to Netty IO operations

• Immediate and embedded client/server for TCP and HTTP

• Decorating IO Read with rx.Observable and applying dynamic pull/push

• Decorating IO Write with rx.Subscriber and requesting more on flush

34

Page 35: Reactive Web Applications

Unless otherwise indicated these slides are © 2013-2014 Pivotal Software Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

RxNetty … what’s up

• RxNetty has introduced Backpressure support in 0.5

• Powered by the backpressure protocol from RxJava

• Overall the API has been heavily lifted toohttps://github.com/ReactiveX/RxNetty/wiki/0.5.x-FAQs

35

Page 36: Reactive Web Applications

Unless otherwise indicated these slides are © 2013-2014 Pivotal Software Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Reactor Net

36

• Reactive Streams as the reactive bridge to Netty and ZeroMQ IO operations

• Immediate and embedded client/server for TCP, UDP and HTTP

• Decorating IO Read with Publisher and applying dynamic pull/push

• Decorating IO Write with Subscriber and requesting more on flush

Page 37: Reactive Web Applications

Unless otherwise indicated these slides are © 2013-2014 Pivotal Software Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Member of the Reactor initiative

• Reactor is a maturing Reactive Streams suite of libraries

• As with a lot of the reactive libraries, observing a rapidly evolving set of API

• Precluded Reactive Streams specification work

• Now evolving and getting ready for Spring 5 Reactive story

projectreactor.io , github.com/reactor

37

Page 38: Reactive Web Applications

Unless otherwise indicated these slides are © 2013-2014 Pivotal Software Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Demo:

Back-Pressure

38

Page 39: Reactive Web Applications

Unless otherwise indicated these slides are © 2013-2014 Pivotal Software Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Async I/O with Reactive Streams

• Never block on Applications Queues : Max(request) == Queue.capacity()

• Keep Reading : Any asynchronous handoff is non-blocking

• Make Writes Quicker : IO operation signals demand on availability

• Optimize hardware resources : Claim bounded memory and cpu

39

Page 40: Reactive Web Applications

Unless otherwise indicated these slides are © 2013-2014 Pivotal Software Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Reactive Read

One read implementation : Publisher stop-read

• Consume NIO Buffers only when requested

• request size is != bytes read

• Application stopping reads propagates back-pressure• server buffers fill• client buffers fill• eventually throttles client

40

Page 41: Reactive Web Applications

Unless otherwise indicated these slides are © 2013-2014 Pivotal Software Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Reactive Write

One write implementation : Subscriber request after flush

• Request after flush indicates availability in write buffer

• Request size is != bytes written

• Write buffers filling naturally propagates back-pressure• buffers fill• no requests• eventually throttles application

41

Page 42: Reactive Web Applications

Unless otherwise indicated these slides are © 2013-2014 Pivotal Software Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Serialization Concerns

• Subscription.request(n)is not absolute ( != bytes number )

• Decoding operations might produce one to many objects• must match subscriber capacity

• Encoding operations might consume one to many byte chunks• must match buffering capacity

• Available serialization libraries not built for chunked streams• Jackson, Kryo, Protobuf, etc.

42

Page 43: Reactive Web Applications

Unless otherwise indicated these slides are © 2013-2014 Pivotal Software Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Demo:

Scatter-gather

43

Page 44: Reactive Web Applications

Unless otherwise indicated these slides are © 2013-2014 Pivotal Software Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Spring Reactive

44

Page 45: Reactive Web Applications

Unless otherwise indicated these slides are © 2013-2014 Pivotal Software Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Spring Reactive

• Experimental work for Spring Framework 5

• Non-blocking runtimes -- Netty, Jetty, Tomcat

• Reactive Streams over network I/O -- RxNetty, Reactor Net

• Spring web processing

45

Page 46: Reactive Web Applications

Unless otherwise indicated these slides are © 2013-2014 Pivotal Software Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

@RequestMapping("/capitalize")@ResponseBodypublic Publisher<Person> capitalize(@RequestBody Publisher<Person> persons) { // … }

46

Reactive Streams Publisher

Page 47: Reactive Web Applications

Unless otherwise indicated these slides are © 2013-2014 Pivotal Software Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

@RequestMapping("/capitalize")@ResponseBodypublic Stream<Person> capitalize(@RequestBody Stream<Person> persons) { return persons.map(person -> { person.setName(person.getName().toUpperCase()); return person; });}

47

Reactor Stream

Page 48: Reactive Web Applications

Unless otherwise indicated these slides are © 2013-2014 Pivotal Software Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

@RequestMapping("/capitalize")@ResponseBodypublic Observable<Person> capitalize(@RequestBody Observable<Person> persons) { return persons.map(person -> { person.setName(person.getName().toUpperCase()); return person; });}

48

RxJava Observable

Page 49: Reactive Web Applications

Unless otherwise indicated these slides are © 2013-2014 Pivotal Software Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

ReactiveX On the Client Side

49

Page 50: Reactive Web Applications

Unless otherwise indicated these slides are © 2013-2014 Pivotal Software Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

RxJSfunction() {

StreamService.connect("stream")

.flatMap(unpackCsv)

.subscribe(updateUI, logError, logComplete);

}

var unpackCsv = function (ev) {

return Rx.Observable.from(ev.data ? ev.data.split("\n") : [])

.filter(discardEmpty)

.map(csvToJson)

}

50

Page 51: Reactive Web Applications

Unless otherwise indicated these slides are © 2013-2014 Pivotal Software Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/

Demo:

RxJS and Ratpack

51

Page 52: Reactive Web Applications

Unless otherwise indicated, these slides are © 2013-2014 Pivotal Software, Inc. and licensed under aCreative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 52

Learn More. Stay Connected.

@springcentral Spring.io/video

Thank You for Listening!

@smaldini / @rstoya05