SlideShare a Scribd company logo
‹#›© 2016 Pivotal Software, Inc. All rights reserved. ‹#›© 2017 Pivotal Software, Inc. All rights reserved.
Spring Framework 5.0
Reactive Web Application
Toshiaki Maki (@making)
2016-05-17 Java Day Tokyo 2017
© 2017 Pivotal Software, Inc. All rights reserved.
Who am I ?
• Toshiaki Maki (@making) https://blog.ik.am
• Sr. Solutions Architect @Pivotal
• Spring Framework 💖
• Cloud Foundry 💖
bit.ly/hajiboot2
© 2017 Pivotal Software, Inc. All rights reserved.
Reactive???
© 2017 Pivotal Software, Inc. All rights reserved.
Reactive???
"In a nutshell reactive programming is about
non-blocking, event-driven applications that
scale with a small number of threads with
backpressure as a key ingredient that remains
to ensure producers do not overwhelm
consumers"
- Rossen Stoyanchev
© 2017 Pivotal Software, Inc. All rights reserved.
Sync / Blocking
https://speakerdeck.com/simonbasle/reactor-3
© 2017 Pivotal Software, Inc. All rights reserved.
Sync / Blocking
https://speakerdeck.com/simonbasle/reactor-3
I/O
main thread processing
resumes
© 2017 Pivotal Software, Inc. All rights reserved.
Sync / Blocking
https://speakerdeck.com/simonbasle/reactor-3
I/O
main thread processing
resumes
😴 app does nothing
© 2017 Pivotal Software, Inc. All rights reserved.
Async & Blocking
https://speakerdeck.com/simonbasle/reactor-3
© 2017 Pivotal Software, Inc. All rights reserved.
Async & Blocking
https://speakerdeck.com/simonbasle/reactor-3
main thread wait &
join
© 2017 Pivotal Software, Inc. All rights reserved.
Async & Blocking
https://speakerdeck.com/simonbasle/reactor-3
main thread wait &
join
complex
new
threads,
costly
© 2017 Pivotal Software, Inc. All rights reserved.
Async & Non-Blocking
© 2017 Pivotal Software, Inc. All rights reserved.
Async & Non-Blocking
https://speakerdeck.com/simonbasle/reactor-3
Event
Loop
chunks
processing
in non-blocking
© 2017 Pivotal Software, Inc. All rights reserved.
Blocking + Thread pools (Servlet)
HTTP request
HTTP response
📖⏳
⚙⏳
✍⏳
Thread
© 2017 Pivotal Software, Inc. All rights reserved.
Non-blocking and event-loop (Netty)
IO Selector Thread Worker Threads
🔄
📖⚙ ⚙ ✍
✍ ⚙ 📖⚙
📖 ✍ ✍ ⚙
⚙ ✍ 📖 📖🔄
🔄
🔄
🔄
© 2017 Pivotal Software, Inc. All rights reserved.
Non-blocking and event-loop (Netty)
IO Selector Thread Worker Threads
🔄
📖⚙ ⚙ ✍
✍ ⚙ 📖⚙
📖 ✍ ✍ ⚙
⚙ ✍ 📖 📖🔄
🔄
🔄
🔄
https://github.com/backpaper0/httpserver
© 2017 Pivotal Software, Inc. All rights reserved.
Use Case: Remote call with latency
☁💻
https://speakerdeck.com/sdeleuze/developing-reactive-applications-with-reactive-streams-and-java-8
© 2017 Pivotal Software, Inc. All rights reserved.
Use Case: Remote call with latency
☁💻
https://speakerdeck.com/sdeleuze/developing-reactive-applications-with-reactive-streams-and-java-8
🐌
© 2017 Pivotal Software, Inc. All rights reserved.
Use Case: Remote call with latency
☁💻
https://speakerdeck.com/sdeleuze/developing-reactive-applications-with-reactive-streams-and-java-8
🐌
© 2017 Pivotal Software, Inc. All rights reserved.
Use Case: Serve a lot of slow clients
https://speakerdeck.com/sdeleuze/developing-reactive-applications-with-reactive-streams-and-java-8
📱📱 📱📱 📱📱 📱📱 📱📱 📱📱
© 2017 Pivotal Software, Inc. All rights reserved.
Use Case: Push message to client
https://speakerdeck.com/sdeleuze/developing-reactive-applications-with-reactive-streams-and-java-8
💻 💬💬💬
Server-Sent Events
WebSocket
RabbitMQ
Apache Kafka
∞
© 2017 Pivotal Software, Inc. All rights reserved.
Other Use Cases
•Live (continuous) database queries
•UI event handling (Android)
•Big Data
•Real Time Analytics
•HTTP/2
© 2017 Pivotal Software, Inc. All rights reserved.
Going Reactive
More for scalability and stability than for speed
© 2017 Pivotal Software, Inc. All rights reserved.
blocking ====> event-based
public class IAmBlocking {
public void blockingCode() {
String a = callRemoteA();
String b = callRemoteB();
String c = callRemoteC();
String d = callRemoteD();
System.out.println(a+" "+b+" "+c+" "+d);
}
}
😅
© 2017 Pivotal Software, Inc. All rights reserved.
blocking ====> event-based
public class AmIReactive {
public void amIReallyReactive() {
callRemoteA(a -> {
callRemoteB(b -> {
callRemoteC(c -> {
callRemoteD(d -> println(a+" "+b+" "+c+" "+d),
exd -> exd.printStackTrace())
}, exc -> exc.printStackTrace())
}, exb -> exb.printStackTrace()
}, exa -> exa.printStackTrace());}}
😕
© 2017 Pivotal Software, Inc. All rights reserved.
public class IAmReactive {
public void iAmReallyReactive() {
when(callRemoteA(), callRemoteB(),
callRemoteC(), callRemoteD())
.doOnError(e -> e.printStakcTrace())
.subscribe(t -> // Tuple4<A, B, C, D>
println(t.t1 +" "+t.t2+" "+t.t3+" "+t.t4));
blocking ====> event-based
😀
‹#›© 2016 Pivotal Software, Inc. All rights reserved.
Reactive Streams / Reactor
© 2017 Pivotal Software, Inc. All rights reserved.
Reactive Streams
•Standard interfaces for asynchronous stream
processing with non-blocking back pressure
•De-facto standard for interoperability
between reactive libraries
•Implemented by
http://www.reactive-streams.org/
© 2017 Pivotal Software, Inc. All rights reserved.
Reactive Streams
•Standard interfaces for asynchronous stream
processing with non-blocking back pressure
•De-facto standard for interoperability
between reactive libraries
•Implemented by
http://www.reactive-streams.org/
RxJava 2 Reactor Akka Streams
‹#›© 2016 Pivotal Software, Inc. All rights reserved.
Reactive Streams has 4 interfaces
public interface Publisher<T> {
void subscribe(Subscriber<? super T> s);
}
public interface Subscription {
void request(long n);
void cancel();
}
public interface Subscriber<T> {
void onSubscribe(Subscription s);
void onNext(T t);
void onError(Throwable t);
void onComplete();
}
public interface Processor<T, R> extends
Publisher<T>, Subscriber<R> {}
© 2017 Pivotal Software, Inc. All rights reserved.
Publisher Subscriber
Data Flow
© 2017 Pivotal Software, Inc. All rights reserved.
Publisher Subscriber
subscribe
Data Flow
© 2017 Pivotal Software, Inc. All rights reserved.
Publisher Subscriber
request(n)
Backpressure
Data Flow
© 2017 Pivotal Software, Inc. All rights reserved.
Publisher Subscriber
Backpressure
onNext(data)
onNext(data)
onNext(data)
Data Flow
© 2017 Pivotal Software, Inc. All rights reserved.
Publisher Subscriber
Backpressure
Error|Complete
Data Flow
© 2017 Pivotal Software, Inc. All rights reserved.
Back-pressure
•Allows to control the amount of inflight data
•Regulate the transfer between
•Slow publisher and fast consumer
•Fast publisher and slow consumer
https://speakerdeck.com/sdeleuze/developing-reactive-applications-with-reactive-streams-and-java-8
© 2017 Pivotal Software, Inc. All rights reserved.
Reactive Streams based libraries
© 2017 Pivotal Software, Inc. All rights reserved.
Reactive Streams based libraries
RxJava
Reactor
Akka Streams
© 2017 Pivotal Software, Inc. All rights reserved.
Reactive Streams based libraries
RxJava
Reactor
Akka Streams
© 2017 Pivotal Software, Inc. All rights reserved.
Reactor
•Natively built on top of Reactive Streams with Rx API
•Developed by Pivotal
•Focus on Java 8
•java.util.function.*
•Duration / CompletableFuture / Stream
• Lightweight Rx API with 2 types:
•Flux / Mono
https://projectreactor.io/
© 2017 Pivotal Software, Inc. All rights reserved.
Flux<T>
Mono<T>
© 2017 Pivotal Software, Inc. All rights reserved.
Flux<T> is a Publisher<T> for 0..n elements
© 2017 Pivotal Software, Inc. All rights reserved.
Flux<T>
Mono<T>
© 2017 Pivotal Software, Inc. All rights reserved.
Mono<T> is a Publisher<T> for 0..1 element
© 2017 Pivotal Software, Inc. All rights reserved.
Flux
Flux<Integer> stream1 = Flux.just(1, 2, 3)
.map(x -> x * 2)
.filter(x -> x > 2); // 4, 6
Flux<String> stream2 = Flux.just("a", "b", "c");
Flux.zip(stream1, stream2)

.doOneNext(t -> println(t.t1 + ":" + t.t2))
.subscribe();
Flux.merge(stream1, stream2)

.doOneNext(x -> println(x)).subscribe();
© 2017 Pivotal Software, Inc. All rights reserved.
Flux
Flux<Integer> stream1 = Flux.just(1, 2, 3)
.map(x -> x * 2)
.filter(x -> x > 2); // 4, 6
Flux<String> stream2 = Flux.just("a", "b", "c");
Flux.zip(stream1, stream2)

.doOneNext(t -> println(t.t1 + ":" + t.t2))
.subscribe();
Flux.merge(stream1, stream2)

.doOneNext(x -> println(x)).subscribe();
4:a
6:b
© 2017 Pivotal Software, Inc. All rights reserved.
Flux
Flux<Integer> stream1 = Flux.just(1, 2, 3)
.map(x -> x * 2)
.filter(x -> x > 2); // 4, 6
Flux<String> stream2 = Flux.just("a", "b", "c");
Flux.zip(stream1, stream2)

.doOneNext(t -> println(t.t1 + ":" + t.t2))
.subscribe();
Flux.merge(stream1, stream2)

.doOneNext(x -> println(x)).subscribe();
4:a
6:b
4
6
a
b
c
© 2017 Pivotal Software, Inc. All rights reserved.
String location = "Tokyo, Japan";
mainService.fetchWeather(location)
.timeout(Duration.ofSeconds(2))
.doOnError(ex -> logger.error(ex.getMessage()))
.onErrorResume(ex -> backupService.fetchWeather(location))
.map(w -> format("Weather in %s is %s", w.location(), w.description()))
.subscribe(message -> logger.info(message));
© 2017 Pivotal Software, Inc. All rights reserved.
String location = "Tokyo, Japan";
mainService.fetchWeather(location)
.timeout(Duration.ofSeconds(2))
.doOnError(ex -> logger.error(ex.getMessage()))
.onErrorResume(ex -> backupService.fetchWeather(location))
.map(w -> format("Weather in %s is %s", w.location(), w.description()))
.subscribe(message -> logger.info(message));
Mono<Weather> fetchWeather(String city);
© 2017 Pivotal Software, Inc. All rights reserved.
String location = "Tokyo, Japan";
mainService.fetchWeather(location)
.timeout(Duration.ofSeconds(2))
.doOnError(ex -> logger.error(ex.getMessage()))
.onErrorResume(ex -> backupService.fetchWeather(location))
.map(w -> format("Weather in %s is %s", w.location(), w.description()))
.subscribe(message -> logger.info(message));
times out and emits an error after 2 sec
© 2017 Pivotal Software, Inc. All rights reserved.
String location = "Tokyo, Japan";
mainService.fetchWeather(location)
.timeout(Duration.ofSeconds(2))
.doOnError(ex -> logger.error(ex.getMessage()))
.onErrorResume(ex -> backupService.fetchWeather(location))
.map(w -> format("Weather in %s is %s", w.location(), w.description()))
.subscribe(message -> logger.info(message));
logs a message in case of errors
© 2017 Pivotal Software, Inc. All rights reserved.
String location = "Tokyo, Japan";
mainService.fetchWeather(location)
.timeout(Duration.ofSeconds(2))
.doOnError(ex -> logger.error(ex.getMessage()))
.onErrorResume(ex -> backupService.fetchWeather(location))
.map(w -> format("Weather in %s is %s", w.location(), w.description()))
.subscribe(message -> logger.info(message));
switches to a different service in case of error
© 2017 Pivotal Software, Inc. All rights reserved.
String location = "Tokyo, Japan";
mainService.fetchWeather(location)
.timeout(Duration.ofSeconds(2))
.doOnError(ex -> logger.error(ex.getMessage()))
.onErrorResume(ex -> backupService.fetchWeather(location))
.map(w -> format("Weather in %s is %s", w.location(), w.description()))
.subscribe(message -> logger.info(message));
transforms a weather instance into a String message
© 2017 Pivotal Software, Inc. All rights reserved.
String location = "Tokyo, Japan";
mainService.fetchWeather(location)
.timeout(Duration.ofSeconds(2))
.doOnError(ex -> logger.error(ex.getMessage()))
.onErrorResume(ex -> backupService.fetchWeather(location))
.map(w -> format("Weather in %s is %s", w.location(), w.description()))
.subscribe(message -> logger.info(message));
triggers the processing of the chain
© 2017 Pivotal Software, Inc. All rights reserved.
Type comparison
No value Single value Multiple values
JDK CompletableFuture<Void> CompletableFuture<T> CompletableFuture<List<T>>
Reactive
Streams
Publisher<Void> Publisher<T> Publisher<T>
RxJava1 Completable Single<T> Observable<T>
RxJava2 Completable

Maybe<T>
Single<T>
Maybe<T>
Flowable<T> (*)
Observable<T>
Reactor Mono<Void> (*) Mono<T> (*) Flux<T> (*)
(*) ... implements Publisher
© 2017 Pivotal Software, Inc. All rights reserved.
java.util.concurrent.Flow in JDK 9
Reactive Streams JDK 9
org.reactivestreams java.util.concurrent
Publisher Flow.Publisher
Subscriber Flow.Subscriber
Subscription Flow.Subscription
Processor Flow.Processor
© 2017 Pivotal Software, Inc. All rights reserved.
Reactive Streams ↔ j.u.c.Flow
// Reactive Streams (Reactor)
Publisher<String> pub = Flux.just("hello");
// java.util.concurrent.Flow
Flow.Publisher<String> flow =
JdkFlowAdapter.publisherToFlowPublisher(pub);
// java.util.concurrent.Flow
Flow.Publisher<String> flow = /* ... */;
// Reactive Streams (Reactor)
Flux<String> pub =
JdkFlowAdapter.flowPublisherToFlux(flow);
‹#›© 2016 Pivotal Software, Inc. All rights reserved.
Spring Framework 5.0
© 2017 Pivotal Software, Inc. All rights reserved.
Spring Framework 5.0
•Performance improvements
•JDK 9 - HTTP/2
•Reactive Spring
•Functional APIs
•Kotlin Support
https://speakerdeck.com/snicoll/spring-framework-5-dot-0-themes-and-trends
© 2017 Pivotal Software, Inc. All rights reserved.
Spring Framework 5.0
•Performance improvements
•JDK 9 - HTTP/2
•Reactive Spring
•Functional APIs
•Kotlin Support
https://speakerdeck.com/snicoll/spring-framework-5-dot-0-themes-and-trends
© 2017 Pivotal Software, Inc. All rights reserved.
© 2017 Pivotal Software, Inc. All rights reserved.
@Controller, @RequestMapping
Spring MVC
Servlet API
Servlet Container
© 2017 Pivotal Software, Inc. All rights reserved.
@Controller, @RequestMapping
Spring MVC
Servlet API
Servlet Container Servlet 3.1, Netty, Undertow
Spring WebFlux
HTTP / Reactive Streams
© 2017 Pivotal Software, Inc. All rights reserved.
@Controller, @RequestMapping
Spring MVC
Servlet API
Servlet Container
Router functions
Servlet 3.1, Netty, Undertow
Spring WebFlux
HTTP / Reactive Streams
© 2017 Pivotal Software, Inc. All rights reserved.
Spring WebFlux
© 2017 Pivotal Software, Inc. All rights reserved.
Spring WebFlux
@RestController

public class HelloController {
@GetMapping
Flux<String> hello() {

return Flux.just("Hello", "World");

}

}
© 2017 Pivotal Software, Inc. All rights reserved.
Spring WebFlux
@RestController

public class EchoController {
@PostMapping("/echo")
Flux<String> upperCase
(@RequestBody Flux<String> body) {

return body.map(String::toUpperCase);

}

}
© 2017 Pivotal Software, Inc. All rights reserved.
Returns Infinite-Stream
@RestController

public class HelloController {
@GetMapping
Flux<Integer> infinite() {
Stream<Integer> s =
Stream.iterate(0, i -> i + 1);

return Flux.fromStream(s);

}}

© 2017 Pivotal Software, Inc. All rights reserved.
Returns Infinite-Stream
@RestController

public class TweetController {
@GetMapping
Flux<Tweet> infiniteTweet() {
Stream<Tweet> s =
Stream.iterate(0, i -> i + 1)
.map(i -> new Tweet("hello" + i));

return Flux.fromStream(s);}}

© 2017 Pivotal Software, Inc. All rights reserved.
Flux<Tweet> as a Server-Sent Events
curl ... -H "Accept: text/event-stream"
< HTTP/1.1 200 OK
< Content-Type: text/event-stream
<
data: {"text":"hello0"}
data: {"text":"hello1"}
data: {"text":"hello2"}
data: {"text":"hello3"}
...
© 2017 Pivotal Software, Inc. All rights reserved.
Flux<Tweet> as a JSON Stream
curl ... -H "Accept: application/stream+json"
< HTTP/1.1 200 OK
< Content-Type: application/stream+json
<
{"text":"hello0"}
{"text":"hello1"}
{"text":"hello2"}
{"text":"hello3"}
...
© 2017 Pivotal Software, Inc. All rights reserved.
WebClient
•Reactive HTTP Client
© 2017 Pivotal Software, Inc. All rights reserved.
WebClient
•Reactive HTTP Client
a nice RestTemplate alternative
© 2017 Pivotal Software, Inc. All rights reserved.
WebClient
•Reactive HTTP Client
WebClient webClient = WebClient.create();
Mono<String> s = webClient.get()
.uri("http://api.example.com")
.exchange()
.flatMap(res ->
res.bodyToMono(String.class));
a nice RestTemplate alternative
© 2017 Pivotal Software, Inc. All rights reserved.
WebClient
•Reactive HTTP Client
WebClient webClient = WebClient.create();
Mono<String> s = webClient.get()
.uri("http://api.example.com")
.retrieve()
.bodyToMono(String.class);
© 2017 Pivotal Software, Inc. All rights reserved.
WebClient
•Reactive HTTP Client
WebClient webClient = WebClient.create();
Flux<Tweet> tweets = webClient.get()
.uri("http://api.example.com")
.retrieve()
.bodyToFlux(Tweet.class);
© 2017 Pivotal Software, Inc. All rights reserved.
Flux<Tweet> WebClient
Streaming API
© 2017 Pivotal Software, Inc. All rights reserved.
Flux<Tweet>
✔ Reactive API
✔ Can consume (infinite) streams
WebClient
Streaming API
© 2017 Pivotal Software, Inc. All rights reserved.
Flux.zip(tweets,	issues)
WebClient
Streaming API
REST API
WebClient
© 2017 Pivotal Software, Inc. All rights reserved.
Flux.zip(tweets,	issues)
✔ Chain and compose
WebClient
Streaming API
REST API
WebClient
© 2017 Pivotal Software, Inc. All rights reserved.
WebClient
Web handler
WebFlux
© 2017 Pivotal Software, Inc. All rights reserved.
WebClient
Web handler
WebFlux
© 2017 Pivotal Software, Inc. All rights reserved.
WebClient
Web handler
WebFlux
✔ Shared resources (event loop, buffers)
✔ Built-in mocking capabilities
© 2017 Pivotal Software, Inc. All rights reserved.
Router Functions
© 2017 Pivotal Software, Inc. All rights reserved.
Router Functions
RouterFunctions<ServerResponse> routes() {

return RouterFunctions.route(
RequestPredicates.GET("/"),
req -> ServerResponse.ok()
.body(Mono.just("Hello","World"),
String.class));

}
© 2017 Pivotal Software, Inc. All rights reserved.
Router Functions
RouterFunctions<ServerResponse> routes() {

return RouterFunctions.route(
RequestPredicates.GET("/"),
req -> ServerResponse.ok()
.body(Mono.just("Hello","World"),
String.class));

}
© 2017 Pivotal Software, Inc. All rights reserved.
Router Functions
RouterFunctions<ServerResponse> routes() {

return route(
RequestPredicates.GET("/"),
req -> ServerResponse.ok()
.body(Mono.just("Hello","World"),
String.class));

}
© 2017 Pivotal Software, Inc. All rights reserved.
Router Functions
RouterFunctions<ServerResponse> routes() {

return route(
RequestPredicates.GET("/"),
req -> ServerResponse.ok()
.body(Mono.just("Hello","World"),
String.class));

}
© 2017 Pivotal Software, Inc. All rights reserved.
Router Functions
RouterFunctions<ServerResponse> routes() {

return route(GET("/"),
req -> ServerResponse.ok()
.body(Mono.just("Hello","World"),
String.class));

}
© 2017 Pivotal Software, Inc. All rights reserved.
Router Functions
RouterFunctions<ServerResponse> routes() {

return route(GET("/"),
req -> ServerResponse.ok()
.body(Mono.just("Hello","World"),
String.class));

}
© 2017 Pivotal Software, Inc. All rights reserved.
Router Functions
RouterFunctions<ServerResponse> routes() {

return route(GET("/"),
req -> ok()
.body(Mono.just("Hello","World"),
String.class));

}
© 2017 Pivotal Software, Inc. All rights reserved.
Router Functions
RouterFunctions<ServerResponse> routes() {
return route(POST("/echo"),
req -> {
Mono<String> body = req
.bodyToMono(String.class)
.map(String::toUpperCase);
return ok().body(body, String.class));
});}
© 2017 Pivotal Software, Inc. All rights reserved.
Spring Boot 2.0
Spring Boot 2.0 supports
Spring 5 and WebFlux ✨
© 2017 Pivotal Software, Inc. All rights reserved.
start.spring.io
‹#›© 2016 Pivotal Software, Inc. All rights reserved.
DEMO
© 2017 Pivotal Software, Inc. All rights reserved.
Spring MVC VS Spring WebFlux
@GetMapping
Flux<String> hello() {

return Flux.just("Hello")
.delayElements(
ofSeconds(1));

}
@GetMapping
String hello() {
Thread.sleep(1000);

return"Hello";

}
server.tomcat.max-threads=200 (default)
https://gist.github.com/making/f32e81c5684a5fd810039854091dd793
Tomcat Netty
© 2017 Pivotal Software, Inc. All rights reserved.
Concurrent users = 100
© 2017 Pivotal Software, Inc. All rights reserved.
Concurrent users = 100
Transaction rate: 94.79 trans/sec
Response time: 1.05 sec
Live peek threads: 129
© 2017 Pivotal Software, Inc. All rights reserved.
Concurrent users = 100
Transaction rate: 94.79 trans/sec
Response time: 1.05 sec
Live peek threads: 129
Transaction rate: 94.88 trans/sec
Response time: 1.05 sec
Live peek threads: 30
© 2017 Pivotal Software, Inc. All rights reserved.
Concurrent users = 200
© 2017 Pivotal Software, Inc. All rights reserved.
Concurrent users = 200
Transaction rate: 182.65 trans/sec
Response time: 1.07 sec
Live peek threads: 218
© 2017 Pivotal Software, Inc. All rights reserved.
Concurrent users = 200
Transaction rate: 182.65 trans/sec
Response time: 1.07 sec
Live peek threads: 218
Transaction rate: 184.50 trans/sec
Response time: 1.06 sec
Live peek threads: 30
© 2017 Pivotal Software, Inc. All rights reserved.
Concurrent users = 300
© 2017 Pivotal Software, Inc. All rights reserved.
Concurrent users = 300
Transaction rate: 192.31 trans/sec
Response time: 1.51 sec
Live peek threads: 218
© 2017 Pivotal Software, Inc. All rights reserved.
Concurrent users = 300
Transaction rate: 192.31 trans/sec
Response time: 1.51 sec
Live peek threads: 218
Transaction rate: 278.55 trans/sec
Response time: 1.04 sec
Live peek threads: 30
© 2017 Pivotal Software, Inc. All rights reserved.
Blocking in WebFlux??
@GetMapping
Flux<String> hello() {
Thread.sleep(1000); // blocking!

return Flux.just("Hello");

}
© 2017 Pivotal Software, Inc. All rights reserved.
Concurrent users = 100
Transaction rate: 7.94 trans/sec
Response time: 12 sec
Live peek threads: 22 😱
‹#›© 2016 Pivotal Software, Inc. All rights reserved.
End-to-End Reactive
© 2017 Pivotal Software, Inc. All rights reserved.
End-to-End Reactive
Controller
Repository
Service
Filter
Publisher Publisher Publisher Publisher
Publisher Publisher Publisher Publisher
© 2017 Pivotal Software, Inc. All rights reserved.
End-to-End Reactive
Controller
Repository
Service
Filter
Publisher Publisher Publisher Publisher
Publisher Publisher Publisher Publisher
© 2017 Pivotal Software, Inc. All rights reserved.
Spring Projects
Reactor Ecosystem
Spring Security
Spring Data
Spring Cloud
Spring Integration
Reactor Projects
Reactor Netty
Reactor Kafka
Lettuce
Thymeleaf
© 2017 Pivotal Software, Inc. All rights reserved.
Spring Projects
Reactor Ecosystem
Spring Security
Spring Data
Spring Cloud
Spring Integration
Reactor Projects
Reactor Netty
Reactor Kafka
Lettuce
MongoDB Redis Cassandra Couchbase
Thymeleaf
© 2017 Pivotal Software, Inc. All rights reserved.
Spring Data Release Train Kay
•Supports
•Reactive Template
•Reactive Repository
© 2017 Pivotal Software, Inc. All rights reserved.
Reactive Repository
public interface ReactiveCrudRepository<ID,T> {
Mono<T> findById(ID id);
Mono<T> findById(Mono<ID> id);
Flux<T> findAll();
Mono<Long> count();
Mono<T> save(T entity);
Mono<T> saveAll(Publisher<T> entityStream);
Mono<Void> delete(T entity)
// ...
}
© 2017 Pivotal Software, Inc. All rights reserved.
@Tailable for Infinite streams
public interface PersonRepository
extends ReactiveMongoRepository<Person,String> {
@Tailable
Flux<Person> findByFirstname(String firstname);
}
© 2017 Pivotal Software, Inc. All rights reserved.
What about JPA/JDBC?
🤔
© 2017 Pivotal Software, Inc. All rights reserved.
What about JPA/JDBC?
•JDBC is blocking ⌛
•JPA is blocking ⌛
🤔
© 2017 Pivotal Software, Inc. All rights reserved.
What about JPA/JDBC?
•JDBC is blocking ⌛
•JPA is blocking ⌛
🤔
https://static.rainfocus.com/oracle/oow16/sess/1461693351182001EmRq/ppt/
CONF1578%2020160916.pdf
https://www.voxxed.com/blog/2016/09/non-blocking-database-access/
•Non-Blocking JDBC in JDK 10?
© 2017 Pivotal Software, Inc. All rights reserved.
Switching execution context
BlockingRepository<User> repo = ...;
Flux<User> users =
Flux.defer(() ->
Flux.fromIterable(repo.findAll()))
.subscribeOn(Schedulers.elastic());
Make the subscription and request happen
on a particular thread
© 2017 Pivotal Software, Inc. All rights reserved.
Switching execution context
Flux<User> users = ...;
BlockingRepository<User> repo = ...;
users.publishOn(Schedulers.elastic())
.doOneNext(u -> repo.save(u))
.then() ;
Switch rest of the flux on a particular thread
‹#›© 2016 Pivotal Software, Inc. All rights reserved.
Reactive Web Applications
Example
© 2017 Pivotal Software, Inc. All rights reserved.
💻
💻
💻
Server-Sent Events
POST
PUBLISH
SUBSCRIBE
INCR
Pub/Sub Application
bit.ly/jdtd1d5
© 2017 Pivotal Software, Inc. All rights reserved.
API Gateway
• Rate Limiter
• Web Application Firewall
© 2017 Pivotal Software, Inc. All rights reserved.
API Gateway
• Rate Limiter
• Web Application Firewall
✅ Spring Cloud Gateway
© 2017 Pivotal Software, Inc. All rights reserved.
Route Services in Cloud Foundry
© 2017 Pivotal Software, Inc. All rights reserved.
FFB (Frontend for Backend)
💻
📱
Frontend Backend
© 2017 Pivotal Software, Inc. All rights reserved.
Reactive Everywhere
CF Java Client
Firehose Nozzle
Firehose Nozzle
Cloud Foundry
💻
Firehose
Doppler Endpoint
WebSocket
Rector Kafka
(Publisher)
Rector Kafka
(Consumer)
Reactor Netty
Sever-Sent Event
Spring WebFluxLog, Metrics
© 2017 Pivotal Software, Inc. All rights reserved.
Spring WebFlux
• https://blog.ik.am/entries/417
• https://blog.ik.am/entries/418
• ...
© 2017 Pivotal Software, Inc. All rights reserved.
Thank you!!
• Handson
• https://github.com/reactor/lite-rx-api-hands-on
• Slides
• https://speakerdeck.com/simonbasle/reactor-3
• https://speakerdeck.com/sdeleuze/developing-reactive-applications-with-
reactive-streams-and-java-8
• https://speakerdeck.com/snicoll/spring-framework-5-dot-0-themes-and-
trends
• https://speakerdeck.com/mp911de/reactive-spring
• https://speakerdeck.com/christophstrobl/sneak-peek-on-spring-data-kay
• https://speakerdeck.com/normanmaurer/netty-meetup-2017-san-francisco

More Related Content

What's hot (20)

PDF
GraalVM: Run Programs Faster Everywhere
J On The Beach
 
PPTX
GOING AOT WITH GRAALVM FOR SPRING BOOT (SPRING IO)
Alina Yurenko
 
PDF
OpenStack Swift紹介
Kota Tsuyuzaki
 
PDF
Spring Security 5.0 解剖速報
Takuya Iwatsuka
 
PDF
WebSocket / WebRTCの技術紹介
Yasuhiro Mawarimichi
 
PDF
Introduction to GitHub Actions
Bo-Yi Wu
 
PDF
Spring Boot
Pei-Tang Huang
 
PDF
Practical Sikuli: using screenshots for GUI automation and testing
vgod
 
PDF
AbemaTVの動画配信を支えるサーバーサイドシステム
yuichiro nakazawa
 
PDF
Using GitLab CI
ColCh
 
PDF
Linux kernel tracing
Viller Hsiao
 
PPTX
Micro-frontends with Angular 10 (Modern Web 2020)
Will Huang
 
PDF
Spring Framework - AOP
Dzmitry Naskou
 
PDF
2021 ZAP Automation in CI/CD
Simon Bennetts
 
PDF
Service Worker Presentation
Kyle Dorman
 
PDF
LINE LIVE のチャットが
30,000+/min のコメント投稿を捌くようになるまで
LINE Corporation
 
PDF
Learning git
Sid Anand
 
PDF
Apache Kafkaによるログ転送とパフォーマンスチューニング - Bonfire Backend #2 -
Yahoo!デベロッパーネットワーク
 
PPTX
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
NTT DATA Technology & Innovation
 
PDF
Running Spring Boot Applications as GraalVM Native Images
VMware Tanzu
 
GraalVM: Run Programs Faster Everywhere
J On The Beach
 
GOING AOT WITH GRAALVM FOR SPRING BOOT (SPRING IO)
Alina Yurenko
 
OpenStack Swift紹介
Kota Tsuyuzaki
 
Spring Security 5.0 解剖速報
Takuya Iwatsuka
 
WebSocket / WebRTCの技術紹介
Yasuhiro Mawarimichi
 
Introduction to GitHub Actions
Bo-Yi Wu
 
Spring Boot
Pei-Tang Huang
 
Practical Sikuli: using screenshots for GUI automation and testing
vgod
 
AbemaTVの動画配信を支えるサーバーサイドシステム
yuichiro nakazawa
 
Using GitLab CI
ColCh
 
Linux kernel tracing
Viller Hsiao
 
Micro-frontends with Angular 10 (Modern Web 2020)
Will Huang
 
Spring Framework - AOP
Dzmitry Naskou
 
2021 ZAP Automation in CI/CD
Simon Bennetts
 
Service Worker Presentation
Kyle Dorman
 
LINE LIVE のチャットが
30,000+/min のコメント投稿を捌くようになるまで
LINE Corporation
 
Learning git
Sid Anand
 
Apache Kafkaによるログ転送とパフォーマンスチューニング - Bonfire Backend #2 -
Yahoo!デベロッパーネットワーク
 
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
NTT DATA Technology & Innovation
 
Running Spring Boot Applications as GraalVM Native Images
VMware Tanzu
 

Viewers also liked (12)

PDF
Spring I/O 2017 報告 ThymeleafのWebFlux対応
Takuya Iwatsuka
 
PDF
Spring Boot概要
af not found
 
PDF
Unified JVM Logging
Yuji Kubota
 
PDF
ArrayListをじっくり読んでみた - JavaコアSDKを読む会を社内でやって気づいたこと -
JustSystems Corporation
 
PDF
ジャストシステムJava100本ノックのご紹介
JustSystems Corporation
 
PPTX
Project Jigsaw #kanjava
Yuji Kubota
 
PPTX
ぱぱっと理解するSpring Cloudの基本
kazuki kumagai
 
PDF
とにかく楽してVue.jsでTypeScriptを使いたい
さくらインターネット株式会社
 
PPTX
Spring 5に備えるリアクティブプログラミング入門
Takuya Iwatsuka
 
PDF
Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3
Toshiaki Maki
 
PDF
4つの戦犯から考えるサービスづくりの失敗
toshihiro ichitani
 
PPTX
AI and Machine Learning Demystified by Carol Smith at Midwest UX 2017
Carol Smith
 
Spring I/O 2017 報告 ThymeleafのWebFlux対応
Takuya Iwatsuka
 
Spring Boot概要
af not found
 
Unified JVM Logging
Yuji Kubota
 
ArrayListをじっくり読んでみた - JavaコアSDKを読む会を社内でやって気づいたこと -
JustSystems Corporation
 
ジャストシステムJava100本ノックのご紹介
JustSystems Corporation
 
Project Jigsaw #kanjava
Yuji Kubota
 
ぱぱっと理解するSpring Cloudの基本
kazuki kumagai
 
とにかく楽してVue.jsでTypeScriptを使いたい
さくらインターネット株式会社
 
Spring 5に備えるリアクティブプログラミング入門
Takuya Iwatsuka
 
Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3
Toshiaki Maki
 
4つの戦犯から考えるサービスづくりの失敗
toshihiro ichitani
 
AI and Machine Learning Demystified by Carol Smith at Midwest UX 2017
Carol Smith
 
Ad

Similar to Spring Framework 5.0による Reactive Web Application #JavaDayTokyo (20)

PPTX
Ongoing management of your PHP 7 application
Zend by Rogue Wave Software
 
PDF
Spring Cloud Servicesの紹介 #pcf_tokyo
Toshiaki Maki
 
PDF
Data Microservices with Spring Cloud Stream, Task, and Data Flow #jsug #spri...
Toshiaki Maki
 
PDF
OSMC 2018 | Distributed Tracing FAQ by Gianluca Arbezzano
NETWAYS
 
PPTX
FactoryTalk® AssetCentre: Overview
Rockwell Automation
 
PDF
Hypha ROS X 星火計畫 ROS 2.0 Introduction [haochih, English ver]
HaoChih Lin
 
PDF
Cloud Foundry Summit 2017
Yahoo!デベロッパーネットワーク
 
PDF
Streaming solutions for real time problems
Aparna Gaonkar
 
PDF
Updates on webSpoon and other innovations from Hitachi R&D
Hiromu Hota
 
PDF
Event Driven Microservices with Spring Cloud Stream #jjug_ccc #ccc_ab3
Toshiaki Maki
 
PDF
Journey to Cloud-Native: Continuous Delivery with Artificial Intelligence
VMware Tanzu
 
PDF
Product Release Webinar- WSO2 Developer Studio 3.5
WSO2
 
PPTX
Webinar: End-to-End CI/CD with GitLab and DC/OS
Mesosphere Inc.
 
PPTX
SplunkLive! London 2017 - DevOps Powered by Splunk
Splunk
 
PPTX
APIdays 2016 - The State of Web API Languages
Restlet
 
PPTX
Syncfusion: Flat License Options
Domingo Rogers
 
PDF
Cytoscape: Now and Future
Keiichiro Ono
 
PDF
SpringOnePlatform2017 recap
minseok kim
 
PDF
Modern Application Development for the Enterprise
Juarez Junior
 
PPTX
Oracle Code Online: Building a Serverless State Service for the Cloud
Ed Burns
 
Ongoing management of your PHP 7 application
Zend by Rogue Wave Software
 
Spring Cloud Servicesの紹介 #pcf_tokyo
Toshiaki Maki
 
Data Microservices with Spring Cloud Stream, Task, and Data Flow #jsug #spri...
Toshiaki Maki
 
OSMC 2018 | Distributed Tracing FAQ by Gianluca Arbezzano
NETWAYS
 
FactoryTalk® AssetCentre: Overview
Rockwell Automation
 
Hypha ROS X 星火計畫 ROS 2.0 Introduction [haochih, English ver]
HaoChih Lin
 
Streaming solutions for real time problems
Aparna Gaonkar
 
Updates on webSpoon and other innovations from Hitachi R&D
Hiromu Hota
 
Event Driven Microservices with Spring Cloud Stream #jjug_ccc #ccc_ab3
Toshiaki Maki
 
Journey to Cloud-Native: Continuous Delivery with Artificial Intelligence
VMware Tanzu
 
Product Release Webinar- WSO2 Developer Studio 3.5
WSO2
 
Webinar: End-to-End CI/CD with GitLab and DC/OS
Mesosphere Inc.
 
SplunkLive! London 2017 - DevOps Powered by Splunk
Splunk
 
APIdays 2016 - The State of Web API Languages
Restlet
 
Syncfusion: Flat License Options
Domingo Rogers
 
Cytoscape: Now and Future
Keiichiro Ono
 
SpringOnePlatform2017 recap
minseok kim
 
Modern Application Development for the Enterprise
Juarez Junior
 
Oracle Code Online: Building a Serverless State Service for the Cloud
Ed Burns
 
Ad

More from Toshiaki Maki (20)

PDF
From Spring Boot 2.2 to Spring Boot 2.3 #jsug
Toshiaki Maki
 
PDF
Concourse x Spinnaker #concourse_tokyo
Toshiaki Maki
 
PDF
Serverless with Spring Cloud Function, Knative and riff #SpringOneTour #s1t
Toshiaki Maki
 
PDF
決済システムの内製化への旅 - SpringとPCFで作るクラウドネイティブなシステム開発 #jsug #sf_h1
Toshiaki Maki
 
PDF
Spring Boot Actuator 2.0 & Micrometer #jjug_ccc #ccc_a1
Toshiaki Maki
 
PDF
Spring Boot Actuator 2.0 & Micrometer
Toshiaki Maki
 
PDF
Open Service Broker APIとKubernetes Service Catalog #k8sjp
Toshiaki Maki
 
PDF
Spring Cloud Function & Project riff #jsug
Toshiaki Maki
 
PDF
BOSH / CF Deployment in modern ways #cf_tokyo
Toshiaki Maki
 
PDF
Why PCF is the best platform for Spring Boot
Toshiaki Maki
 
PDF
Zipkin Components #zipkin_jp
Toshiaki Maki
 
PPTX
マイクロサービスに必要な技術要素はすべてSpring Cloudにある #DO07
Toshiaki Maki
 
PDF
実例で学ぶ、明日から使えるSpring Boot Tips #jsug
Toshiaki Maki
 
PDF
Spring ❤️ Kotlin #jjug
Toshiaki Maki
 
PDF
Managing your Docker image continuously with Concourse CI
Toshiaki Maki
 
PDF
Short Lived Tasks in Cloud Foundry #cfdtokyo
Toshiaki Maki
 
PDF
今すぐ始めるCloud Foundry #hackt #hackt_k
Toshiaki Maki
 
PDF
Team Support in Concourse CI 2.0 #concourse_tokyo
Toshiaki Maki
 
PDF
From Zero to Hero with REST and OAuth2 #jjug
Toshiaki Maki
 
PDF
Consumer Driven Contractsで REST API/マイクロサービスをテスト #m3tech
Toshiaki Maki
 
From Spring Boot 2.2 to Spring Boot 2.3 #jsug
Toshiaki Maki
 
Concourse x Spinnaker #concourse_tokyo
Toshiaki Maki
 
Serverless with Spring Cloud Function, Knative and riff #SpringOneTour #s1t
Toshiaki Maki
 
決済システムの内製化への旅 - SpringとPCFで作るクラウドネイティブなシステム開発 #jsug #sf_h1
Toshiaki Maki
 
Spring Boot Actuator 2.0 & Micrometer #jjug_ccc #ccc_a1
Toshiaki Maki
 
Spring Boot Actuator 2.0 & Micrometer
Toshiaki Maki
 
Open Service Broker APIとKubernetes Service Catalog #k8sjp
Toshiaki Maki
 
Spring Cloud Function & Project riff #jsug
Toshiaki Maki
 
BOSH / CF Deployment in modern ways #cf_tokyo
Toshiaki Maki
 
Why PCF is the best platform for Spring Boot
Toshiaki Maki
 
Zipkin Components #zipkin_jp
Toshiaki Maki
 
マイクロサービスに必要な技術要素はすべてSpring Cloudにある #DO07
Toshiaki Maki
 
実例で学ぶ、明日から使えるSpring Boot Tips #jsug
Toshiaki Maki
 
Spring ❤️ Kotlin #jjug
Toshiaki Maki
 
Managing your Docker image continuously with Concourse CI
Toshiaki Maki
 
Short Lived Tasks in Cloud Foundry #cfdtokyo
Toshiaki Maki
 
今すぐ始めるCloud Foundry #hackt #hackt_k
Toshiaki Maki
 
Team Support in Concourse CI 2.0 #concourse_tokyo
Toshiaki Maki
 
From Zero to Hero with REST and OAuth2 #jjug
Toshiaki Maki
 
Consumer Driven Contractsで REST API/マイクロサービスをテスト #m3tech
Toshiaki Maki
 

Recently uploaded (20)

PDF
[Newgen] NewgenONE Marvin Brochure 1.pdf
darshakparmar
 
PDF
Book industry state of the nation 2025 - Tech Forum 2025
BookNet Canada
 
PDF
Mastering Financial Management in Direct Selling
Epixel MLM Software
 
PDF
Future-Proof or Fall Behind? 10 Tech Trends You Can’t Afford to Ignore in 2025
DIGITALCONFEX
 
PPTX
AI Penetration Testing Essentials: A Cybersecurity Guide for 2025
defencerabbit Team
 
PDF
Staying Human in a Machine- Accelerated World
Catalin Jora
 
PPTX
Designing_the_Future_AI_Driven_Product_Experiences_Across_Devices.pptx
presentifyai
 
PDF
Automating Feature Enrichment and Station Creation in Natural Gas Utility Net...
Safe Software
 
PDF
CIFDAQ Market Wrap for the week of 4th July 2025
CIFDAQ
 
PPTX
Agentforce World Tour Toronto '25 - MCP with MuleSoft
Alexandra N. Martinez
 
PDF
“NPU IP Hardware Shaped Through Software and Use-case Analysis,” a Presentati...
Edge AI and Vision Alliance
 
PPTX
Future Tech Innovations 2025 – A TechLists Insight
TechLists
 
PPTX
The Project Compass - GDG on Campus MSIT
dscmsitkol
 
PDF
What’s my job again? Slides from Mark Simos talk at 2025 Tampa BSides
Mark Simos
 
PDF
Bitcoin for Millennials podcast with Bram, Power Laws of Bitcoin
Stephen Perrenod
 
PDF
UiPath DevConnect 2025: Agentic Automation Community User Group Meeting
DianaGray10
 
PDF
Kit-Works Team Study_20250627_한달만에만든사내서비스키링(양다윗).pdf
Wonjun Hwang
 
PDF
“Squinting Vision Pipelines: Detecting and Correcting Errors in Vision Models...
Edge AI and Vision Alliance
 
PDF
The 2025 InfraRed Report - Redpoint Ventures
Razin Mustafiz
 
PPTX
MuleSoft MCP Support (Model Context Protocol) and Use Case Demo
shyamraj55
 
[Newgen] NewgenONE Marvin Brochure 1.pdf
darshakparmar
 
Book industry state of the nation 2025 - Tech Forum 2025
BookNet Canada
 
Mastering Financial Management in Direct Selling
Epixel MLM Software
 
Future-Proof or Fall Behind? 10 Tech Trends You Can’t Afford to Ignore in 2025
DIGITALCONFEX
 
AI Penetration Testing Essentials: A Cybersecurity Guide for 2025
defencerabbit Team
 
Staying Human in a Machine- Accelerated World
Catalin Jora
 
Designing_the_Future_AI_Driven_Product_Experiences_Across_Devices.pptx
presentifyai
 
Automating Feature Enrichment and Station Creation in Natural Gas Utility Net...
Safe Software
 
CIFDAQ Market Wrap for the week of 4th July 2025
CIFDAQ
 
Agentforce World Tour Toronto '25 - MCP with MuleSoft
Alexandra N. Martinez
 
“NPU IP Hardware Shaped Through Software and Use-case Analysis,” a Presentati...
Edge AI and Vision Alliance
 
Future Tech Innovations 2025 – A TechLists Insight
TechLists
 
The Project Compass - GDG on Campus MSIT
dscmsitkol
 
What’s my job again? Slides from Mark Simos talk at 2025 Tampa BSides
Mark Simos
 
Bitcoin for Millennials podcast with Bram, Power Laws of Bitcoin
Stephen Perrenod
 
UiPath DevConnect 2025: Agentic Automation Community User Group Meeting
DianaGray10
 
Kit-Works Team Study_20250627_한달만에만든사내서비스키링(양다윗).pdf
Wonjun Hwang
 
“Squinting Vision Pipelines: Detecting and Correcting Errors in Vision Models...
Edge AI and Vision Alliance
 
The 2025 InfraRed Report - Redpoint Ventures
Razin Mustafiz
 
MuleSoft MCP Support (Model Context Protocol) and Use Case Demo
shyamraj55
 

Spring Framework 5.0による Reactive Web Application #JavaDayTokyo

