SlideShare a Scribd company logo
1 of 105
Download to read offline
The Value Of Reactive
Stephane Maldini - Reactive Engineering @ Pivotal
@smaldini
The Value Of Reactive
What is it ? Where is the value ?
3
No, I do not have a medium blog
=+
Reactive
Programming
● The next frontier for high-efficiency applications
● Non-blocking and allows for concurrent executions
● Often associated with functional programming
● Have no opinion on async and many flows are totally
synchronous
● Resilient with graceful error handling and interruptions
(producer or consumer related)
Reactive
Programming
● The next frontier for high-efficiency applications
● Non-blocking and allows for concurrent executions
● Often associated with functional programming
● Have no opinion on async and many flows are totally
synchronous
● Resilient with graceful error handling and interruptions
(producer or consumer related)
😴
A reactive API primer
5
@GetMapping("/health")
public Mono<Health> compositeHealth() {
return Mono.zip(
webClient.get()
.uri(“https://alpha-service/health")
.retrieve()
.bodyToMono(Health.class),
webClient.get()
.uri("https://bravo-service/health")
.retrieve()
.bodyToMono(Health.class),
(alpha, bravo) -> composite(alpha, bravo))
.switchIfEmpty(emptyComposite());
}
But, is it only a writing style issue ?
6
Debugging Reactive flows
7
java.lang.RuntimeException: Am I looking like a nice stacktrace friends ?
at io.spring.workshop.tradingservice.TradingCompanyClient.lambda$getTradingCompany$0(TradingCompanyClient.java:38) ~[classes/:na]
at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onNext(FluxPeekFuseable.java:190) ~[reactor-core-3.3.0]
at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1575) ~[reactor-core-3.3.0]
at reactor.core.publisher.MonoFlatMap$FlatMapInner.onNext(MonoFlatMap.java:241) ~[reactor-core-3.3.0]
at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onNext(FluxOnAssembly.java:349) ~[reactor-core-3.3.0]
at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:121) ~[reactor-core-3.3.0]
at reactor.core.publisher.FluxContextStart$ContextStartSubscriber.onNext(FluxContextStart.java:103) ~[reactor-core-3.3.0]
at reactor.core.publisher.FluxMapFuseable$MapFuseableConditionalSubscriber.onNext(FluxMapFuseable.java:287) ~[reactor-core-3.3.0]
at reactor.core.publisher.FluxFilterFuseable$FilterFuseableConditionalSubscriber.onNext(FluxFilterFuseable.java:331) ~[reactor-core-3.3.0]
at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1575) ~[reactor-core-3.3.0]
at reactor.core.publisher.MonoCollectList$MonoCollectListSubscriber.onComplete(MonoCollectList.java:121) ~[reactor-core-3.3.0]
at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:136) ~[reactor-core-3.3.0]
at reactor.core.publisher.FluxPeek$PeekSubscriber.onComplete(FluxPeek.java:252) ~[reactor-core-3.3.0]
at reactor.core.publisher.FluxPeek$PeekSubscriber.onComplete(FluxPeek.java:252) ~[reactor-core-3.3.0]
at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:136) ~[reactor-core-3.3.0]
at reactor.netty.channel.FluxReceive.terminateReceiver(FluxReceive.java:391) ~[reactor-netty-0.9.0]
at reactor.netty.channel.FluxReceive.drainReceiver(FluxReceive.java:197) ~[reactor-netty-0.9.0]
at reactor.netty.channel.FluxReceive.onInboundComplete(FluxReceive.java:338) ~[reactor-netty-0.9.0]
at reactor.netty.channel.ChannelOperations.onInboundComplete(ChannelOperations.java:350) ~[reactor-netty-0.9.0]
at reactor.netty.channel.ChannelOperations.terminate(ChannelOperations.java:399) ~[reactor-netty-0.9.0]
at reactor.netty.http.client.HttpClientOperations.onInboundNext(HttpClientOperations.java:555) ~[reactor-netty-0.9.0]
…
Debugging Reactive flows
7
java.lang.RuntimeException: Am I looking like a nice stacktrace friends ?
at io.spring.workshop.tradingservice.TradingCompanyClient.lambda$getTradingCompany$0(TradingCompanyClient.java:38) ~[classes/:na]
at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onNext(FluxPeekFuseable.java:190) ~[reactor-core-3.3.0]
at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1575) ~[reactor-core-3.3.0]
at reactor.core.publisher.MonoFlatMap$FlatMapInner.onNext(MonoFlatMap.java:241) ~[reactor-core-3.3.0]
at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onNext(FluxOnAssembly.java:349) ~[reactor-core-3.3.0]
at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:121) ~[reactor-core-3.3.0]
at reactor.core.publisher.FluxContextStart$ContextStartSubscriber.onNext(FluxContextStart.java:103) ~[reactor-core-3.3.0]
at reactor.core.publisher.FluxMapFuseable$MapFuseableConditionalSubscriber.onNext(FluxMapFuseable.java:287) ~[reactor-core-3.3.0]
at reactor.core.publisher.FluxFilterFuseable$FilterFuseableConditionalSubscriber.onNext(FluxFilterFuseable.java:331) ~[reactor-core-3.3.0]
at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1575) ~[reactor-core-3.3.0]
at reactor.core.publisher.MonoCollectList$MonoCollectListSubscriber.onComplete(MonoCollectList.java:121) ~[reactor-core-3.3.0]
at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:136) ~[reactor-core-3.3.0]
at reactor.core.publisher.FluxPeek$PeekSubscriber.onComplete(FluxPeek.java:252) ~[reactor-core-3.3.0]
at reactor.core.publisher.FluxPeek$PeekSubscriber.onComplete(FluxPeek.java:252) ~[reactor-core-3.3.0]
at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:136) ~[reactor-core-3.3.0]
at reactor.netty.channel.FluxReceive.terminateReceiver(FluxReceive.java:391) ~[reactor-netty-0.9.0]
at reactor.netty.channel.FluxReceive.drainReceiver(FluxReceive.java:197) ~[reactor-netty-0.9.0]
at reactor.netty.channel.FluxReceive.onInboundComplete(FluxReceive.java:338) ~[reactor-netty-0.9.0]
at reactor.netty.channel.ChannelOperations.onInboundComplete(ChannelOperations.java:350) ~[reactor-netty-0.9.0]
at reactor.netty.channel.ChannelOperations.terminate(ChannelOperations.java:399) ~[reactor-netty-0.9.0]
at reactor.netty.http.client.HttpClientOperations.onInboundNext(HttpClientOperations.java:555) ~[reactor-netty-0.9.0]
…
Debugging Reactive flows
7
java.lang.RuntimeException: Am I looking like a nice stacktrace friends ?
at io.spring.workshop.tradingservice.TradingCompanyClient.lambda$getTradingCompany$0(TradingCompanyClient.java:38) ~[classes/:na]
at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onNext(FluxPeekFuseable.java:190) ~[reactor-core-3.3.0]
at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1575) ~[reactor-core-3.3.0]
at reactor.core.publisher.MonoFlatMap$FlatMapInner.onNext(MonoFlatMap.java:241) ~[reactor-core-3.3.0]
at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onNext(FluxOnAssembly.java:349) ~[reactor-core-3.3.0]
at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:121) ~[reactor-core-3.3.0]
at reactor.core.publisher.FluxContextStart$ContextStartSubscriber.onNext(FluxContextStart.java:103) ~[reactor-core-3.3.0]
at reactor.core.publisher.FluxMapFuseable$MapFuseableConditionalSubscriber.onNext(FluxMapFuseable.java:287) ~[reactor-core-3.3.0]
at reactor.core.publisher.FluxFilterFuseable$FilterFuseableConditionalSubscriber.onNext(FluxFilterFuseable.java:331) ~[reactor-core-3.3.0]
at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1575) ~[reactor-core-3.3.0]
at reactor.core.publisher.MonoCollectList$MonoCollectListSubscriber.onComplete(MonoCollectList.java:121) ~[reactor-core-3.3.0]
at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:136) ~[reactor-core-3.3.0]
at reactor.core.publisher.FluxPeek$PeekSubscriber.onComplete(FluxPeek.java:252) ~[reactor-core-3.3.0]
at reactor.core.publisher.FluxPeek$PeekSubscriber.onComplete(FluxPeek.java:252) ~[reactor-core-3.3.0]
at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:136) ~[reactor-core-3.3.0]
at reactor.netty.channel.FluxReceive.terminateReceiver(FluxReceive.java:391) ~[reactor-netty-0.9.0]
at reactor.netty.channel.FluxReceive.drainReceiver(FluxReceive.java:197) ~[reactor-netty-0.9.0]
at reactor.netty.channel.FluxReceive.onInboundComplete(FluxReceive.java:338) ~[reactor-netty-0.9.0]
at reactor.netty.channel.ChannelOperations.onInboundComplete(ChannelOperations.java:350) ~[reactor-netty-0.9.0]
at reactor.netty.channel.ChannelOperations.terminate(ChannelOperations.java:399) ~[reactor-netty-0.9.0]
at reactor.netty.http.client.HttpClientOperations.onInboundNext(HttpClientOperations.java:555) ~[reactor-netty-0.9.0]
…
You ?
Using blocking code in reactive callbacks
8
TradingCompany tradingCompany = this.restTemplate.exchange(
get("http://localhost:8082/details/{ticker}", ticker),
TradingCompany.class)
.getBody();
Using blocking code in reactive callbacks
9
someMono.doOnSuccess(data -> {
TradingCompany tradingCompany = this.restTemplate.exchange(
get("http://localhost:8082/details/{ticker}", ticker),
TradingCompany.class)
.getBody();
return tradingCompany;
});
Using blocking code in reactive callbacks
9
someMono.doOnSuccess(data -> {
TradingCompany tradingCompany = this.restTemplate.exchange(
get("http://localhost:8082/details/{ticker}", ticker),
TradingCompany.class)
.getBody();
return tradingCompany;
});
💩
10
You
What are you priorities ?
11
What are you priorities ?
12
Time To Market / Dev Productivity
What are you priorities ?
13
Time To Market / Dev Productivity
Day 2 Operations / Observability
What are you priorities ?
14
Time To Market / Dev Productivity
Day 2 Operations / Observability
[…]
What are you priorities ?
15
Time To Market / Dev Productivity
Day 2 Operations / Observability
Running costs / efficiency
[…]
What are you priorities ?
16
Time To Market / Dev Productivity
Day 2 Operations / Observability
Reactive ?Running costs / efficiency
[…]
Give me
17
Reasons
To use this stuff
18
Order(s) of Magnitude 

