Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Reactive Spring 5: WebFlux & Reactor

Reactive Spring 5: WebFlux & Reactor

Filip Maelbrancke

October 24, 2018
Tweet

More Decks by Filip Maelbrancke

Other Decks in Programming

Transcript

  1. Spring 5 & Reactive systems
    Project Reactor

    View full-size slide

  2. Reactive Programming
    what is it?

    View full-size slide

  3. Imperative programming
    expression is evaluated once
    value is assigned to a variable
    Reactive programming
    is all about responding to value changes

    View full-size slide

  4. Reactive programming
    Who has done it?

    View full-size slide

  5. You have probably done some reactive programming,
    even if you didn’t realise it at that time:
    - Defining cell values in spreadsheets is similar to
    defining variables in imperative programming
    - Defining cell expressions in spreadsheets is similar
    to defining and operating on reactive types
    Reactive programming

    View full-size slide

  6. Previous example in spreadsheet:
    - assign cell B1 with value of 2
    - assign cell B2 with value of 3
    - assign cell B3 with an expression that
    multiplies B1 value with B2 value
    - when value of either referenced
    component in the expression changes ->
    expression is re-evaluated automagically
    in B3

    View full-size slide

  7. Spring 5
    WebFlux

    View full-size slide

  8. Spring 5
    Embraced different perspective on modern day
    web architecture

    View full-size slide

  9. Spring 5
    Embraced different perspective on modern day
    web architecture
    Spring WebFlux = parallel web architecture next to the servlet-based Spring MVC

    View full-size slide

  10. Non-Blocking
    Event

    Queue
    IO

    Calls
    Schedule
    Schedule
    Callback
    Callback
    Request
    Response
    EVENT

    LOOP

    View full-size slide

  11. Load test
    milliseconds (95th percentile)
    0
    500
    1000
    1500
    2000
    2500
    3000
    3500
    4000
    Concurrent users
    1 10 100 200 500 1000 2000
    Synchronous Reactive
    (500ms backend service)

    View full-size slide

  12. Load test
    requests served per second (parallellism : 100)
    0
    25
    50
    75
    100
    1 8 32 96 768
    Blocking WebFlux (Reactive)

    View full-size slide

  13. Project Reactor
    history

    View full-size slide

  14. Dutch computer scientist
    Erik Meijer
    @Microsoft: C#, LINQ
    Reactive Extensions (RX)
    Currently Director Of Engineering
    @ Facebook
    Bearer of extremely cool tie-dyed
    shirts
    reactivex.io

    View full-size slide

  15. Reactive Manifesto

    View full-size slide

  16. Reactive Manifesto
    Responsive

    View full-size slide

  17. Reactive Manifesto
    Responsive
    Resilient

    View full-size slide

  18. Reactive Manifesto
    Responsive
    Resilient
    Elastic

    View full-size slide

  19. Reactive Manifesto
    Responsive
    Resilient
    Elastic
    Message Driven

    View full-size slide

  20. Reactive Manifesto
    To be reactive, according to The
    Reactive Manifesto, you have to be
    Responsive, Resilient, Elastic, and
    Message Driven.
    The last criteria in this list caused big movement into the asynchronous way of
    communications.

    View full-size slide

  21. Reactive Streams

    View full-size slide

  22. rxjava 1.x
    rx
    reactive streams commons
    rxjava 2.x
    reactive streams
    akka
    reactor 2.x
    reactor 3.x
    spring

    View full-size slide

  23. Reactive Streams

    View full-size slide

  24. Reactive Streams

    View full-size slide

  25. Reactive Streams

    View full-size slide

  26. Reactive Streams
    standard for asynchronous stream
    processing with non-blocking back
    pressure

    View full-size slide

  27. Goal of Reactive Streams
    exchange of data across
    an asynchronous boundary
    while ensuring that the receiving side is not forced to buffer arbitrary amounts of data
    (back pressure)

    View full-size slide

  28. Subscription

    View full-size slide

  29. Iterator Subscriber
    Comparison
    Iterable
    VS
    Publisher

    View full-size slide

  30. Java 9
    2015
    Start
    Reactive Streams 1.0
    2016
    Growth
    Akka, Spring, Pivotal Project
    Reactor, RxJava, MongoDB, Kafka,

    2017
    Java
    The interfaces available in JDK9’s
    java.util.concurrent.Flow, are 1:1
    semantically equivalent

    View full-size slide

  31. Reactive Streams
    PUBLISHER SUBSCRIBER
    Subscribe then

    request(n) data

    (Backpressure)
    0..N data then

    0..1 (Error | Complete)

    View full-size slide

  32. Reactive Streams implementations

    View full-size slide

  33. Reactive core Typed [0|1|N] sequences Non-blocking IPC
    non-blocking foundation

    interacts with Java 8

    functional API, Completable

    Future, Streams
    reactive composable API

    Flux[N]

    Mono[0/1]

    implements Reactive Extensions
    suited for microservices architecture

    backpressure-ready network engines

    (HTTP / Websockets / TCP / UDP)

    reactive encoding/decoding
    Reactor

    View full-size slide

  34. Operators
    work with the stream

    View full-size slide

  35. 5 6 7
    8 9 10
    8 10

    View full-size slide

  36. 5 6 7
    8 9 10
    8 10
    [8,10]

    View full-size slide

  37. SUBSCRIBE!
    Nothing happens until you

    View full-size slide

  38. Function composition

    View full-size slide

  39. Function composition
    map collect
    sorted
    filter
    Original list
    of
    machines
    List of
    model
    names

    View full-size slide

  40. Nothing happens until you subscribe
    Assembly Time

    View full-size slide

  41. Nothing happens until you subscribe
    Execution Time

    View full-size slide

  42. Assembly time

    View full-size slide

  43. subscription
    Execution time

    View full-size slide

  44. AGNOSTIC!
    Reactor is threading

    View full-size slide

  45. Concurrency
    … but facilitates switching

    View full-size slide

  46. Schedulers
    elastic, parallel, single, …

    View full-size slide

  47. publishOn / subscribeOn
    determine threading

    View full-size slide

  48. publishOn
    switch rest of Flux on a thread

    View full-size slide

  49. Flux.op1.op2.publishOn.op3.op4.subscribe

    View full-size slide

  50. Flux.op1.op2.publishOn.op3.op4.subscribe
    1
    2
    Thread calling subscribe()

    is where data flows initially
    1
    After publishOn()
    data flows in Thread 2
    2

    View full-size slide

  51. subscribeOn
    make subscription happen on particular thread

    View full-size slide

  52. Flux.op1.op2.subscribeOn.op3.op4.subscribe

    View full-size slide

  53. Flux.op1.op2.subscribeOn.op3.op4.subscribe
    1
    2
    SubscribeOn() changes where
    sequence subscription happens…
    1
    … which is also
    where data flows initially
    2

    View full-size slide

  54. and the two together?
    knock yourself out…

    View full-size slide

  55. But…
    Frameworks, libraries & operators build on top
    might be opinionated

    View full-size slide

  56. HARD!
    Async debugging is

    View full-size slide

  57. When you shift to asynchronous code, things can get more
    complicated:
    - Ugly stack traces
    - Missing async call chain
    - Stack pollution
    Debugging

    View full-size slide

  58. java.lang.ArithmeticException: / by zero
    at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:107)
    at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:115)
    at reactor.core.publisher.FluxJust$WeakScalarSubscription.request(FluxJust.java:99)
    at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.request(FluxMapFuseable.java:156)
    at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.request(FluxMapFuseable.java:156)
    at reactor.core.publisher.BlockingSingleSubscriber.onSubscribe(BlockingSingleSubscriber.java:49)
    at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onSubscribe(FluxMapFuseable.java:90)
    at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onSubscribe(FluxMapFuseable.java:90)
    at reactor.core.publisher.FluxJust.subscribe(FluxJust.java:70)
    at reactor.core.publisher.FluxMapFuseable.subscribe(FluxMapFuseable.java:63)
    at reactor.core.publisher.FluxMapFuseable.subscribe(FluxMapFuseable.java:63)
    at reactor.core.publisher.Flux.subscribe(Flux.java:6873)
    at mycode.test(MyTest.java:xx)
    Debugging

    View full-size slide

  59. Spring WebFlux
    Spring WebFlux vs Spring MVC

    View full-size slide

  60. Spring WebFlux

    View full-size slide

  61. Spring 5
    WebFlux

    View full-size slide

  62. Servlet Container Netty, Tomcat, Jetty, Undertow
    HTTP / Reactive Streams
    spring-webflux
    Servlet API
    spring-webmvc
    Router Functions
    @Controller, @RequestMapping
    Spring 5

    View full-size slide

  63. Demo
    Spring WebFlux application
    Testing
    Reactive Mongo
    Server-Sent Events

    View full-size slide

  64. Real-life example
    Measuring time with Reactor (NTP)

    View full-size slide

  65. Network Time Protocol

    View full-size slide

  66. SNTP
    time
    Client
    time
    Server
    135ms 137ms
    298ms
    231ms
    t1 t2
    t0 t3
    δ=65ms
    time offset ϑ =
    (t1
    − t0
    ) + (t2
    − t3
    )
    2
    round − trip delay δ = (t3
    − t0
    ) − (t2
    − t1
    )

    View full-size slide

  67. Less than
    ideal network
    —UDP

    View full-size slide

  68. DNS
    Resolution
    IP1
    IP2
    IP3
    IP4
    SNTP Request 1
    NTP
    POOL
    Least
    Roundtrip
    Delay
    SNTP Request 2
    SNTP Request 3
    SNTP Request 4
    SNTP Request 5
    Statistical
    analysis
    Sort by
    clock offset
    + median
    NTP
    Time
    Best
    possible
    approximation
    of
    5
    .
    .
    .

    View full-size slide

  69. Everything is a
    STREAM !!!

    almost

    View full-size slide

  70. DNS
    Resolution
    IP1
    IP2
    IP3
    IP4
    SNTP Request 1
    NTP
    POOL
    Least
    Roundtrip
    Delay
    SNTP Request 2
    SNTP Request 3
    SNTP Request 4
    SNTP Request 5
    Statistical
    analysis
    Sort by
    clock offset
    + median
    NTP
    Time
    Best
    possible
    approximation
    of
    5
    .
    .
    .

    View full-size slide

  71. testability++
    Reactive approach
    pure functions
    elegant
    concise


    View full-size slide

  72. Spring 5
    WebFlux

    View full-size slide

  73. Summarizing
    Reactor

    View full-size slide

  74. Reactor is awesome!
    Asynchronous, non-blocking, reactive data flows
    Event-based programs

    View full-size slide

  75. Reactor is so so…
    Reactor is not the holy grail.

    View full-size slide

  76. Reactor is so so…
    Reactor is not the holy grail.
    Should be used for streams processing, for
    general asynchronous non-blocking
    computation, see coroutines (Spring 5.2+)

    View full-size slide

  77. Reactor has downsides?
    Mindshift (also when testing)

    Debugging & stacktraces are harder
    For the DDD people: (small) pollution of your
    domain with Mono/Flux

    View full-size slide

  78. request / stream finite stream of many
    RSocket
    request / response stream of 1
    fire and forget
    channel
    no response
    bi-directional streams

    View full-size slide

  79. Questions with(out) answers

    View full-size slide

  80. Simplicity does not precede
    complexity but follows it
    Alan Perlis

    View full-size slide

  81. Thank you!
    Spring WebFlux
    projectreactor.io

    View full-size slide