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 Slide

  2. Reactive Programming
    what is it?

    View Slide

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

    View Slide

  4. Reactive programming
    Who has done it?

    View 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 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 Slide

  7. Spring 5
    WebFlux

    View Slide

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

    View 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 Slide

  10. Non-Blocking
    Event

    Queue
    IO

    Calls
    Schedule
    Schedule
    Callback
    Callback
    Request
    Response
    EVENT

    LOOP

    View 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 Slide

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

    View Slide

  13. Project Reactor
    history

    View 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 Slide

  15. Reactive Manifesto

    View Slide

  16. Reactive Manifesto
    Responsive

    View Slide

  17. Reactive Manifesto
    Responsive
    Resilient

    View Slide

  18. Reactive Manifesto
    Responsive
    Resilient
    Elastic

    View Slide

  19. Reactive Manifesto
    Responsive
    Resilient
    Elastic
    Message Driven

    View 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 Slide

  21. Reactive Streams

    View Slide

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

    View Slide

  23. Reactive Streams

    View Slide

  24. Reactive Streams

    View Slide

  25. Reactive Streams

    View Slide

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

    View 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 Slide

  28. View Slide

  29. View Slide

  30. View Slide

  31. Publisher

    View Slide

  32. Subscriber

    View Slide

  33. Subscription

    View Slide

  34. Processor

    View Slide

  35. Pull?

    View Slide

  36. PUSH!
    Pull?

    View Slide

  37. Iterator Subscriber
    Comparison
    Iterable
    VS
    Publisher

    View Slide

  38. 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 Slide

  39. View Slide

  40. Reactive Streams
    PUBLISHER SUBSCRIBER
    Subscribe then

    request(n) data

    (Backpressure)
    0..N data then

    0..1 (Error | Complete)

    View Slide

  41. View Slide

  42. Reactive Streams implementations

    View Slide

  43. View Slide

  44. View Slide

  45. View Slide

  46. View Slide

  47. 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 Slide

  48. Operators
    work with the stream

    View Slide

  49. View Slide

  50. View Slide

  51. View Slide

  52. View Slide

  53. 5 6 7

    View Slide

  54. 5 6 7
    8 9 10

    View Slide

  55. 5 6 7
    8 9 10
    8 10

    View Slide

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

    View Slide

  57. SUBSCRIBE!
    Nothing happens until you

    View Slide

  58. Function composition

    View Slide

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

    View Slide

  60. Nothing happens until you subscribe
    Assembly Time

    View Slide

  61. Nothing happens until you subscribe
    Execution Time

    View Slide

  62. Assembly time

    View Slide

  63. subscription
    Execution time

    View Slide

  64. AGNOSTIC!
    Reactor is threading

    View Slide

  65. Concurrency
    … but facilitates switching

    View Slide

  66. Schedulers
    elastic, parallel, single, …

    View Slide

  67. publishOn / subscribeOn
    determine threading

    View Slide

  68. publishOn
    switch rest of Flux on a thread

    View Slide

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

    View Slide

  70. 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 Slide

  71. subscribeOn
    make subscription happen on particular thread

    View Slide

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

    View Slide

  73. 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 Slide

  74. and the two together?
    knock yourself out…

    View Slide

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

    View Slide

  76. HARD!
    Async debugging is

    View Slide

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

    View Slide

  78. 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 Slide

  79. Spring WebFlux
    Spring WebFlux vs Spring MVC

    View Slide

  80. Spring WebFlux

    View Slide

  81. Spring 5
    WebFlux

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  85. Network Time Protocol

    View Slide

  86. S1
    S2
    S3

    View Slide

  87. View Slide

  88. 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 Slide

  89. Less than
    ideal network
    —UDP

    View Slide

  90. 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 Slide

  91. Everything is a
    STREAM !!!

    almost

    View Slide

  92. 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 Slide

  93. View Slide

  94. View Slide

  95. testability++
    Reactive approach
    pure functions
    elegant
    concise


    View Slide

  96. Spring 5
    WebFlux

    View Slide

  97. Summarizing
    Reactor

    View Slide

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

    View Slide

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

    View Slide

  100. 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 Slide

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

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

    View Slide

  102. View Slide

  103. View Slide

  104. View Slide

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

    View Slide

  106. Questions with(out) answers

    View Slide

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

    View Slide

  108. Thank you!
    Spring WebFlux
    projectreactor.io

    View Slide