more efficient
🤑
• Lower Number of processes/threads used by instance
• Lower Memory Pressure and associated costs (Garbage collectors)
• Lower Hardware specification requirements
• Lower Startup time
19
Order(s) of Magnitude 

more efficient
Show me some numbers
20
Order(s) of Magnitude 

more efficient
21
Order(s) of Magnitude 

more efficient
Spring WebFlux.Fn - Reactor Netty - 4 threads
&
Spring MVC - Tomcat - 200 threads
With a simple hello world String rendering
128 / steps up to 4000 20s 20min
22
Order(s) of Magnitude 

more efficient
23
Order(s) of Magnitude 

more efficient MVCWebFlux
24
Order(s) of Magnitude 

more efficient
😎
🤒
25
Order(s) of Magnitude 

more efficient
Moar Old Gen
Moar Young Gen
26
Order(s) of Magnitude 

more efficient
27
Order(s) of Magnitude 

more efficient
x2
28
Order(s) of Magnitude 

more efficient
😎 ⏰
29
Designed for 

connection volume scalability
📱Order(s) of Magnitude 

more efficient
• Lower Number of instances running a same application
• Lower Impact from traffic latency diversity
• Lower Impact from persistent http traffic (websocket, sse, http2…)
30
Designed for 

connection volume scalability
31
Spring WebFlux.Fn - Reactor Netty - 4 threads
&
Spring MVC - Tomcat - 200 threads
With a 100ms delayed hello world String rendering
128 / steps up to 4000 20s 20min
Designed for 

connection volume scalability
Designed for 

connection volume scalability
32
MVC (async)WebFlux
Designed for 

connection volume scalability
33🤢
34
Designed for 

connection volume scalability
35
x4
Designed for 

connection volume scalability
36
⏰⏰
Designed for 

connection volume scalability
How does the response delay impact each model ?
37
Designed for 

connection volume scalability
38
Designed for 

connection volume scalability
WebFlux WebFlux (with response delay)
WebFlux WebFlux (with response delay)
39
Designed for 

connection volume scalability
WebFlux WebFlux (with response delay)
40
Designed for 

connection volume scalability
No major impact from backend delays
41
Designed for 

connection volume scalability
WebMVC (with response delay)WebMVC
42
Designed for 

connection volume scalability
WebMVC (with response delay)WebMVC
Rapidly degrading running conditions
43
Designed for 

connection volume scalability
WebMVC WebMVC (with response delay)
44
Designed for 

connection volume scalability
WebMVC WebMVC (with response delay)
x4 slower due to backend delays
45
Designed for 

connection volume scalability
📱Order(s) of Magnitude 

more efficient
46
Sleep Well,

get less paged
📟
Order(s) of Magnitude 

more efficient Designed for 

connection volume scalability
Sleep Well,

get less paged
• Greater resilience to runtime errors, including memory issues
• Greater availability at any point in time, specially under stress
• Easier resources use modeling
47
Sleep Well,

get less paged
48
Figure 1.a: 

A blocking JVM HTTP server with no flow control
Sleep Well,

get less paged
48
Figure 1.a: 

A blocking JVM HTTP server with no flow control
Sleep Well,

get less paged
Reactive IO allows reading when application capacity permits
49
Sleep Well,

get less paged
Reactive IO only requests application data to write when client capacity permits
50
51
WebFlux WebFlux (with response delay)
Sleep Well,

get less paged
52
WebFlux WebFlux (with response delay)
Very similar resources use profile
Sleep Well,

get less paged
Sleep Well,

get less paged
53
Can reactive programming help with JVM OutOfMemory
exceptions caused by incoming request traffic ?
Sleep Well,

get less paged
• Yes, using a reactive IO runtime, request body overflow is isolated
• Errors are propagated via the reactive flow error route : onError
• Associated connection will usually be closed or a fallback route will be provided
• With a blocking runtime, errors are bubbling up and OutOfMemory will be fatal
• Long JVM pauses will lead to a full app crash or unrecoverable state
54
55
Sleep Well,

get less paged
Order(s) of Magnitude 

more efficient
Designed for 

connection volume scalability
56
Sleep Well,

get less paged
Order(s) of Magnitude 

more efficient
Designed for 

