Programmation réactive
avec Spring 5 et Reactor
Florian Beaufumé
@fbeaufume
11/2017
v1.1
Slide 2
Slide 2 text
Florian Beaufumé
• Architecte logiciel et expert Java
• Freelance
• Brown bag lunch
• @fbeaufume
Slide 3
Slide 3 text
• Montée en charge
• C10K (= 10K connexions)
• Comment supporter
10000 connexions simultanées ?
• Robustesse
• Que faire si la base ou les systèmes tiers
sont (très) lents ?
Objectifs
Server
DB
@fbeaufume
Slide 4
Slide 4 text
• Modèle standard de nos serveurs
• Est bloquant avec pool de thread :
• En charge :
• Multiplier les serveurs ?
• Multiplier les threads ?
Modèle « thread-per-request »
Server
Requests Threads pool
@fbeaufume
Slide 5
Slide 5 text
• Cout mémoire et CPU (context switches)
• Contention
Limitations des threads
Server thread Database
Client
HTTP request
SQL request #1
SQL request #2
@fbeaufume
Slide 6
Slide 6 text
• Montée en charge et robustesse
• Exemples : Node.js, Vert.x, Redis, HAProxy
Modèle non bloquant
Event queue
Events
Event loop
HTTP requests
SQL responses
…
Few worker threads
@fbeaufume
Spring Framework 5
Spring Framework
Tomcat Netty
Reactor
Spring Web MVC Spring WebFlux
Bloquant Réactif
Reactive
Streams
@fbeaufume
Slide 12
Slide 12 text
Ecosystème Spring réactif
Spring Framework 5
Spring Boot 2
Spring Data 2
Spring Security 5
Spring Integration 5
Spring Cloud
@fbeaufume
Slide 13
Slide 13 text
Spring Data 2
@fbeaufume
Slide 14
Slide 14 text
• "Programming with asynchronous data streams"
• Basé sur des étapes asynchrones et non bloquantes
• API orientées callback et/ou déclaratives par composition de fonctions
• Programmation réactive ≈ streams + CompletableFuture + backpressure
• Bénéfices :
• Montée en charge
• Robustesse
Programmation réactive
@fbeaufume
Slide 15
Slide 15 text
• Code
• Logs
Reactor
@fbeaufume
Slide 16
Slide 16 text
Construction
@fbeaufume
Slide 17
Slide 17 text
Opérateurs
@fbeaufume
Slide 18
Slide 18 text
Marble diagrams
Slide 19
Slide 19 text
• Pour donner du contrôle au consommateur sur le producteur
Backpressure
Producer Consumer
Data flow
Data request
@fbeaufume
Slide 20
Slide 20 text
Conversions
@fbeaufume
Slide 21
Slide 21 text
• Cas simple
• Manipulation de l’échelle de temps
Tests avec reactor-test
@fbeaufume
Slide 22
Slide 22 text
• "Standard for asynchronous stream processing with non-blocking
backpressure"
• Implémentations : RxJava, Reactor, Akka Streams, etc.
Reactive streams
@fbeaufume
Slide 23
Slide 23 text
Comparaison de performance
VS
Bloquant
Réactif
@fbeaufume
Slide 24
Slide 24 text
Scénario
Time
Concurrent
users
2 min
10 sec
http://localhost:8080/pause/1000
@fbeaufume
Temps de réponse
Bloquant Réactif
Moyenne=1462, médiane=1579, σ=297 Moyenne=1036, médiane=1013, σ=59
Slide 27
Slide 27 text
Threads
Bloquant Réactif
@fbeaufume
Slide 28
Slide 28 text
• Syntaxe déroutante
• Commencer par les streams Java 8 et la programmation fonctionnelle
• API contaminante
• Plus facile pour de nouvelles applications ou microservices
Difficultés
@fbeaufume
Slide 29
Slide 29 text
• JDBC pas encore supporté
• Mono.fromCallable(() -> { … }).subscribeOn(Schedulers.elastic())
• Attendre JDK 10
• ThreadLocal perdent leur intérêt (MDC logging par exemple)
• Pas encore de scope request ou session
• myFlux.subscriberContext(Context.of("key", "value"))…
Limitations
@fbeaufume
Slide 30
Slide 30 text
• Supporter une forte charge
• Pour fiabiliser des applications très communicantes
• Microservices
• Applications sensibles à la contention
Cas d’usages
@fbeaufume