  • 1. ‹#›© 2016 Pivotal Software, Inc. All rights reserved. ‹#›© 2017 Pivotal Software, Inc. All rights reserved. Spring Framework 5.0 Reactive Web Application Toshiaki Maki (@making) 2016-05-17 Java Day Tokyo 2017
  • 2. © 2017 Pivotal Software, Inc. All rights reserved. Who am I ? • Toshiaki Maki (@making) https://blog.ik.am • Sr. Solutions Architect @Pivotal • Spring Framework 💖 • Cloud Foundry 💖 bit.ly/hajiboot2
  • 3. © 2017 Pivotal Software, Inc. All rights reserved. Reactive???
  • 4. © 2017 Pivotal Software, Inc. All rights reserved. Reactive??? "In a nutshell reactive programming is about non-blocking, event-driven applications that scale with a small number of threads with backpressure as a key ingredient that remains to ensure producers do not overwhelm consumers" - Rossen Stoyanchev
  • 5. © 2017 Pivotal Software, Inc. All rights reserved. Sync / Blocking https://speakerdeck.com/simonbasle/reactor-3
  • 6. © 2017 Pivotal Software, Inc. All rights reserved. Sync / Blocking https://speakerdeck.com/simonbasle/reactor-3 I/O main thread processing resumes
  • 7. © 2017 Pivotal Software, Inc. All rights reserved. Sync / Blocking https://speakerdeck.com/simonbasle/reactor-3 I/O main thread processing resumes 😴 app does nothing
  • 8. © 2017 Pivotal Software, Inc. All rights reserved. Async & Blocking https://speakerdeck.com/simonbasle/reactor-3
  • 9. © 2017 Pivotal Software, Inc. All rights reserved. Async & Blocking https://speakerdeck.com/simonbasle/reactor-3 main thread wait & join
  • 10. © 2017 Pivotal Software, Inc. All rights reserved. Async & Blocking https://speakerdeck.com/simonbasle/reactor-3 main thread wait & join complex new threads, costly
  • 11. © 2017 Pivotal Software, Inc. All rights reserved. Async & Non-Blocking
  • 12. © 2017 Pivotal Software, Inc. All rights reserved. Async & Non-Blocking https://speakerdeck.com/simonbasle/reactor-3 Event Loop chunks processing in non-blocking
  • 13. © 2017 Pivotal Software, Inc. All rights reserved. Blocking + Thread pools (Servlet) HTTP request HTTP response 📖⏳ ⚙⏳ ✍⏳ Thread
  • 14. © 2017 Pivotal Software, Inc. All rights reserved. Non-blocking and event-loop (Netty) IO Selector Thread Worker Threads 🔄 📖⚙ ⚙ ✍ ✍ ⚙ 📖⚙ 📖 ✍ ✍ ⚙ ⚙ ✍ 📖 📖🔄 🔄 🔄 🔄
  • 15. © 2017 Pivotal Software, Inc. All rights reserved. Non-blocking and event-loop (Netty) IO Selector Thread Worker Threads 🔄 📖⚙ ⚙ ✍ ✍ ⚙ 📖⚙ 📖 ✍ ✍ ⚙ ⚙ ✍ 📖 📖🔄 🔄 🔄 🔄 https://github.com/backpaper0/httpserver
  • 16. © 2017 Pivotal Software, Inc. All rights reserved. Use Case: Remote call with latency ☁💻 https://speakerdeck.com/sdeleuze/developing-reactive-applications-with-reactive-streams-and-java-8
  • 17. © 2017 Pivotal Software, Inc. All rights reserved. Use Case: Remote call with latency ☁💻 https://speakerdeck.com/sdeleuze/developing-reactive-applications-with-reactive-streams-and-java-8 🐌
  • 18. © 2017 Pivotal Software, Inc. All rights reserved. Use Case: Remote call with latency ☁💻 https://speakerdeck.com/sdeleuze/developing-reactive-applications-with-reactive-streams-and-java-8 🐌
  • 19. © 2017 Pivotal Software, Inc. All rights reserved. Use Case: Serve a lot of slow clients https://speakerdeck.com/sdeleuze/developing-reactive-applications-with-reactive-streams-and-java-8 📱📱 📱📱 📱📱 📱📱 📱📱 📱📱
  • 20. © 2017 Pivotal Software, Inc. All rights reserved. Use Case: Push message to client https://speakerdeck.com/sdeleuze/developing-reactive-applications-with-reactive-streams-and-java-8 💻 💬💬💬 Server-Sent Events WebSocket RabbitMQ Apache Kafka ∞
  • 21. © 2017 Pivotal Software, Inc. All rights reserved. Other Use Cases •Live (continuous) database queries •UI event handling (Android) •Big Data •Real Time Analytics •HTTP/2
  • 22. © 2017 Pivotal Software, Inc. All rights reserved. Going Reactive More for scalability and stability than for speed
  • 23. © 2017 Pivotal Software, Inc. All rights reserved. blocking ====> event-based public class IAmBlocking { public void blockingCode() { String a = callRemoteA(); String b = callRemoteB(); String c = callRemoteC(); String d = callRemoteD(); System.out.println(a+" "+b+" "+c+" "+d); } } 😅
  • 24. © 2017 Pivotal Software, Inc. All rights reserved. blocking ====> event-based public class AmIReactive { public void amIReallyReactive() { callRemoteA(a -> { callRemoteB(b -> { callRemoteC(c -> { callRemoteD(d -> println(a+" "+b+" "+c+" "+d), exd -> exd.printStackTrace()) }, exc -> exc.printStackTrace()) }, exb -> exb.printStackTrace() }, exa -> exa.printStackTrace());}} 😕
  • 25. © 2017 Pivotal Software, Inc. All rights reserved. public class IAmReactive { public void iAmReallyReactive() { when(callRemoteA(), callRemoteB(), callRemoteC(), callRemoteD()) .doOnError(e -> e.printStakcTrace()) .subscribe(t -> // Tuple4<A, B, C, D> println(t.t1 +" "+t.t2+" "+t.t3+" "+t.t4)); blocking ====> event-based 😀
  • 26. ‹#›© 2016 Pivotal Software, Inc. All rights reserved. Reactive Streams / Reactor
  • 27. © 2017 Pivotal Software, Inc. All rights reserved. Reactive Streams •Standard interfaces for asynchronous stream processing with non-blocking back pressure •De-facto standard for interoperability between reactive libraries •Implemented by http://www.reactive-streams.org/
  • 28. © 2017 Pivotal Software, Inc. All rights reserved. Reactive Streams •Standard interfaces for asynchronous stream processing with non-blocking back pressure •De-facto standard for interoperability between reactive libraries •Implemented by http://www.reactive-streams.org/ RxJava 2 Reactor Akka Streams
  • 29. ‹#›© 2016 Pivotal Software, Inc. All rights reserved. Reactive Streams has 4 interfaces public interface Publisher<T> { void subscribe(Subscriber<? super T> s); } public interface Subscription { void request(long n); void cancel(); } public interface Subscriber<T> { void onSubscribe(Subscription s); void onNext(T t); void onError(Throwable t); void onComplete(); } public interface Processor<T, R> extends Publisher<T>, Subscriber<R> {}
  • 30. © 2017 Pivotal Software, Inc. All rights reserved. Publisher Subscriber Data Flow
  • 31. © 2017 Pivotal Software, Inc. All rights reserved. Publisher Subscriber subscribe Data Flow
  • 32. © 2017 Pivotal Software, Inc. All rights reserved. Publisher Subscriber request(n) Backpressure Data Flow
  • 33. © 2017 Pivotal Software, Inc. All rights reserved. Publisher Subscriber Backpressure onNext(data) onNext(data) onNext(data) Data Flow
  • 34. © 2017 Pivotal Software, Inc. All rights reserved. Publisher Subscriber Backpressure Error|Complete Data Flow
  • 35. © 2017 Pivotal Software, Inc. All rights reserved. Back-pressure •Allows to control the amount of inflight data •Regulate the transfer between •Slow publisher and fast consumer •Fast publisher and slow consumer https://speakerdeck.com/sdeleuze/developing-reactive-applications-with-reactive-streams-and-java-8
  • 36. © 2017 Pivotal Software, Inc. All rights reserved. Reactive Streams based libraries
  • 37. © 2017 Pivotal Software, Inc. All rights reserved. Reactive Streams based libraries RxJava Reactor Akka Streams
  • 38. © 2017 Pivotal Software, Inc. All rights reserved. Reactive Streams based libraries RxJava Reactor Akka Streams
  • 39. © 2017 Pivotal Software, Inc. All rights reserved. Reactor •Natively built on top of Reactive Streams with Rx API •Developed by Pivotal •Focus on Java 8 •java.util.function.* •Duration / CompletableFuture / Stream • Lightweight Rx API with 2 types: •Flux / Mono https://projectreactor.io/
  • 40. © 2017 Pivotal Software, Inc. All rights reserved. Flux<T> Mono<T>
  • 41. © 2017 Pivotal Software, Inc. All rights reserved. Flux<T> is a Publisher<T> for 0..n elements
  • 42. © 2017 Pivotal Software, Inc. All rights reserved. Flux<T> Mono<T>
  • 43. © 2017 Pivotal Software, Inc. All rights reserved. Mono<T> is a Publisher<T> for 0..1 element
  • 44. © 2017 Pivotal Software, Inc. All rights reserved. Flux Flux<Integer> stream1 = Flux.just(1, 2, 3) .map(x -> x * 2) .filter(x -> x > 2); // 4, 6 Flux<String> stream2 = Flux.just("a", "b", "c"); Flux.zip(stream1, stream2)
 .doOneNext(t -> println(t.t1 + ":" + t.t2)) .subscribe(); Flux.merge(stream1, stream2)
 .doOneNext(x -> println(x)).subscribe();
  • 45. © 2017 Pivotal Software, Inc. All rights reserved. Flux Flux<Integer> stream1 = Flux.just(1, 2, 3) .map(x -> x * 2) .filter(x -> x > 2); // 4, 6 Flux<String> stream2 = Flux.just("a", "b", "c"); Flux.zip(stream1, stream2)
 .doOneNext(t -> println(t.t1 + ":" + t.t2)) .subscribe(); Flux.merge(stream1, stream2)
 .doOneNext(x -> println(x)).subscribe(); 4:a 6:b
  • 46. © 2017 Pivotal Software, Inc. All rights reserved. Flux Flux<Integer> stream1 = Flux.just(1, 2, 3) .map(x -> x * 2) .filter(x -> x > 2); // 4, 6 Flux<String> stream2 = Flux.just("a", "b", "c"); Flux.zip(stream1, stream2)
 .doOneNext(t -> println(t.t1 + ":" + t.t2)) .subscribe(); Flux.merge(stream1, stream2)
 .doOneNext(x -> println(x)).subscribe(); 4:a 6:b 4 6 a b c
  • 47. © 2017 Pivotal Software, Inc. All rights reserved. String location = "Tokyo, Japan"; mainService.fetchWeather(location) .timeout(Duration.ofSeconds(2)) .doOnError(ex -> logger.error(ex.getMessage())) .onErrorResume(ex -> backupService.fetchWeather(location)) .map(w -> format("Weather in %s is %s", w.location(), w.description())) .subscribe(message -> logger.info(message));
  • 48. © 2017 Pivotal Software, Inc. All rights reserved. String location = "Tokyo, Japan"; mainService.fetchWeather(location) .timeout(Duration.ofSeconds(2)) .doOnError(ex -> logger.error(ex.getMessage())) .onErrorResume(ex -> backupService.fetchWeather(location)) .map(w -> format("Weather in %s is %s", w.location(), w.description())) .subscribe(message -> logger.info(message)); Mono<Weather> fetchWeather(String city);
  • 49. © 2017 Pivotal Software, Inc. All rights reserved. String location = "Tokyo, Japan"; mainService.fetchWeather(location) .timeout(Duration.ofSeconds(2)) .doOnError(ex -> logger.error(ex.getMessage())) .onErrorResume(ex -> backupService.fetchWeather(location)) .map(w -> format("Weather in %s is %s", w.location(), w.description())) .subscribe(message -> logger.info(message)); times out and emits an error after 2 sec
  • 50. © 2017 Pivotal Software, Inc. All rights reserved. String location = "Tokyo, Japan"; mainService.fetchWeather(location) .timeout(Duration.ofSeconds(2)) .doOnError(ex -> logger.error(ex.getMessage())) .onErrorResume(ex -> backupService.fetchWeather(location)) .map(w -> format("Weather in %s is %s", w.location(), w.description())) .subscribe(message -> logger.info(message)); logs a message in case of errors
  • 51. © 2017 Pivotal Software, Inc. All rights reserved. String location = "Tokyo, Japan"; mainService.fetchWeather(location) .timeout(Duration.ofSeconds(2)) .doOnError(ex -> logger.error(ex.getMessage())) .onErrorResume(ex -> backupService.fetchWeather(location)) .map(w -> format("Weather in %s is %s", w.location(), w.description())) .subscribe(message -> logger.info(message)); switches to a different service in case of error
  • 52. © 2017 Pivotal Software, Inc. All rights reserved. String location = "Tokyo, Japan"; mainService.fetchWeather(location) .timeout(Duration.ofSeconds(2)) .doOnError(ex -> logger.error(ex.getMessage())) .onErrorResume(ex -> backupService.fetchWeather(location)) .map(w -> format("Weather in %s is %s", w.location(), w.description())) .subscribe(message -> logger.info(message)); transforms a weather instance into a String message
  • 53. © 2017 Pivotal Software, Inc. All rights reserved. String location = "Tokyo, Japan"; mainService.fetchWeather(location) .timeout(Duration.ofSeconds(2)) .doOnError(ex -> logger.error(ex.getMessage())) .onErrorResume(ex -> backupService.fetchWeather(location)) .map(w -> format("Weather in %s is %s", w.location(), w.description())) .subscribe(message -> logger.info(message)); triggers the processing of the chain
  • 54. © 2017 Pivotal Software, Inc. All rights reserved. Type comparison No value Single value Multiple values JDK CompletableFuture<Void> CompletableFuture<T> CompletableFuture<List<T>> Reactive Streams Publisher<Void> Publisher<T> Publisher<T> RxJava1 Completable Single<T> Observable<T> RxJava2 Completable
 Maybe<T> Single<T> Maybe<T> Flowable<T> (*) Observable<T> Reactor Mono<Void> (*) Mono<T> (*) Flux<T> (*) (*) ... implements Publisher
  • 55. © 2017 Pivotal Software, Inc. All rights reserved. java.util.concurrent.Flow in JDK 9 Reactive Streams JDK 9 org.reactivestreams java.util.concurrent Publisher Flow.Publisher Subscriber Flow.Subscriber Subscription Flow.Subscription Processor Flow.Processor
  • 56. © 2017 Pivotal Software, Inc. All rights reserved. Reactive Streams ↔ j.u.c.Flow // Reactive Streams (Reactor) Publisher<String> pub = Flux.just("hello"); // java.util.concurrent.Flow Flow.Publisher<String> flow = JdkFlowAdapter.publisherToFlowPublisher(pub); // java.util.concurrent.Flow Flow.Publisher<String> flow = /* ... */; // Reactive Streams (Reactor) Flux<String> pub = JdkFlowAdapter.flowPublisherToFlux(flow);
  • 57. ‹#›© 2016 Pivotal Software, Inc. All rights reserved. Spring Framework 5.0
  • 58. © 2017 Pivotal Software, Inc. All rights reserved. Spring Framework 5.0 •Performance improvements •JDK 9 - HTTP/2 •Reactive Spring •Functional APIs •Kotlin Support https://speakerdeck.com/snicoll/spring-framework-5-dot-0-themes-and-trends
  • 59. © 2017 Pivotal Software, Inc. All rights reserved. Spring Framework 5.0 •Performance improvements •JDK 9 - HTTP/2 •Reactive Spring •Functional APIs •Kotlin Support https://speakerdeck.com/snicoll/spring-framework-5-dot-0-themes-and-trends
  • 60. © 2017 Pivotal Software, Inc. All rights reserved.
  • 61. © 2017 Pivotal Software, Inc. All rights reserved. @Controller, @RequestMapping Spring MVC Servlet API Servlet Container
  • 62. © 2017 Pivotal Software, Inc. All rights reserved. @Controller, @RequestMapping Spring MVC Servlet API Servlet Container Servlet 3.1, Netty, Undertow Spring WebFlux HTTP / Reactive Streams
  • 63. © 2017 Pivotal Software, Inc. All rights reserved. @Controller, @RequestMapping Spring MVC Servlet API Servlet Container Router functions Servlet 3.1, Netty, Undertow Spring WebFlux HTTP / Reactive Streams
  • 64. © 2017 Pivotal Software, Inc. All rights reserved. Spring WebFlux
  • 65. © 2017 Pivotal Software, Inc. All rights reserved. Spring WebFlux @RestController
 public class HelloController { @GetMapping Flux<String> hello() {
 return Flux.just("Hello", "World");
 }
 }
  • 66. © 2017 Pivotal Software, Inc. All rights reserved. Spring WebFlux @RestController
 public class EchoController { @PostMapping("/echo") Flux<String> upperCase (@RequestBody Flux<String> body) {
 return body.map(String::toUpperCase);
 }
 }
  • 67. © 2017 Pivotal Software, Inc. All rights reserved. Returns Infinite-Stream @RestController
 public class HelloController { @GetMapping Flux<Integer> infinite() { Stream<Integer> s = Stream.iterate(0, i -> i + 1);
 return Flux.fromStream(s);
 }}

  • 68. © 2017 Pivotal Software, Inc. All rights reserved. Returns Infinite-Stream @RestController
 public class TweetController { @GetMapping Flux<Tweet> infiniteTweet() { Stream<Tweet> s = Stream.iterate(0, i -> i + 1) .map(i -> new Tweet("hello" + i));
 return Flux.fromStream(s);}}

  • 69. © 2017 Pivotal Software, Inc. All rights reserved. Flux<Tweet> as a Server-Sent Events curl ... -H "Accept: text/event-stream" < HTTP/1.1 200 OK < Content-Type: text/event-stream < data: {"text":"hello0"} data: {"text":"hello1"} data: {"text":"hello2"} data: {"text":"hello3"} ...
  • 70. © 2017 Pivotal Software, Inc. All rights reserved. Flux<Tweet> as a JSON Stream curl ... -H "Accept: application/stream+json" < HTTP/1.1 200 OK < Content-Type: application/stream+json < {"text":"hello0"} {"text":"hello1"} {"text":"hello2"} {"text":"hello3"} ...
  • 71. © 2017 Pivotal Software, Inc. All rights reserved. WebClient •Reactive HTTP Client
  • 72. © 2017 Pivotal Software, Inc. All rights reserved. WebClient •Reactive HTTP Client a nice RestTemplate alternative
  • 73. © 2017 Pivotal Software, Inc. All rights reserved. WebClient •Reactive HTTP Client WebClient webClient = WebClient.create(); Mono<String> s = webClient.get() .uri("http://api.example.com") .exchange() .flatMap(res -> res.bodyToMono(String.class)); a nice RestTemplate alternative
  • 74. © 2017 Pivotal Software, Inc. All rights reserved. WebClient •Reactive HTTP Client WebClient webClient = WebClient.create(); Mono<String> s = webClient.get() .uri("http://api.example.com") .retrieve() .bodyToMono(String.class);
  • 75. © 2017 Pivotal Software, Inc. All rights reserved. WebClient •Reactive HTTP Client WebClient webClient = WebClient.create(); Flux<Tweet> tweets = webClient.get() .uri("http://api.example.com") .retrieve() .bodyToFlux(Tweet.class);
  • 76. © 2017 Pivotal Software, Inc. All rights reserved. Flux<Tweet> WebClient Streaming API
  • 77. © 2017 Pivotal Software, Inc. All rights reserved. Flux<Tweet> ✔ Reactive API ✔ Can consume (infinite) streams WebClient Streaming API
  • 78. © 2017 Pivotal Software, Inc. All rights reserved. Flux.zip(tweets, issues) WebClient Streaming API REST API WebClient
  • 79. © 2017 Pivotal Software, Inc. All rights reserved. Flux.zip(tweets, issues) ✔ Chain and compose WebClient Streaming API REST API WebClient
  • 80. © 2017 Pivotal Software, Inc. All rights reserved. WebClient Web handler WebFlux
  • 81. © 2017 Pivotal Software, Inc. All rights reserved. WebClient Web handler WebFlux
  • 82. © 2017 Pivotal Software, Inc. All rights reserved. WebClient Web handler WebFlux ✔ Shared resources (event loop, buffers) ✔ Built-in mocking capabilities
  • 83. © 2017 Pivotal Software, Inc. All rights reserved. Router Functions
  • 84. © 2017 Pivotal Software, Inc. All rights reserved. Router Functions RouterFunctions<ServerResponse> routes() {
 return RouterFunctions.route( RequestPredicates.GET("/"), req -> ServerResponse.ok() .body(Mono.just("Hello","World"), String.class));
 }
  • 85. © 2017 Pivotal Software, Inc. All rights reserved. Router Functions RouterFunctions<ServerResponse> routes() {
 return RouterFunctions.route( RequestPredicates.GET("/"), req -> ServerResponse.ok() .body(Mono.just("Hello","World"), String.class));
 }
  • 86. © 2017 Pivotal Software, Inc. All rights reserved. Router Functions RouterFunctions<ServerResponse> routes() {
 return route( RequestPredicates.GET("/"), req -> ServerResponse.ok() .body(Mono.just("Hello","World"), String.class));
 }
  • 87. © 2017 Pivotal Software, Inc. All rights reserved. Router Functions RouterFunctions<ServerResponse> routes() {
 return route( RequestPredicates.GET("/"), req -> ServerResponse.ok() .body(Mono.just("Hello","World"), String.class));
 }
  • 88. © 2017 Pivotal Software, Inc. All rights reserved. Router Functions RouterFunctions<ServerResponse> routes() {
 return route(GET("/"), req -> ServerResponse.ok() .body(Mono.just("Hello","World"), String.class));
 }
  • 89. © 2017 Pivotal Software, Inc. All rights reserved. Router Functions RouterFunctions<ServerResponse> routes() {
 return route(GET("/"), req -> ServerResponse.ok() .body(Mono.just("Hello","World"), String.class));
 }
  • 90. © 2017 Pivotal Software, Inc. All rights reserved. Router Functions RouterFunctions<ServerResponse> routes() {
 return route(GET("/"), req -> ok() .body(Mono.just("Hello","World"), String.class));
 }
  • 91. © 2017 Pivotal Software, Inc. All rights reserved. Router Functions RouterFunctions<ServerResponse> routes() { return route(POST("/echo"), req -> { Mono<String> body = req .bodyToMono(String.class) .map(String::toUpperCase); return ok().body(body, String.class)); });}
  • 92. © 2017 Pivotal Software, Inc. All rights reserved. Spring Boot 2.0 Spring Boot 2.0 supports Spring 5 and WebFlux ✨
  • 93. © 2017 Pivotal Software, Inc. All rights reserved. start.spring.io
  • 94. ‹#›© 2016 Pivotal Software, Inc. All rights reserved. DEMO
  • 95. © 2017 Pivotal Software, Inc. All rights reserved. Spring MVC VS Spring WebFlux @GetMapping Flux<String> hello() {
 return Flux.just("Hello") .delayElements( ofSeconds(1));
 } @GetMapping String hello() { Thread.sleep(1000);
 return"Hello";
 } server.tomcat.max-threads=200 (default) https://gist.github.com/making/f32e81c5684a5fd810039854091dd793 Tomcat Netty
  • 96. © 2017 Pivotal Software, Inc. All rights reserved. Concurrent users = 100
  • 97. © 2017 Pivotal Software, Inc. All rights reserved. Concurrent users = 100 Transaction rate: 94.79 trans/sec Response time: 1.05 sec Live peek threads: 129
  • 98. © 2017 Pivotal Software, Inc. All rights reserved. Concurrent users = 100 Transaction rate: 94.79 trans/sec Response time: 1.05 sec Live peek threads: 129 Transaction rate: 94.88 trans/sec Response time: 1.05 sec Live peek threads: 30
  • 99. © 2017 Pivotal Software, Inc. All rights reserved. Concurrent users = 200
  • 100. © 2017 Pivotal Software, Inc. All rights reserved. Concurrent users = 200 Transaction rate: 182.65 trans/sec Response time: 1.07 sec Live peek threads: 218
  • 101. © 2017 Pivotal Software, Inc. All rights reserved. Concurrent users = 200 Transaction rate: 182.65 trans/sec Response time: 1.07 sec Live peek threads: 218 Transaction rate: 184.50 trans/sec Response time: 1.06 sec Live peek threads: 30
  • 102. © 2017 Pivotal Software, Inc. All rights reserved. Concurrent users = 300
  • 103. © 2017 Pivotal Software, Inc. All rights reserved. Concurrent users = 300 Transaction rate: 192.31 trans/sec Response time: 1.51 sec Live peek threads: 218
  • 104. © 2017 Pivotal Software, Inc. All rights reserved. Concurrent users = 300 Transaction rate: 192.31 trans/sec Response time: 1.51 sec Live peek threads: 218 Transaction rate: 278.55 trans/sec Response time: 1.04 sec Live peek threads: 30
  • 105. © 2017 Pivotal Software, Inc. All rights reserved. Blocking in WebFlux?? @GetMapping Flux<String> hello() { Thread.sleep(1000); // blocking!
 return Flux.just("Hello");
 }
  • 106. © 2017 Pivotal Software, Inc. All rights reserved. Concurrent users = 100 Transaction rate: 7.94 trans/sec Response time: 12 sec Live peek threads: 22 😱
  • 107. ‹#›© 2016 Pivotal Software, Inc. All rights reserved. End-to-End Reactive
  • 108. © 2017 Pivotal Software, Inc. All rights reserved. End-to-End Reactive Controller Repository Service Filter Publisher Publisher Publisher Publisher Publisher Publisher Publisher Publisher
  • 109. © 2017 Pivotal Software, Inc. All rights reserved. End-to-End Reactive Controller Repository Service Filter Publisher Publisher Publisher Publisher Publisher Publisher Publisher Publisher
  • 110. © 2017 Pivotal Software, Inc. All rights reserved. Spring Projects Reactor Ecosystem Spring Security Spring Data Spring Cloud Spring Integration Reactor Projects Reactor Netty Reactor Kafka Lettuce Thymeleaf
  • 111. © 2017 Pivotal Software, Inc. All rights reserved. Spring Projects Reactor Ecosystem Spring Security Spring Data Spring Cloud Spring Integration Reactor Projects Reactor Netty Reactor Kafka Lettuce MongoDB Redis Cassandra Couchbase Thymeleaf
  • 112. © 2017 Pivotal Software, Inc. All rights reserved. Spring Data Release Train Kay •Supports •Reactive Template •Reactive Repository
  • 113. © 2017 Pivotal Software, Inc. All rights reserved. Reactive Repository public interface ReactiveCrudRepository<ID,T> { Mono<T> findById(ID id); Mono<T> findById(Mono<ID> id); Flux<T> findAll(); Mono<Long> count(); Mono<T> save(T entity); Mono<T> saveAll(Publisher<T> entityStream); Mono<Void> delete(T entity) // ... }
  • 114. © 2017 Pivotal Software, Inc. All rights reserved. @Tailable for Infinite streams public interface PersonRepository extends ReactiveMongoRepository<Person,String> { @Tailable Flux<Person> findByFirstname(String firstname); }
  • 115. © 2017 Pivotal Software, Inc. All rights reserved. What about JPA/JDBC? 🤔
  • 116. © 2017 Pivotal Software, Inc. All rights reserved. What about JPA/JDBC? •JDBC is blocking ⌛ •JPA is blocking ⌛ 🤔
  • 117. © 2017 Pivotal Software, Inc. All rights reserved. What about JPA/JDBC? •JDBC is blocking ⌛ •JPA is blocking ⌛ 🤔 https://static.rainfocus.com/oracle/oow16/sess/1461693351182001EmRq/ppt/ CONF1578%2020160916.pdf https://www.voxxed.com/blog/2016/09/non-blocking-database-access/ •Non-Blocking JDBC in JDK 10?
  • 118. © 2017 Pivotal Software, Inc. All rights reserved. Switching execution context BlockingRepository<User> repo = ...; Flux<User> users = Flux.defer(() -> Flux.fromIterable(repo.findAll())) .subscribeOn(Schedulers.elastic()); Make the subscription and request happen on a particular thread
  • 119. © 2017 Pivotal Software, Inc. All rights reserved. Switching execution context Flux<User> users = ...; BlockingRepository<User> repo = ...; users.publishOn(Schedulers.elastic()) .doOneNext(u -> repo.save(u)) .then() ; Switch rest of the flux on a particular thread
  • 120. ‹#›© 2016 Pivotal Software, Inc. All rights reserved. Reactive Web Applications Example
  • 121. © 2017 Pivotal Software, Inc. All rights reserved. 💻 💻 💻 Server-Sent Events POST PUBLISH SUBSCRIBE INCR Pub/Sub Application bit.ly/jdtd1d5
  • 122. © 2017 Pivotal Software, Inc. All rights reserved. API Gateway • Rate Limiter • Web Application Firewall
  • 123. © 2017 Pivotal Software, Inc. All rights reserved. API Gateway • Rate Limiter • Web Application Firewall ✅ Spring Cloud Gateway
  • 124. © 2017 Pivotal Software, Inc. All rights reserved. Route Services in Cloud Foundry
  • 125. © 2017 Pivotal Software, Inc. All rights reserved. FFB (Frontend for Backend) 💻 📱 Frontend Backend
  • 126. © 2017 Pivotal Software, Inc. All rights reserved. Reactive Everywhere CF Java Client Firehose Nozzle Firehose Nozzle Cloud Foundry 💻 Firehose Doppler Endpoint WebSocket Rector Kafka (Publisher) Rector Kafka (Consumer) Reactor Netty Sever-Sent Event Spring WebFluxLog, Metrics
  • 127. © 2017 Pivotal Software, Inc. All rights reserved. Spring WebFlux • https://blog.ik.am/entries/417 • https://blog.ik.am/entries/418 • ...
  • 128. © 2017 Pivotal Software, Inc. All rights reserved. Thank you!! • Handson • https://github.com/reactor/lite-rx-api-hands-on • Slides • https://speakerdeck.com/simonbasle/reactor-3 • https://speakerdeck.com/sdeleuze/developing-reactive-applications-with- reactive-streams-and-java-8 • https://speakerdeck.com/snicoll/spring-framework-5-dot-0-themes-and- trends • https://speakerdeck.com/mp911de/reactive-spring • https://speakerdeck.com/christophstrobl/sneak-peek-on-spring-data-kay • https://speakerdeck.com/normanmaurer/netty-meetup-2017-san-francisco