connection volume scalability
Event-Driven
Less Threads - Memory
Start quicker
Improve Latency*
Unlocks hyper concurrency
Connected Experience
Slow/Fast traffic
Near-Always Available
Flow Control
Predictable load
Resilient
57
What do you do with these
qualities ?
🤓
58
Write Any Microservice
Resilient
Smaller resources footprint
Remote calls parallelization
Hedge Clients
Edge API
Available
Traffic control
Volume of Connections
Mobile Backend
Scale even with different traffic latency
Connected experience (notifications…)
Volume of clients
59
Write Any Microservice
Resilient
Smaller resources footprint
Remote calls parallelization
Hedge Clients
Edge API
Available
Traffic control
Volume of Connections
Mobile Backend
Scale even with different traffic latency
Connected experience (notifications…)
Volume of clients
60
Remote calls parallelization
With Spring, you can start writing your app with WebMVC,
introduce WebClient to improve backend calls workflows,
then consider moving to WebFlux
Edge API
Available
Traffic control
Volume of Connections
Mobile Backend
Scale even with different traffic latency
Connected experience (notifications…)
Volume of clients
61
Write an Edge API
Available
Traffic Control
Volume of Connections
Mobile Backend
Scale even with different traffic latency
Connected experience (notifications…)
Volume of clients
62
Write an Edge API
Available
Traffic Control
Volume of Connections
Mobile Backend
Scale even with different traffic latency
Connected experience (notifications…)
Volume of clients
63
Traffic Control
A reactive runtime will isolate ingress/egress traffic latency
and exceptions.
Given this isolation property, a reactive Edge API should
always be able to route traffic, even limit it or short-circuit
when required.
Edge API
Available
Traffic control
Volume of Connections
Mobile Backend
Scale even with different traffic latency
Connected experience (notifications…)
Volume of clients
64
Mobile Backend
Scale with different traffic latency
Connected experience (notifications…)
Volume of clients
65
Mobile IoT Backend
Scale with different traffic latency
Connected experience (notifications…)
Volume of clients
Ok sounds cool, but what about the
developer experience ?
66
😷
67
Error has been observed at the following site(s):
|_ checkpoint ⇢ Handler io.spring.workshop.tradingservice.QuotesController#quotesDetails(String) [DispatcherHandler]
|_ checkpoint ⇢ org.springframework.security.web.server.authorization.AuthorizationWebFilter [DefaultWebFilterChain]
|_ checkpoint ⇢ org.springframework.security.web.server.authorization.ExceptionTranslationWebFilter [DefaultWebFilterChain]
|_ checkpoint ⇢ org.springframework.security.web.server.authentication.logout.LogoutWebFilter [DefaultWebFilterChain]
|_ checkpoint ⇢ org.springframework.security.web.server.savedrequest.ServerRequestCacheWebFilter [DefaultWebFilterChain]
|_ checkpoint ⇢ org.springframework.security.web.server.context.SecurityContextServerWebExchangeWebFilter [DefaultWebFilterChain]
|_ checkpoint ⇢ org.springframework.security.web.server.ui.LogoutPageGeneratingWebFilter [DefaultWebFilterChain]
|_ checkpoint ⇢ org.springframework.security.web.server.ui.LoginPageGeneratingWebFilter [DefaultWebFilterChain]
|_ checkpoint ⇢ org.springframework.security.web.server.authentication.AuthenticationWebFilter [DefaultWebFilterChain]
|_ checkpoint ⇢ org.springframework.security.web.server.authentication.AuthenticationWebFilter [DefaultWebFilterChain]
|_ checkpoint ⇢ org.springframework.security.web.server.context.ReactorContextWebFilter [DefaultWebFilterChain]
|_ checkpoint ⇢ org.springframework.security.web.server.csrf.CsrfWebFilter [DefaultWebFilterChain]
|_ checkpoint ⇢ org.springframework.security.web.server.header.HttpHeaderWriterWebFilter [DefaultWebFilterChain]
|_ checkpoint ⇢ org.springframework.security.config.web.server.ServerHttpSecurity$ServerWebExchangeReactorContextWebFilter [DefaultWebFilterChain]
|_ checkpoint ⇢ org.springframework.security.web.server.WebFilterChainProxy [DefaultWebFilterChain]
|_ checkpoint ⇢ org.springframework.boot.web.reactive.filter.OrderedHiddenHttpMethodFilter [DefaultWebFilterChain]
|_ checkpoint ⇢ org.springframework.boot.actuate.metrics.web.reactive.server.MetricsWebFilter [DefaultWebFilterChain]
|_ checkpoint ⇢ HTTP GET "/quotes/summary/MSFT" [ExceptionHandlingWebHandler]
Exceptions since Spring Framework 5.2
67
Error has been observed at the following site(s):
|_ checkpoint ⇢ Handler io.spring.workshop.tradingservice.QuotesController#quotesDetails(String) [DispatcherHandler]
|_ checkpoint ⇢ org.springframework.security.web.server.authorization.AuthorizationWebFilter [DefaultWebFilterChain]
|_ checkpoint ⇢ org.springframework.security.web.server.authorization.ExceptionTranslationWebFilter [DefaultWebFilterChain]
|_ checkpoint ⇢ org.springframework.security.web.server.authentication.logout.LogoutWebFilter [DefaultWebFilterChain]
|_ checkpoint ⇢ org.springframework.security.web.server.savedrequest.ServerRequestCacheWebFilter [DefaultWebFilterChain]
|_ checkpoint ⇢ org.springframework.security.web.server.context.SecurityContextServerWebExchangeWebFilter [DefaultWebFilterChain]
|_ checkpoint ⇢ org.springframework.security.web.server.ui.LogoutPageGeneratingWebFilter [DefaultWebFilterChain]
|_ checkpoint ⇢ org.springframework.security.web.server.ui.LoginPageGeneratingWebFilter [DefaultWebFilterChain]
|_ checkpoint ⇢ org.springframework.security.web.server.authentication.AuthenticationWebFilter [DefaultWebFilterChain]
|_ checkpoint ⇢ org.springframework.security.web.server.authentication.AuthenticationWebFilter [DefaultWebFilterChain]
|_ checkpoint ⇢ org.springframework.security.web.server.context.ReactorContextWebFilter [DefaultWebFilterChain]
|_ checkpoint ⇢ org.springframework.security.web.server.csrf.CsrfWebFilter [DefaultWebFilterChain]
|_ checkpoint ⇢ org.springframework.security.web.server.header.HttpHeaderWriterWebFilter [DefaultWebFilterChain]
|_ checkpoint ⇢ org.springframework.security.config.web.server.ServerHttpSecurity$ServerWebExchangeReactorContextWebFilter [DefaultWebFilterChain]
|_ checkpoint ⇢ org.springframework.security.web.server.WebFilterChainProxy [DefaultWebFilterChain]
|_ checkpoint ⇢ org.springframework.boot.web.reactive.filter.OrderedHiddenHttpMethodFilter [DefaultWebFilterChain]
|_ checkpoint ⇢ org.springframework.boot.actuate.metrics.web.reactive.server.MetricsWebFilter [DefaultWebFilterChain]
|_ checkpoint ⇢ HTTP GET "/quotes/summary/MSFT" [ExceptionHandlingWebHandler]
Exceptions since Spring Framework 5.2
Actionable stacktraces
68
Error has been observed at the following site(s):
|_ Mono.doOnNext ⇢ at io.spring.workshop.tradingservice.TradingCompanyClient.getTradingCompany(TradingCompanyClient.java:38)
|_ Mono.switchIfEmpty ⇢ at io.spring.workshop.tradingservice.TradingCompanyClient.getTradingCompany(TradingCompanyClient.java:39)
|_ Mono.zipWith ⇢ at io.spring.workshop.tradingservice.QuotesController.quotesDetails(QuotesController.java:39)
|_ Mono.switchIfEmpty ⇢ at org.springframework.http.codec.EncoderHttpMessageWriter.write(EncoderHttpMessageWriter.java:119)
|_ Mono.flatMap ⇢ at org.springframework.http.codec.EncoderHttpMessageWriter.write(EncoderHttpMessageWriter.java:123)
|_ checkpoint ⇢ Handler io.spring.workshop.tradingservice.QuotesController#quotesDetails(String) [DispatcherHandler]
|_ Mono.flatMap ⇢ at org.springframework.web.reactive.DispatcherHandler.lambda$handleResult$5(DispatcherHandler.java:172)
|_ Mono.onErrorResume ⇢ at org.springframework.web.reactive.DispatcherHandler.handleResult(DispatcherHandler.java:171)
|_ Mono.flatMap ⇢ at org.springframework.web.reactive.DispatcherHandler.handle(DispatcherHandler.java:147)
|_ Mono.defer ⇢ at org.springframework.web.server.handler.DefaultWebFilterChain.filter(DefaultWebFilterChain.java:119)
|_ Mono.defer ⇢ at org.springframework.web.server.handler.DefaultWebFilterChain.filter(DefaultWebFilterChain.java:119)
|_ Mono.switchIfEmpty ⇢ at org.springframework.security.web.server.authorization.AuthorizationWebFilter.filter(AuthorizationWebFilter.java:46)
|_ checkpoint ⇢ org.springframework.security.web.server.authorization.AuthorizationWebFilter [DefaultWebFilterChain]
|_ Mono.defer ⇢ at org.springframework.web.server.handler.DefaultWebFilterChain.filter(DefaultWebFilterChain.java:119)
|_ FluxMap$MapSubscriber.onComplete ⇢ at reactor.netty.channel.FluxReceive.terminateReceiver(FluxReceive.java:391)
Exceptions with debug mode enabled
69
Error has been observed at the following site(s):
|_ Mono.doOnNext ⇢ at io.spring.workshop.tradingservice.TradingCompanyClient.getTradingCompany(TradingCompanyClient.java:38)
|_ Mono.switchIfEmpty ⇢ at io.spring.workshop.tradingservice.TradingCompanyClient.getTradingCompany(TradingCompanyClient.java:39)
|_ Mono.zipWith ⇢ at io.spring.workshop.tradingservice.QuotesController.quotesDetails(QuotesController.java:39)
|_ Mono.switchIfEmpty ⇢ at org.springframework.http.codec.EncoderHttpMessageWriter.write(EncoderHttpMessageWriter.java:119)
|_ Mono.flatMap ⇢ at org.springframework.http.codec.EncoderHttpMessageWriter.write(EncoderHttpMessageWriter.java:123)
|_ checkpoint ⇢ Handler io.spring.workshop.tradingservice.QuotesController#quotesDetails(String) [DispatcherHandler]
|_ Mono.flatMap ⇢ at org.springframework.web.reactive.DispatcherHandler.lambda$handleResult$5(DispatcherHandler.java:172)
|_ Mono.onErrorResume ⇢ at org.springframework.web.reactive.DispatcherHandler.handleResult(DispatcherHandler.java:171)
|_ Mono.flatMap ⇢ at org.springframework.web.reactive.DispatcherHandler.handle(DispatcherHandler.java:147)
|_ Mono.defer ⇢ at org.springframework.web.server.handler.DefaultWebFilterChain.filter(DefaultWebFilterChain.java:119)
|_ Mono.defer ⇢ at org.springframework.web.server.handler.DefaultWebFilterChain.filter(DefaultWebFilterChain.java:119)
|_ Mono.switchIfEmpty ⇢ at org.springframework.security.web.server.authorization.AuthorizationWebFilter.filter(AuthorizationWebFilter.java:46)
|_ checkpoint ⇢ org.springframework.security.web.server.authorization.AuthorizationWebFilter [DefaultWebFilterChain]
|_ Mono.defer ⇢ at org.springframework.web.server.handler.DefaultWebFilterChain.filter(DefaultWebFilterChain.java:119)
|_ FluxMap$MapSubscriber.onComplete ⇢ at reactor.netty.channel.FluxReceive.terminateReceiver(FluxReceive.java:391)
Exceptions with debug mode enabled
69
Error has been observed at the following site(s):
|_ Mono.doOnNext ⇢ at io.spring.workshop.tradingservice.TradingCompanyClient.getTradingCompany(TradingCompanyClient.java:38)
|_ Mono.switchIfEmpty ⇢ at io.spring.workshop.tradingservice.TradingCompanyClient.getTradingCompany(TradingCompanyClient.java:39)
|_ Mono.zipWith ⇢ at io.spring.workshop.tradingservice.QuotesController.quotesDetails(QuotesController.java:39)
|_ Mono.switchIfEmpty ⇢ at org.springframework.http.codec.EncoderHttpMessageWriter.write(EncoderHttpMessageWriter.java:119)
|_ Mono.flatMap ⇢ at org.springframework.http.codec.EncoderHttpMessageWriter.write(EncoderHttpMessageWriter.java:123)
|_ checkpoint ⇢ Handler io.spring.workshop.tradingservice.QuotesController#quotesDetails(String) [DispatcherHandler]
|_ Mono.flatMap ⇢ at org.springframework.web.reactive.DispatcherHandler.lambda$handleResult$5(DispatcherHandler.java:172)
|_ Mono.onErrorResume ⇢ at org.springframework.web.reactive.DispatcherHandler.handleResult(DispatcherHandler.java:171)
|_ Mono.flatMap ⇢ at org.springframework.web.reactive.DispatcherHandler.handle(DispatcherHandler.java:147)
|_ Mono.defer ⇢ at org.springframework.web.server.handler.DefaultWebFilterChain.filter(DefaultWebFilterChain.java:119)
|_ Mono.defer ⇢ at org.springframework.web.server.handler.DefaultWebFilterChain.filter(DefaultWebFilterChain.java:119)
|_ Mono.switchIfEmpty ⇢ at org.springframework.security.web.server.authorization.AuthorizationWebFilter.filter(AuthorizationWebFilter.java:46)
|_ checkpoint ⇢ org.springframework.security.web.server.authorization.AuthorizationWebFilter [DefaultWebFilterChain]
|_ Mono.defer ⇢ at org.springframework.web.server.handler.DefaultWebFilterChain.filter(DefaultWebFilterChain.java:119)
|_ FluxMap$MapSubscriber.onComplete ⇢ at reactor.netty.channel.FluxReceive.terminateReceiver(FluxReceive.java:391)
Exceptions with debug mode enabled
Reactive Developer productivity
70
Soon coming as a jvm agent
Mobile Backend
Scale even with different traffic latency
Connected experience (notifications…)
Volume of clients
71
Soon coming as a jvm agent
Mobile Backend
Scale even with different traffic latency
Connected experience (notifications…)
Volume of clients
Speaking of which…
72
BlockHound !
Mobile Backend
Scale even with different traffic latency
Connected experience (notifications…)
Volume of clients
https://github.com/reactor/BlockHound
Detecting blocking code in reactive stack
73
BlockHound.install();
someMono.doOnSuccess(data -> {
TradingCompany tradingCompany = this.restTemplate.exchange(
get("http://localhost:8082/details/{ticker}", ticker),
TradingCompany.class)
.getBody();
return tradingCompany;
});
Detecting blocking code in reactive stack
74
BlockHound.install();
someMono.doOnSuccess(data -> {
TradingCompany tradingCompany = this.restTemplate.exchange(
get("http://localhost:8082/details/{ticker}", ticker),
TradingCompany.class)
.getBody();
return tradingCompany;
});
java.lang.Error:	Blocking	call!	java.net.Socket#connect	
	 at	reactor.blockhound.BlockHound$Builder.lambda$new$0(BlockHound.java:154)	
~[blockhound-1.0.0.jar:na]	
	 at	reactor.blockhound.BlockHound$Builder.lambda$install$8(BlockHound.java:254)	
~[blockhound-1.0.0.jar:na]	
	 at	reactor.blockhound.BlockHoundRuntime.checkBlocking(BlockHoundRuntime.java:43)	
~[blockhound-1.0.0.jar:na]	
	 at	java.net.Socket.connect(Socket.java)	~[na:1.8.0_144]	
	 at	sun.net.NetworkClient.doConnect(NetworkClient.java:180)	~[na:1.8.0_144]	
	 at	sun.net.www.http.HttpClient.openServer(HttpClient.java:463)	~[na:1.8.0_144]	
	 at	sun.net.www.http.HttpClient.openServer(HttpClient.java:558)	~[na:1.8.0_144]	
	 at	sun.net.www.http.HttpClient.<init>(HttpClient.java:242)	~[na:1.8.0_144]	
	 at	sun.net.www.http.HttpClient.New(HttpClient.java:339)	~[na:1.8.0_144]	
	 at	sun.net.www.http.HttpClient.New(HttpClient.java:357)	~[na:1.8.0_144]
Detecting blocking code in reactive stack
74
BlockHound.install();
someMono.doOnSuccess(data -> {
TradingCompany tradingCompany = this.restTemplate.exchange(
get("http://localhost:8082/details/{ticker}", ticker),
TradingCompany.class)
.getBody();
return tradingCompany;
});
java.lang.Error:	Blocking	call!	java.net.Socket#connect	
	 at	reactor.blockhound.BlockHound$Builder.lambda$new$0(BlockHound.java:154)	
~[blockhound-1.0.0.jar:na]	
	 at	reactor.blockhound.BlockHound$Builder.lambda$install$8(BlockHound.java:254)	
~[blockhound-1.0.0.jar:na]	
	 at	reactor.blockhound.BlockHoundRuntime.checkBlocking(BlockHoundRuntime.java:43)	
~[blockhound-1.0.0.jar:na]	
	 at	java.net.Socket.connect(Socket.java)	~[na:1.8.0_144]	
	 at	sun.net.NetworkClient.doConnect(NetworkClient.java:180)	~[na:1.8.0_144]	
	 at	sun.net.www.http.HttpClient.openServer(HttpClient.java:463)	~[na:1.8.0_144]	
	 at	sun.net.www.http.HttpClient.openServer(HttpClient.java:558)	~[na:1.8.0_144]	
	 at	sun.net.www.http.HttpClient.<init>(HttpClient.java:242)	~[na:1.8.0_144]	
	 at	sun.net.www.http.HttpClient.New(HttpClient.java:339)	~[na:1.8.0_144]	
	 at	sun.net.www.http.HttpClient.New(HttpClient.java:357)	~[na:1.8.0_144]
Quickly detect during pre-production
workflows that will likely degrade your
reactive stack experience
More reactive microservices ?
75
80% of apps generated by start.spring.io are using a SQL driver
76
80% of apps generated by start.spring.io are using a SQL driver
77
r2dbc.io
What should I look after I successfully have written my first Reactive apps ?
78
Monitoring with Micrometer
79
micrometer.io
80
Networking with RSocket
rsocket.io
81
Having fun developing with Kotlin
kotlinlang.org
So In Conclusion
82
What are you priorities ?
83
Time To Market / Dev Productivity
Day 2 Operations / Observability
Running costs / efficiency
[…]
What are you priorities ?
83
Time To Market / Dev Productivity
Day 2 Operations / Observability
Running costs / efficiency
[…]
With Reactive
You can actually be more productive in
writing state of the art, scalable
microservices
What are you priorities ?
84
Time To Market / Dev Productivity
Day 2 Operations / Observability
Running costs / efficiency
[…]
What are you priorities ?
84
Time To Market / Dev Productivity
Day 2 Operations / Observability
Running costs / efficiency
[…]
With Reactive
Your Applications are designed to be
resilient under stress and naturally
lower maintenance
What are you priorities ?
85
Time To Market / Dev Productivity
Day 2 Operations / Observability
Running costs / efficiency
[…]
What are you priorities ?
85
Time To Market / Dev Productivity
Day 2 Operations / Observability
Running costs / efficiency
[…]
With Reactive
You run more for less
What are you priorities ?
86
Time To Market / Dev Productivity
Day 2 Operations / Observability
Running costs / efficiency
[…]
87
Establish the right project to experiment
Reactive Programming with
88
Do it progressively, migrate a few dedicated
backend routes then an entire application
You can already parallelize some workloads
even on your blocking stack
89
Qualify a few benefits identified in this session
Establish your own benchmark to verify the
outcome !
90
Use all the developers tools you can to
accelerate your reactive adoption and
build trust
91
Once the learning curve price has been
paid and the benefits realized- it’s usually
difficult to come back to blocking solutions.
92
In fact it’s difficult in today’s world of
distributed systems to not find a reason
for giving a go to any Reactive stack.
93
In fact it’s difficult in today’s world of
distributed systems to not find a reason
for giving a go to any Reactive stack.
It’s just designed for them
THANK YOU
@smaldini
smaldini

More Related Content

What's hot

What's hot (9)

Guava collection-zero-to-hero
Guava collection-zero-to-heroGuava collection-zero-to-hero
Guava collection-zero-to-hero
 
Practical Protocol-Oriented-Programming
Practical Protocol-Oriented-ProgrammingPractical Protocol-Oriented-Programming
Practical Protocol-Oriented-Programming
 
Java Libraries You Can’t Afford to Miss
Java Libraries You Can’t Afford to Miss Java Libraries You Can’t Afford to Miss
Java Libraries You Can’t Afford to Miss
 
Design Summit - Migrating to Ruby 2 - Joe Rafaniello
Design Summit - Migrating to Ruby 2 - Joe RafanielloDesign Summit - Migrating to Ruby 2 - Joe Rafaniello
Design Summit - Migrating to Ruby 2 - Joe Rafaniello
 
Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5
 
Making the Most of Your Gradle Build
Making the Most of Your Gradle BuildMaking the Most of Your Gradle Build
Making the Most of Your Gradle Build
 
Making the most of your gradle build - Gr8Conf 2017
Making the most of your gradle build - Gr8Conf 2017Making the most of your gradle build - Gr8Conf 2017
Making the most of your gradle build - Gr8Conf 2017
 
Making the most of your gradle build - Greach 2017
Making the most of your gradle build - Greach 2017Making the most of your gradle build - Greach 2017
Making the most of your gradle build - Greach 2017
 
REST APIs in Laravel 101
REST APIs in Laravel 101REST APIs in Laravel 101
REST APIs in Laravel 101
 

Similar to The Value of Reactive Design - Stéphane Maldini

Innovation and Security in Ruby on Rails
Innovation and Security in Ruby on RailsInnovation and Security in Ruby on Rails
Innovation and Security in Ruby on Rails
tielefeld
 

Similar to The Value of Reactive Design - Stéphane Maldini (20)

Reactive programming for java developers
Reactive programming for java developersReactive programming for java developers
Reactive programming for java developers
 
What is new in java 8 concurrency
What is new in java 8 concurrencyWhat is new in java 8 concurrency
What is new in java 8 concurrency
 
Building Scalable Stateless Applications with RxJava
Building Scalable Stateless Applications with RxJavaBuilding Scalable Stateless Applications with RxJava
Building Scalable Stateless Applications with RxJava
 
Understanding Reactive Programming
Understanding Reactive ProgrammingUnderstanding Reactive Programming
Understanding Reactive Programming
 
React & The Art of Managing Complexity
React &  The Art of Managing ComplexityReact &  The Art of Managing Complexity
React & The Art of Managing Complexity
 
Don’t be Homer Simpson 
with your Reactor!
 Don’t be Homer Simpson 
with your Reactor! Don’t be Homer Simpson 
with your Reactor!
Don’t be Homer Simpson 
with your Reactor!
 
Mario Fusco - Reactive programming in Java - Codemotion Milan 2017
Mario Fusco - Reactive programming in Java - Codemotion Milan 2017Mario Fusco - Reactive programming in Java - Codemotion Milan 2017
Mario Fusco - Reactive programming in Java - Codemotion Milan 2017
 
Reactive Thinking in Java with RxJava2
Reactive Thinking in Java with RxJava2Reactive Thinking in Java with RxJava2
Reactive Thinking in Java with RxJava2
 
Reactive java programming for the impatient
Reactive java programming for the impatientReactive java programming for the impatient
Reactive java programming for the impatient
 
RxJava2 Slides
RxJava2 SlidesRxJava2 Slides
RxJava2 Slides
 
Reactive Programming in Java and Spring Framework 5
Reactive Programming in Java and Spring Framework 5Reactive Programming in Java and Spring Framework 5
Reactive Programming in Java and Spring Framework 5
 
Innovation and Security in Ruby on Rails
Innovation and Security in Ruby on RailsInnovation and Security in Ruby on Rails
Innovation and Security in Ruby on Rails
 
Code transformation With Spoon
Code transformation With SpoonCode transformation With Spoon
Code transformation With Spoon
 
Progscon 2017: Taming the wild fronteer - Adventures in Clojurescript
Progscon 2017: Taming the wild fronteer - Adventures in ClojurescriptProgscon 2017: Taming the wild fronteer - Adventures in Clojurescript
Progscon 2017: Taming the wild fronteer - Adventures in Clojurescript
 
Reactive programming with examples
Reactive programming with examplesReactive programming with examples
Reactive programming with examples
 
Functional Reactive Endpoints using Spring 5
Functional Reactive Endpoints using Spring 5Functional Reactive Endpoints using Spring 5
Functional Reactive Endpoints using Spring 5
 
ClojureScript - Making Front-End development Fun again - John Stevenson - Cod...
ClojureScript - Making Front-End development Fun again - John Stevenson - Cod...ClojureScript - Making Front-End development Fun again - John Stevenson - Cod...
ClojureScript - Making Front-End development Fun again - John Stevenson - Cod...
 
TYPO3 Flow 2.0 (International PHP Conference 2013)
TYPO3 Flow 2.0 (International PHP Conference 2013)TYPO3 Flow 2.0 (International PHP Conference 2013)
TYPO3 Flow 2.0 (International PHP Conference 2013)
 
An Introduction to Reactive Cocoa
An Introduction to Reactive CocoaAn Introduction to Reactive Cocoa
An Introduction to Reactive Cocoa
 
Reactor spring one2gx_2013_0902-final
Reactor spring one2gx_2013_0902-finalReactor spring one2gx_2013_0902-final
Reactor spring one2gx_2013_0902-final
 

More from VMware Tanzu

More from VMware Tanzu (20)

What AI Means For Your Product Strategy And What To Do About It
What AI Means For Your Product Strategy And What To Do About ItWhat AI Means For Your Product Strategy And What To Do About It
What AI Means For Your Product Strategy And What To Do About It
 
Make the Right Thing the Obvious Thing at Cardinal Health 2023
Make the Right Thing the Obvious Thing at Cardinal Health 2023Make the Right Thing the Obvious Thing at Cardinal Health 2023
Make the Right Thing the Obvious Thing at Cardinal Health 2023
 
Enhancing DevEx and Simplifying Operations at Scale
Enhancing DevEx and Simplifying Operations at ScaleEnhancing DevEx and Simplifying Operations at Scale
Enhancing DevEx and Simplifying Operations at Scale
 
Spring Update | July 2023
Spring Update | July 2023Spring Update | July 2023
Spring Update | July 2023
 
Platforms, Platform Engineering, & Platform as a Product
Platforms, Platform Engineering, & Platform as a ProductPlatforms, Platform Engineering, & Platform as a Product
Platforms, Platform Engineering, & Platform as a Product
 
Building Cloud Ready Apps
Building Cloud Ready AppsBuilding Cloud Ready Apps
Building Cloud Ready Apps
 
Spring Boot 3 And Beyond
Spring Boot 3 And BeyondSpring Boot 3 And Beyond
Spring Boot 3 And Beyond
 
Spring Cloud Gateway - SpringOne Tour 2023 Charles Schwab.pdf
Spring Cloud Gateway - SpringOne Tour 2023 Charles Schwab.pdfSpring Cloud Gateway - SpringOne Tour 2023 Charles Schwab.pdf
Spring Cloud Gateway - SpringOne Tour 2023 Charles Schwab.pdf
 
Simplify and Scale Enterprise Apps in the Cloud | Boston 2023
Simplify and Scale Enterprise Apps in the Cloud | Boston 2023Simplify and Scale Enterprise Apps in the Cloud | Boston 2023
Simplify and Scale Enterprise Apps in the Cloud | Boston 2023
 
Simplify and Scale Enterprise Apps in the Cloud | Seattle 2023
Simplify and Scale Enterprise Apps in the Cloud | Seattle 2023Simplify and Scale Enterprise Apps in the Cloud | Seattle 2023
Simplify and Scale Enterprise Apps in the Cloud | Seattle 2023
 
tanzu_developer_connect.pptx
tanzu_developer_connect.pptxtanzu_developer_connect.pptx
tanzu_developer_connect.pptx
 
Tanzu Virtual Developer Connect Workshop - French
Tanzu Virtual Developer Connect Workshop - FrenchTanzu Virtual Developer Connect Workshop - French
Tanzu Virtual Developer Connect Workshop - French
 
Tanzu Developer Connect Workshop - English
Tanzu Developer Connect Workshop - EnglishTanzu Developer Connect Workshop - English
Tanzu Developer Connect Workshop - English
 
Virtual Developer Connect Workshop - English
Virtual Developer Connect Workshop - EnglishVirtual Developer Connect Workshop - English
Virtual Developer Connect Workshop - English
 
Tanzu Developer Connect - French
Tanzu Developer Connect - FrenchTanzu Developer Connect - French
Tanzu Developer Connect - French
 
Simplify and Scale Enterprise Apps in the Cloud | Dallas 2023
Simplify and Scale Enterprise Apps in the Cloud | Dallas 2023Simplify and Scale Enterprise Apps in the Cloud | Dallas 2023
Simplify and Scale Enterprise Apps in the Cloud | Dallas 2023
 
SpringOne Tour: Deliver 15-Factor Applications on Kubernetes with Spring Boot
SpringOne Tour: Deliver 15-Factor Applications on Kubernetes with Spring BootSpringOne Tour: Deliver 15-Factor Applications on Kubernetes with Spring Boot
SpringOne Tour: Deliver 15-Factor Applications on Kubernetes with Spring Boot
 
SpringOne Tour: The Influential Software Engineer
SpringOne Tour: The Influential Software EngineerSpringOne Tour: The Influential Software Engineer
SpringOne Tour: The Influential Software Engineer
 
SpringOne Tour: Domain-Driven Design: Theory vs Practice
SpringOne Tour: Domain-Driven Design: Theory vs PracticeSpringOne Tour: Domain-Driven Design: Theory vs Practice
SpringOne Tour: Domain-Driven Design: Theory vs Practice
 
SpringOne Tour: Spring Recipes: A Collection of Common-Sense Solutions
SpringOne Tour: Spring Recipes: A Collection of Common-Sense SolutionsSpringOne Tour: Spring Recipes: A Collection of Common-Sense Solutions
SpringOne Tour: Spring Recipes: A Collection of Common-Sense Solutions
 

Recently uploaded

%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
masabamasaba
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
masabamasaba
 
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
masabamasaba
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
VictoriaMetrics
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
masabamasaba
 

Recently uploaded (20)

%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
 
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With SimplicityWSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 
WSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security ProgramWSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security Program
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
 
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
 
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
 
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park %in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
 
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
 
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
 
Architecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastArchitecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the past
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 

The Value of Reactive Design - Stéphane Maldini

  • 1. The Value Of Reactive Stephane Maldini - Reactive Engineering @ Pivotal @smaldini
  • 2. The Value Of Reactive What is it ? Where is the value ?
  • 3. 3 No, I do not have a medium blog =+
  • 4. Reactive Programming ● The next frontier for high-efficiency applications ● Non-blocking and allows for concurrent executions ● Often associated with functional programming ● Have no opinion on async and many flows are totally synchronous ● Resilient with graceful error handling and interruptions (producer or consumer related)
  • 5. Reactive Programming ● The next frontier for high-efficiency applications ● Non-blocking and allows for concurrent executions ● Often associated with functional programming ● Have no opinion on async and many flows are totally synchronous ● Resilient with graceful error handling and interruptions (producer or consumer related) 😴
  • 6. A reactive API primer 5 @GetMapping("/health") public Mono<Health> compositeHealth() { return Mono.zip( webClient.get() .uri(“https://alpha-service/health") .retrieve() .bodyToMono(Health.class), webClient.get() .uri("https://bravo-service/health") .retrieve() .bodyToMono(Health.class), (alpha, bravo) -> composite(alpha, bravo)) .switchIfEmpty(emptyComposite()); }
  • 7. But, is it only a writing style issue ? 6
  • 8. Debugging Reactive flows 7 java.lang.RuntimeException: Am I looking like a nice stacktrace friends ? at io.spring.workshop.tradingservice.TradingCompanyClient.lambda$getTradingCompany$0(TradingCompanyClient.java:38) ~[classes/:na] at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onNext(FluxPeekFuseable.java:190) ~[reactor-core-3.3.0] at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1575) ~[reactor-core-3.3.0] at reactor.core.publisher.MonoFlatMap$FlatMapInner.onNext(MonoFlatMap.java:241) ~[reactor-core-3.3.0] at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onNext(FluxOnAssembly.java:349) ~[reactor-core-3.3.0] at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:121) ~[reactor-core-3.3.0] at reactor.core.publisher.FluxContextStart$ContextStartSubscriber.onNext(FluxContextStart.java:103) ~[reactor-core-3.3.0] at reactor.core.publisher.FluxMapFuseable$MapFuseableConditionalSubscriber.onNext(FluxMapFuseable.java:287) ~[reactor-core-3.3.0] at reactor.core.publisher.FluxFilterFuseable$FilterFuseableConditionalSubscriber.onNext(FluxFilterFuseable.java:331) ~[reactor-core-3.3.0] at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1575) ~[reactor-core-3.3.0] at reactor.core.publisher.MonoCollectList$MonoCollectListSubscriber.onComplete(MonoCollectList.java:121) ~[reactor-core-3.3.0] at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:136) ~[reactor-core-3.3.0] at reactor.core.publisher.FluxPeek$PeekSubscriber.onComplete(FluxPeek.java:252) ~[reactor-core-3.3.0] at reactor.core.publisher.FluxPeek$PeekSubscriber.onComplete(FluxPeek.java:252) ~[reactor-core-3.3.0] at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:136) ~[reactor-core-3.3.0] at reactor.netty.channel.FluxReceive.terminateReceiver(FluxReceive.java:391) ~[reactor-netty-0.9.0] at reactor.netty.channel.FluxReceive.drainReceiver(FluxReceive.java:197) ~[reactor-netty-0.9.0] at reactor.netty.channel.FluxReceive.onInboundComplete(FluxReceive.java:338) ~[reactor-netty-0.9.0] at reactor.netty.channel.ChannelOperations.onInboundComplete(ChannelOperations.java:350) ~[reactor-netty-0.9.0] at reactor.netty.channel.ChannelOperations.terminate(ChannelOperations.java:399) ~[reactor-netty-0.9.0] at reactor.netty.http.client.HttpClientOperations.onInboundNext(HttpClientOperations.java:555) ~[reactor-netty-0.9.0] …
  • 9. Debugging Reactive flows 7 java.lang.RuntimeException: Am I looking like a nice stacktrace friends ? at io.spring.workshop.tradingservice.TradingCompanyClient.lambda$getTradingCompany$0(TradingCompanyClient.java:38) ~[classes/:na] at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onNext(FluxPeekFuseable.java:190) ~[reactor-core-3.3.0] at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1575) ~[reactor-core-3.3.0] at reactor.core.publisher.MonoFlatMap$FlatMapInner.onNext(MonoFlatMap.java:241) ~[reactor-core-3.3.0] at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onNext(FluxOnAssembly.java:349) ~[reactor-core-3.3.0] at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:121) ~[reactor-core-3.3.0] at reactor.core.publisher.FluxContextStart$ContextStartSubscriber.onNext(FluxContextStart.java:103) ~[reactor-core-3.3.0] at reactor.core.publisher.FluxMapFuseable$MapFuseableConditionalSubscriber.onNext(FluxMapFuseable.java:287) ~[reactor-core-3.3.0] at reactor.core.publisher.FluxFilterFuseable$FilterFuseableConditionalSubscriber.onNext(FluxFilterFuseable.java:331) ~[reactor-core-3.3.0] at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1575) ~[reactor-core-3.3.0] at reactor.core.publisher.MonoCollectList$MonoCollectListSubscriber.onComplete(MonoCollectList.java:121) ~[reactor-core-3.3.0] at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:136) ~[reactor-core-3.3.0] at reactor.core.publisher.FluxPeek$PeekSubscriber.onComplete(FluxPeek.java:252) ~[reactor-core-3.3.0] at reactor.core.publisher.FluxPeek$PeekSubscriber.onComplete(FluxPeek.java:252) ~[reactor-core-3.3.0] at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:136) ~[reactor-core-3.3.0] at reactor.netty.channel.FluxReceive.terminateReceiver(FluxReceive.java:391) ~[reactor-netty-0.9.0] at reactor.netty.channel.FluxReceive.drainReceiver(FluxReceive.java:197) ~[reactor-netty-0.9.0] at reactor.netty.channel.FluxReceive.onInboundComplete(FluxReceive.java:338) ~[reactor-netty-0.9.0] at reactor.netty.channel.ChannelOperations.onInboundComplete(ChannelOperations.java:350) ~[reactor-netty-0.9.0] at reactor.netty.channel.ChannelOperations.terminate(ChannelOperations.java:399) ~[reactor-netty-0.9.0] at reactor.netty.http.client.HttpClientOperations.onInboundNext(HttpClientOperations.java:555) ~[reactor-netty-0.9.0] …
  • 10. Debugging Reactive flows 7 java.lang.RuntimeException: Am I looking like a nice stacktrace friends ? at io.spring.workshop.tradingservice.TradingCompanyClient.lambda$getTradingCompany$0(TradingCompanyClient.java:38) ~[classes/:na] at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onNext(FluxPeekFuseable.java:190) ~[reactor-core-3.3.0] at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1575) ~[reactor-core-3.3.0] at reactor.core.publisher.MonoFlatMap$FlatMapInner.onNext(MonoFlatMap.java:241) ~[reactor-core-3.3.0] at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onNext(FluxOnAssembly.java:349) ~[reactor-core-3.3.0] at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:121) ~[reactor-core-3.3.0] at reactor.core.publisher.FluxContextStart$ContextStartSubscriber.onNext(FluxContextStart.java:103) ~[reactor-core-3.3.0] at reactor.core.publisher.FluxMapFuseable$MapFuseableConditionalSubscriber.onNext(FluxMapFuseable.java:287) ~[reactor-core-3.3.0] at reactor.core.publisher.FluxFilterFuseable$FilterFuseableConditionalSubscriber.onNext(FluxFilterFuseable.java:331) ~[reactor-core-3.3.0] at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1575) ~[reactor-core-3.3.0] at reactor.core.publisher.MonoCollectList$MonoCollectListSubscriber.onComplete(MonoCollectList.java:121) ~[reactor-core-3.3.0] at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:136) ~[reactor-core-3.3.0] at reactor.core.publisher.FluxPeek$PeekSubscriber.onComplete(FluxPeek.java:252) ~[reactor-core-3.3.0] at reactor.core.publisher.FluxPeek$PeekSubscriber.onComplete(FluxPeek.java:252) ~[reactor-core-3.3.0] at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:136) ~[reactor-core-3.3.0] at reactor.netty.channel.FluxReceive.terminateReceiver(FluxReceive.java:391) ~[reactor-netty-0.9.0] at reactor.netty.channel.FluxReceive.drainReceiver(FluxReceive.java:197) ~[reactor-netty-0.9.0] at reactor.netty.channel.FluxReceive.onInboundComplete(FluxReceive.java:338) ~[reactor-netty-0.9.0] at reactor.netty.channel.ChannelOperations.onInboundComplete(ChannelOperations.java:350) ~[reactor-netty-0.9.0] at reactor.netty.channel.ChannelOperations.terminate(ChannelOperations.java:399) ~[reactor-netty-0.9.0] at reactor.netty.http.client.HttpClientOperations.onInboundNext(HttpClientOperations.java:555) ~[reactor-netty-0.9.0] … You ?
  • 11. Using blocking code in reactive callbacks 8 TradingCompany tradingCompany = this.restTemplate.exchange( get("http://localhost:8082/details/{ticker}", ticker), TradingCompany.class) .getBody();
  • 12. Using blocking code in reactive callbacks 9 someMono.doOnSuccess(data -> { TradingCompany tradingCompany = this.restTemplate.exchange( get("http://localhost:8082/details/{ticker}", ticker), TradingCompany.class) .getBody(); return tradingCompany; });
  • 13. Using blocking code in reactive callbacks 9 someMono.doOnSuccess(data -> { TradingCompany tradingCompany = this.restTemplate.exchange( get("http://localhost:8082/details/{ticker}", ticker), TradingCompany.class) .getBody(); return tradingCompany; }); 💩
  • 15. What are you priorities ? 11
  • 16. What are you priorities ? 12 Time To Market / Dev Productivity
  • 17. What are you priorities ? 13 Time To Market / Dev Productivity Day 2 Operations / Observability
  • 18. What are you priorities ? 14 Time To Market / Dev Productivity Day 2 Operations / Observability […]
  • 19. What are you priorities ? 15 Time To Market / Dev Productivity Day 2 Operations / Observability Running costs / efficiency […]
  • 20. What are you priorities ? 16 Time To Market / Dev Productivity Day 2 Operations / Observability Reactive ?Running costs / efficiency […]
  • 22. 18 Order(s) of Magnitude 
 more efficient 🤑
  • 23. • Lower Number of processes/threads used by instance • Lower Memory Pressure and associated costs (Garbage collectors) • Lower Hardware specification requirements • Lower Startup time 19 Order(s) of Magnitude 
 more efficient
  • 24. Show me some numbers 20 Order(s) of Magnitude 
 more efficient
  • 25. 21 Order(s) of Magnitude 
 more efficient Spring WebFlux.Fn - Reactor Netty - 4 threads & Spring MVC - Tomcat - 200 threads With a simple hello world String rendering 128 / steps up to 4000 20s 20min
  • 26. 22 Order(s) of Magnitude 
 more efficient
  • 27. 23 Order(s) of Magnitude 
 more efficient MVCWebFlux
  • 28. 24 Order(s) of Magnitude 
 more efficient 😎 🤒
  • 29. 25 Order(s) of Magnitude 
 more efficient Moar Old Gen Moar Young Gen
  • 30. 26 Order(s) of Magnitude 
 more efficient
  • 31. 27 Order(s) of Magnitude 
 more efficient x2
  • 32. 28 Order(s) of Magnitude 
 more efficient 😎 ⏰
  • 33. 29 Designed for 
 connection volume scalability 📱Order(s) of Magnitude 
 more efficient
  • 34. • Lower Number of instances running a same application • Lower Impact from traffic latency diversity • Lower Impact from persistent http traffic (websocket, sse, http2…) 30 Designed for 
 connection volume scalability
  • 35. 31 Spring WebFlux.Fn - Reactor Netty - 4 threads & Spring MVC - Tomcat - 200 threads With a 100ms delayed hello world String rendering 128 / steps up to 4000 20s 20min Designed for 
 connection volume scalability
  • 36. Designed for 
 connection volume scalability 32 MVC (async)WebFlux
  • 37. Designed for 
 connection volume scalability 33🤢
  • 38. 34 Designed for 
 connection volume scalability
  • 39. 35 x4 Designed for 
 connection volume scalability
  • 41. How does the response delay impact each model ? 37 Designed for 
 connection volume scalability
  • 42. 38 Designed for 
 connection volume scalability WebFlux WebFlux (with response delay)
  • 43. WebFlux WebFlux (with response delay) 39 Designed for 
 connection volume scalability
  • 44. WebFlux WebFlux (with response delay) 40 Designed for 
 connection volume scalability No major impact from backend delays
  • 45. 41 Designed for 
 connection volume scalability WebMVC (with response delay)WebMVC
  • 46. 42 Designed for 
 connection volume scalability WebMVC (with response delay)WebMVC Rapidly degrading running conditions
  • 47. 43 Designed for 
 connection volume scalability WebMVC WebMVC (with response delay)
  • 48. 44 Designed for 
 connection volume scalability WebMVC WebMVC (with response delay) x4 slower due to backend delays
  • 49. 45 Designed for 
 connection volume scalability 📱Order(s) of Magnitude 
 more efficient
  • 50. 46 Sleep Well,
 get less paged 📟 Order(s) of Magnitude 
 more efficient Designed for 
 connection volume scalability
  • 51. Sleep Well,
 get less paged • Greater resilience to runtime errors, including memory issues • Greater availability at any point in time, specially under stress • Easier resources use modeling 47
  • 52. Sleep Well,
 get less paged 48 Figure 1.a: 
 A blocking JVM HTTP server with no flow control
  • 53. Sleep Well,
 get less paged 48 Figure 1.a: 
 A blocking JVM HTTP server with no flow control
  • 54. Sleep Well,
 get less paged Reactive IO allows reading when application capacity permits 49
  • 55. Sleep Well,
 get less paged Reactive IO only requests application data to write when client capacity permits 50
  • 56. 51 WebFlux WebFlux (with response delay) Sleep Well,
 get less paged
  • 57. 52 WebFlux WebFlux (with response delay) Very similar resources use profile Sleep Well,
 get less paged
  • 58. Sleep Well,
 get less paged 53 Can reactive programming help with JVM OutOfMemory exceptions caused by incoming request traffic ?
  • 59. Sleep Well,
 get less paged • Yes, using a reactive IO runtime, request body overflow is isolated • Errors are propagated via the reactive flow error route : onError • Associated connection will usually be closed or a fallback route will be provided • With a blocking runtime, errors are bubbling up and OutOfMemory will be fatal • Long JVM pauses will lead to a full app crash or unrecoverable state 54
  • 60. 55 Sleep Well,
 get less paged Order(s) of Magnitude 
 more efficient Designed for 
 connection volume scalability
  • 61. 56 Sleep Well,
 get less paged Order(s) of Magnitude 
 more efficient Designed for 
 connection volume scalability Event-Driven Less Threads - Memory Start quicker Improve Latency* Unlocks hyper concurrency Connected Experience Slow/Fast traffic Near-Always Available Flow Control Predictable load Resilient
  • 62. 57 What do you do with these qualities ? 🤓
  • 63. 58 Write Any Microservice Resilient Smaller resources footprint Remote calls parallelization Hedge Clients Edge API Available Traffic control Volume of Connections Mobile Backend Scale even with different traffic latency Connected experience (notifications…) Volume of clients
  • 64. 59 Write Any Microservice Resilient Smaller resources footprint Remote calls parallelization Hedge Clients Edge API Available Traffic control Volume of Connections Mobile Backend Scale even with different traffic latency Connected experience (notifications…) Volume of clients
  • 65. 60 Remote calls parallelization With Spring, you can start writing your app with WebMVC, introduce WebClient to improve backend calls workflows, then consider moving to WebFlux Edge API Available Traffic control Volume of Connections Mobile Backend Scale even with different traffic latency Connected experience (notifications…) Volume of clients
  • 66. 61 Write an Edge API Available Traffic Control Volume of Connections Mobile Backend Scale even with different traffic latency Connected experience (notifications…) Volume of clients
  • 67. 62 Write an Edge API Available Traffic Control Volume of Connections Mobile Backend Scale even with different traffic latency Connected experience (notifications…) Volume of clients
  • 68. 63 Traffic Control A reactive runtime will isolate ingress/egress traffic latency and exceptions. Given this isolation property, a reactive Edge API should always be able to route traffic, even limit it or short-circuit when required. Edge API Available Traffic control Volume of Connections Mobile Backend Scale even with different traffic latency Connected experience (notifications…) Volume of clients
  • 69. 64 Mobile Backend Scale with different traffic latency Connected experience (notifications…) Volume of clients
  • 70. 65 Mobile IoT Backend Scale with different traffic latency Connected experience (notifications…) Volume of clients
  • 71. Ok sounds cool, but what about the developer experience ? 66 😷
  • 72. 67 Error has been observed at the following site(s): |_ checkpoint ⇢ Handler io.spring.workshop.tradingservice.QuotesController#quotesDetails(String) [DispatcherHandler] |_ checkpoint ⇢ org.springframework.security.web.server.authorization.AuthorizationWebFilter [DefaultWebFilterChain] |_ checkpoint ⇢ org.springframework.security.web.server.authorization.ExceptionTranslationWebFilter [DefaultWebFilterChain] |_ checkpoint ⇢ org.springframework.security.web.server.authentication.logout.LogoutWebFilter [DefaultWebFilterChain] |_ checkpoint ⇢ org.springframework.security.web.server.savedrequest.ServerRequestCacheWebFilter [DefaultWebFilterChain] |_ checkpoint ⇢ org.springframework.security.web.server.context.SecurityContextServerWebExchangeWebFilter [DefaultWebFilterChain] |_ checkpoint ⇢ org.springframework.security.web.server.ui.LogoutPageGeneratingWebFilter [DefaultWebFilterChain] |_ checkpoint ⇢ org.springframework.security.web.server.ui.LoginPageGeneratingWebFilter [DefaultWebFilterChain] |_ checkpoint ⇢ org.springframework.security.web.server.authentication.AuthenticationWebFilter [DefaultWebFilterChain] |_ checkpoint ⇢ org.springframework.security.web.server.authentication.AuthenticationWebFilter [DefaultWebFilterChain] |_ checkpoint ⇢ org.springframework.security.web.server.context.ReactorContextWebFilter [DefaultWebFilterChain] |_ checkpoint ⇢ org.springframework.security.web.server.csrf.CsrfWebFilter [DefaultWebFilterChain] |_ checkpoint ⇢ org.springframework.security.web.server.header.HttpHeaderWriterWebFilter [DefaultWebFilterChain] |_ checkpoint ⇢ org.springframework.security.config.web.server.ServerHttpSecurity$ServerWebExchangeReactorContextWebFilter [DefaultWebFilterChain] |_ checkpoint ⇢ org.springframework.security.web.server.WebFilterChainProxy [DefaultWebFilterChain] |_ checkpoint ⇢ org.springframework.boot.web.reactive.filter.OrderedHiddenHttpMethodFilter [DefaultWebFilterChain] |_ checkpoint ⇢ org.springframework.boot.actuate.metrics.web.reactive.server.MetricsWebFilter [DefaultWebFilterChain] |_ checkpoint ⇢ HTTP GET "/quotes/summary/MSFT" [ExceptionHandlingWebHandler] Exceptions since Spring Framework 5.2
  • 73. 67 Error has been observed at the following site(s): |_ checkpoint ⇢ Handler io.spring.workshop.tradingservice.QuotesController#quotesDetails(String) [DispatcherHandler] |_ checkpoint ⇢ org.springframework.security.web.server.authorization.AuthorizationWebFilter [DefaultWebFilterChain] |_ checkpoint ⇢ org.springframework.security.web.server.authorization.ExceptionTranslationWebFilter [DefaultWebFilterChain] |_ checkpoint ⇢ org.springframework.security.web.server.authentication.logout.LogoutWebFilter [DefaultWebFilterChain] |_ checkpoint ⇢ org.springframework.security.web.server.savedrequest.ServerRequestCacheWebFilter [DefaultWebFilterChain] |_ checkpoint ⇢ org.springframework.security.web.server.context.SecurityContextServerWebExchangeWebFilter [DefaultWebFilterChain] |_ checkpoint ⇢ org.springframework.security.web.server.ui.LogoutPageGeneratingWebFilter [DefaultWebFilterChain] |_ checkpoint ⇢ org.springframework.security.web.server.ui.LoginPageGeneratingWebFilter [DefaultWebFilterChain] |_ checkpoint ⇢ org.springframework.security.web.server.authentication.AuthenticationWebFilter [DefaultWebFilterChain] |_ checkpoint ⇢ org.springframework.security.web.server.authentication.AuthenticationWebFilter [DefaultWebFilterChain] |_ checkpoint ⇢ org.springframework.security.web.server.context.ReactorContextWebFilter [DefaultWebFilterChain] |_ checkpoint ⇢ org.springframework.security.web.server.csrf.CsrfWebFilter [DefaultWebFilterChain] |_ checkpoint ⇢ org.springframework.security.web.server.header.HttpHeaderWriterWebFilter [DefaultWebFilterChain] |_ checkpoint ⇢ org.springframework.security.config.web.server.ServerHttpSecurity$ServerWebExchangeReactorContextWebFilter [DefaultWebFilterChain] |_ checkpoint ⇢ org.springframework.security.web.server.WebFilterChainProxy [DefaultWebFilterChain] |_ checkpoint ⇢ org.springframework.boot.web.reactive.filter.OrderedHiddenHttpMethodFilter [DefaultWebFilterChain] |_ checkpoint ⇢ org.springframework.boot.actuate.metrics.web.reactive.server.MetricsWebFilter [DefaultWebFilterChain] |_ checkpoint ⇢ HTTP GET "/quotes/summary/MSFT" [ExceptionHandlingWebHandler] Exceptions since Spring Framework 5.2 Actionable stacktraces
  • 74. 68 Error has been observed at the following site(s): |_ Mono.doOnNext ⇢ at io.spring.workshop.tradingservice.TradingCompanyClient.getTradingCompany(TradingCompanyClient.java:38) |_ Mono.switchIfEmpty ⇢ at io.spring.workshop.tradingservice.TradingCompanyClient.getTradingCompany(TradingCompanyClient.java:39) |_ Mono.zipWith ⇢ at io.spring.workshop.tradingservice.QuotesController.quotesDetails(QuotesController.java:39) |_ Mono.switchIfEmpty ⇢ at org.springframework.http.codec.EncoderHttpMessageWriter.write(EncoderHttpMessageWriter.java:119) |_ Mono.flatMap ⇢ at org.springframework.http.codec.EncoderHttpMessageWriter.write(EncoderHttpMessageWriter.java:123) |_ checkpoint ⇢ Handler io.spring.workshop.tradingservice.QuotesController#quotesDetails(String) [DispatcherHandler] |_ Mono.flatMap ⇢ at org.springframework.web.reactive.DispatcherHandler.lambda$handleResult$5(DispatcherHandler.java:172) |_ Mono.onErrorResume ⇢ at org.springframework.web.reactive.DispatcherHandler.handleResult(DispatcherHandler.java:171) |_ Mono.flatMap ⇢ at org.springframework.web.reactive.DispatcherHandler.handle(DispatcherHandler.java:147) |_ Mono.defer ⇢ at org.springframework.web.server.handler.DefaultWebFilterChain.filter(DefaultWebFilterChain.java:119) |_ Mono.defer ⇢ at org.springframework.web.server.handler.DefaultWebFilterChain.filter(DefaultWebFilterChain.java:119) |_ Mono.switchIfEmpty ⇢ at org.springframework.security.web.server.authorization.AuthorizationWebFilter.filter(AuthorizationWebFilter.java:46) |_ checkpoint ⇢ org.springframework.security.web.server.authorization.AuthorizationWebFilter [DefaultWebFilterChain] |_ Mono.defer ⇢ at org.springframework.web.server.handler.DefaultWebFilterChain.filter(DefaultWebFilterChain.java:119) |_ FluxMap$MapSubscriber.onComplete ⇢ at reactor.netty.channel.FluxReceive.terminateReceiver(FluxReceive.java:391) Exceptions with debug mode enabled
  • 75. 69 Error has been observed at the following site(s): |_ Mono.doOnNext ⇢ at io.spring.workshop.tradingservice.TradingCompanyClient.getTradingCompany(TradingCompanyClient.java:38) |_ Mono.switchIfEmpty ⇢ at io.spring.workshop.tradingservice.TradingCompanyClient.getTradingCompany(TradingCompanyClient.java:39) |_ Mono.zipWith ⇢ at io.spring.workshop.tradingservice.QuotesController.quotesDetails(QuotesController.java:39) |_ Mono.switchIfEmpty ⇢ at org.springframework.http.codec.EncoderHttpMessageWriter.write(EncoderHttpMessageWriter.java:119) |_ Mono.flatMap ⇢ at org.springframework.http.codec.EncoderHttpMessageWriter.write(EncoderHttpMessageWriter.java:123) |_ checkpoint ⇢ Handler io.spring.workshop.tradingservice.QuotesController#quotesDetails(String) [DispatcherHandler] |_ Mono.flatMap ⇢ at org.springframework.web.reactive.DispatcherHandler.lambda$handleResult$5(DispatcherHandler.java:172) |_ Mono.onErrorResume ⇢ at org.springframework.web.reactive.DispatcherHandler.handleResult(DispatcherHandler.java:171) |_ Mono.flatMap ⇢ at org.springframework.web.reactive.DispatcherHandler.handle(DispatcherHandler.java:147) |_ Mono.defer ⇢ at org.springframework.web.server.handler.DefaultWebFilterChain.filter(DefaultWebFilterChain.java:119) |_ Mono.defer ⇢ at org.springframework.web.server.handler.DefaultWebFilterChain.filter(DefaultWebFilterChain.java:119) |_ Mono.switchIfEmpty ⇢ at org.springframework.security.web.server.authorization.AuthorizationWebFilter.filter(AuthorizationWebFilter.java:46) |_ checkpoint ⇢ org.springframework.security.web.server.authorization.AuthorizationWebFilter [DefaultWebFilterChain] |_ Mono.defer ⇢ at org.springframework.web.server.handler.DefaultWebFilterChain.filter(DefaultWebFilterChain.java:119) |_ FluxMap$MapSubscriber.onComplete ⇢ at reactor.netty.channel.FluxReceive.terminateReceiver(FluxReceive.java:391) Exceptions with debug mode enabled
  • 76. 69 Error has been observed at the following site(s): |_ Mono.doOnNext ⇢ at io.spring.workshop.tradingservice.TradingCompanyClient.getTradingCompany(TradingCompanyClient.java:38) |_ Mono.switchIfEmpty ⇢ at io.spring.workshop.tradingservice.TradingCompanyClient.getTradingCompany(TradingCompanyClient.java:39) |_ Mono.zipWith ⇢ at io.spring.workshop.tradingservice.QuotesController.quotesDetails(QuotesController.java:39) |_ Mono.switchIfEmpty ⇢ at org.springframework.http.codec.EncoderHttpMessageWriter.write(EncoderHttpMessageWriter.java:119) |_ Mono.flatMap ⇢ at org.springframework.http.codec.EncoderHttpMessageWriter.write(EncoderHttpMessageWriter.java:123) |_ checkpoint ⇢ Handler io.spring.workshop.tradingservice.QuotesController#quotesDetails(String) [DispatcherHandler] |_ Mono.flatMap ⇢ at org.springframework.web.reactive.DispatcherHandler.lambda$handleResult$5(DispatcherHandler.java:172) |_ Mono.onErrorResume ⇢ at org.springframework.web.reactive.DispatcherHandler.handleResult(DispatcherHandler.java:171) |_ Mono.flatMap ⇢ at org.springframework.web.reactive.DispatcherHandler.handle(DispatcherHandler.java:147) |_ Mono.defer ⇢ at org.springframework.web.server.handler.DefaultWebFilterChain.filter(DefaultWebFilterChain.java:119) |_ Mono.defer ⇢ at org.springframework.web.server.handler.DefaultWebFilterChain.filter(DefaultWebFilterChain.java:119) |_ Mono.switchIfEmpty ⇢ at org.springframework.security.web.server.authorization.AuthorizationWebFilter.filter(AuthorizationWebFilter.java:46) |_ checkpoint ⇢ org.springframework.security.web.server.authorization.AuthorizationWebFilter [DefaultWebFilterChain] |_ Mono.defer ⇢ at org.springframework.web.server.handler.DefaultWebFilterChain.filter(DefaultWebFilterChain.java:119) |_ FluxMap$MapSubscriber.onComplete ⇢ at reactor.netty.channel.FluxReceive.terminateReceiver(FluxReceive.java:391) Exceptions with debug mode enabled Reactive Developer productivity
  • 77. 70 Soon coming as a jvm agent Mobile Backend Scale even with different traffic latency Connected experience (notifications…) Volume of clients
  • 78. 71 Soon coming as a jvm agent Mobile Backend Scale even with different traffic latency Connected experience (notifications…) Volume of clients Speaking of which…
  • 79. 72 BlockHound ! Mobile Backend Scale even with different traffic latency Connected experience (notifications…) Volume of clients https://github.com/reactor/BlockHound
  • 80. Detecting blocking code in reactive stack 73 BlockHound.install(); someMono.doOnSuccess(data -> { TradingCompany tradingCompany = this.restTemplate.exchange( get("http://localhost:8082/details/{ticker}", ticker), TradingCompany.class) .getBody(); return tradingCompany; });
  • 81. Detecting blocking code in reactive stack 74 BlockHound.install(); someMono.doOnSuccess(data -> { TradingCompany tradingCompany = this.restTemplate.exchange( get("http://localhost:8082/details/{ticker}", ticker), TradingCompany.class) .getBody(); return tradingCompany; }); java.lang.Error: Blocking call! java.net.Socket#connect at reactor.blockhound.BlockHound$Builder.lambda$new$0(BlockHound.java:154) ~[blockhound-1.0.0.jar:na] at reactor.blockhound.BlockHound$Builder.lambda$install$8(BlockHound.java:254) ~[blockhound-1.0.0.jar:na] at reactor.blockhound.BlockHoundRuntime.checkBlocking(BlockHoundRuntime.java:43) ~[blockhound-1.0.0.jar:na] at java.net.Socket.connect(Socket.java) ~[na:1.8.0_144] at sun.net.NetworkClient.doConnect(NetworkClient.java:180) ~[na:1.8.0_144] at sun.net.www.http.HttpClient.openServer(HttpClient.java:463) ~[na:1.8.0_144] at sun.net.www.http.HttpClient.openServer(HttpClient.java:558) ~[na:1.8.0_144] at sun.net.www.http.HttpClient.<init>(HttpClient.java:242) ~[na:1.8.0_144] at sun.net.www.http.HttpClient.New(HttpClient.java:339) ~[na:1.8.0_144] at sun.net.www.http.HttpClient.New(HttpClient.java:357) ~[na:1.8.0_144]
  • 82. Detecting blocking code in reactive stack 74 BlockHound.install(); someMono.doOnSuccess(data -> { TradingCompany tradingCompany = this.restTemplate.exchange( get("http://localhost:8082/details/{ticker}", ticker), TradingCompany.class) .getBody(); return tradingCompany; }); java.lang.Error: Blocking call! java.net.Socket#connect at reactor.blockhound.BlockHound$Builder.lambda$new$0(BlockHound.java:154) ~[blockhound-1.0.0.jar:na] at reactor.blockhound.BlockHound$Builder.lambda$install$8(BlockHound.java:254) ~[blockhound-1.0.0.jar:na] at reactor.blockhound.BlockHoundRuntime.checkBlocking(BlockHoundRuntime.java:43) ~[blockhound-1.0.0.jar:na] at java.net.Socket.connect(Socket.java) ~[na:1.8.0_144] at sun.net.NetworkClient.doConnect(NetworkClient.java:180) ~[na:1.8.0_144] at sun.net.www.http.HttpClient.openServer(HttpClient.java:463) ~[na:1.8.0_144] at sun.net.www.http.HttpClient.openServer(HttpClient.java:558) ~[na:1.8.0_144] at sun.net.www.http.HttpClient.<init>(HttpClient.java:242) ~[na:1.8.0_144] at sun.net.www.http.HttpClient.New(HttpClient.java:339) ~[na:1.8.0_144] at sun.net.www.http.HttpClient.New(HttpClient.java:357) ~[na:1.8.0_144] Quickly detect during pre-production workflows that will likely degrade your reactive stack experience
  • 84. 80% of apps generated by start.spring.io are using a SQL driver 76
  • 85. 80% of apps generated by start.spring.io are using a SQL driver 77 r2dbc.io
  • 86. What should I look after I successfully have written my first Reactive apps ? 78
  • 89. 81 Having fun developing with Kotlin kotlinlang.org
  • 91. What are you priorities ? 83 Time To Market / Dev Productivity Day 2 Operations / Observability Running costs / efficiency […]
  • 92. What are you priorities ? 83 Time To Market / Dev Productivity Day 2 Operations / Observability Running costs / efficiency […] With Reactive You can actually be more productive in writing state of the art, scalable microservices
  • 93. What are you priorities ? 84 Time To Market / Dev Productivity Day 2 Operations / Observability Running costs / efficiency […]
  • 94. What are you priorities ? 84 Time To Market / Dev Productivity Day 2 Operations / Observability Running costs / efficiency […] With Reactive Your Applications are designed to be resilient under stress and naturally lower maintenance
  • 95. What are you priorities ? 85 Time To Market / Dev Productivity Day 2 Operations / Observability Running costs / efficiency […]
  • 96. What are you priorities ? 85 Time To Market / Dev Productivity Day 2 Operations / Observability Running costs / efficiency […] With Reactive You run more for less
  • 97. What are you priorities ? 86 Time To Market / Dev Productivity Day 2 Operations / Observability Running costs / efficiency […]
  • 98. 87 Establish the right project to experiment Reactive Programming with
  • 99. 88 Do it progressively, migrate a few dedicated backend routes then an entire application You can already parallelize some workloads even on your blocking stack
  • 100. 89 Qualify a few benefits identified in this session Establish your own benchmark to verify the outcome !
  • 101. 90 Use all the developers tools you can to accelerate your reactive adoption and build trust
  • 102. 91 Once the learning curve price has been paid and the benefits realized- it’s usually difficult to come back to blocking solutions.
  • 103. 92 In fact it’s difficult in today’s world of distributed systems to not find a reason for giving a go to any Reactive stack.
  • 104. 93 In fact it’s difficult in today’s world of distributed systems to not find a reason for giving a go to any Reactive stack. It’s just designed for them