SlideShare une entreprise Scribd logo
1  sur  128
Télécharger pour lire hors ligne
‹#›© 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

Contenu connexe

Tendances

Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3
Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3
Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3
Toshiaki Maki
 

Tendances (20)

Kafka vs Pulsar @KafkaMeetup_20180316
Kafka vs Pulsar @KafkaMeetup_20180316Kafka vs Pulsar @KafkaMeetup_20180316
Kafka vs Pulsar @KafkaMeetup_20180316
 
コンテナ未経験新人が学ぶコンテナ技術入門
コンテナ未経験新人が学ぶコンテナ技術入門コンテナ未経験新人が学ぶコンテナ技術入門
コンテナ未経験新人が学ぶコンテナ技術入門
 
Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3
Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3
Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3
 
WebRTC と Native とそれから、それから。
WebRTC と Native とそれから、それから。 WebRTC と Native とそれから、それから。
WebRTC と Native とそれから、それから。
 
Spring Boot ユーザの方のための Quarkus 入門
Spring Boot ユーザの方のための Quarkus 入門Spring Boot ユーザの方のための Quarkus 入門
Spring Boot ユーザの方のための Quarkus 入門
 
Apache Kafka 0.11 の Exactly Once Semantics
Apache Kafka 0.11 の Exactly Once SemanticsApache Kafka 0.11 の Exactly Once Semantics
Apache Kafka 0.11 の Exactly Once Semantics
 
Dockerイメージの理解とコンテナのライフサイクル
Dockerイメージの理解とコンテナのライフサイクルDockerイメージの理解とコンテナのライフサイクル
Dockerイメージの理解とコンテナのライフサイクル
 
オープンソースのAPIゲートウェイ Kong ご紹介
オープンソースのAPIゲートウェイ Kong ご紹介 オープンソースのAPIゲートウェイ Kong ご紹介
オープンソースのAPIゲートウェイ Kong ご紹介
 
[JAWS DAYS 2019] Amazon DocumentDB(with MongoDB Compatibility)入門
[JAWS DAYS 2019] Amazon DocumentDB(with MongoDB Compatibility)入門[JAWS DAYS 2019] Amazon DocumentDB(with MongoDB Compatibility)入門
[JAWS DAYS 2019] Amazon DocumentDB(with MongoDB Compatibility)入門
 
速習!論理レプリケーション ~基礎から最新動向まで~(PostgreSQL Conference Japan 2022 発表資料)
速習!論理レプリケーション ~基礎から最新動向まで~(PostgreSQL Conference Japan 2022 発表資料)速習!論理レプリケーション ~基礎から最新動向まで~(PostgreSQL Conference Japan 2022 発表資料)
速習!論理レプリケーション ~基礎から最新動向まで~(PostgreSQL Conference Japan 2022 発表資料)
 
HTTP/2 入門
HTTP/2 入門HTTP/2 入門
HTTP/2 入門
 
オープンソースで提供される第二のJVM:OpenJ9 VMとIBM Javaについて
オープンソースで提供される第二のJVM:OpenJ9 VMとIBM Javaについてオープンソースで提供される第二のJVM:OpenJ9 VMとIBM Javaについて
オープンソースで提供される第二のJVM:OpenJ9 VMとIBM Javaについて
 
SPAセキュリティ入門~PHP Conference Japan 2021
SPAセキュリティ入門~PHP Conference Japan 2021SPAセキュリティ入門~PHP Conference Japan 2021
SPAセキュリティ入門~PHP Conference Japan 2021
 
Redisの特徴と活用方法について
Redisの特徴と活用方法についてRedisの特徴と活用方法について
Redisの特徴と活用方法について
 
最適なOpenJDKディストリビューションの選び方 #codetokyo19B3 #ccc_l5
最適なOpenJDKディストリビューションの選び方 #codetokyo19B3 #ccc_l5最適なOpenJDKディストリビューションの選び方 #codetokyo19B3 #ccc_l5
最適なOpenJDKディストリビューションの選び方 #codetokyo19B3 #ccc_l5
 
JDKの選択肢とサーバーサイドでの選び方
JDKの選択肢とサーバーサイドでの選び方JDKの選択肢とサーバーサイドでの選び方
JDKの選択肢とサーバーサイドでの選び方
 
Composer bin plugin / ツールの依存管理から解放される
Composer bin plugin / ツールの依存管理から解放されるComposer bin plugin / ツールの依存管理から解放される
Composer bin plugin / ツールの依存管理から解放される
 
エンジニアのためのOSSライセンス管理~OSS管理ツールの池の水全部抜く~
エンジニアのためのOSSライセンス管理~OSS管理ツールの池の水全部抜く~エンジニアのためのOSSライセンス管理~OSS管理ツールの池の水全部抜く~
エンジニアのためのOSSライセンス管理~OSS管理ツールの池の水全部抜く~
 
コンテナの作り方「Dockerは裏方で何をしているのか?」
コンテナの作り方「Dockerは裏方で何をしているのか?」コンテナの作り方「Dockerは裏方で何をしているのか?」
コンテナの作り方「Dockerは裏方で何をしているのか?」
 
KeycloakでAPI認可に入門する
KeycloakでAPI認可に入門するKeycloakでAPI認可に入門する
KeycloakでAPI認可に入門する
 

En vedette

En vedette (12)

Spring I/O 2017 報告 ThymeleafのWebFlux対応
Spring I/O 2017 報告 ThymeleafのWebFlux対応Spring I/O 2017 報告 ThymeleafのWebFlux対応
Spring I/O 2017 報告 ThymeleafのWebFlux対応
 
Spring Boot概要
Spring Boot概要Spring Boot概要
Spring Boot概要
 
Unified JVM Logging
Unified JVM LoggingUnified JVM Logging
Unified JVM Logging
 
ArrayListをじっくり読んでみた - JavaコアSDKを読む会を社内でやって気づいたこと -
ArrayListをじっくり読んでみた - JavaコアSDKを読む会を社内でやって気づいたこと -ArrayListをじっくり読んでみた - JavaコアSDKを読む会を社内でやって気づいたこと -
ArrayListをじっくり読んでみた - JavaコアSDKを読む会を社内でやって気づいたこと -
 
ジャストシステムJava100本ノックのご紹介
ジャストシステムJava100本ノックのご紹介ジャストシステムJava100本ノックのご紹介
ジャストシステムJava100本ノックのご紹介
 
Project Jigsaw #kanjava
Project Jigsaw #kanjavaProject Jigsaw #kanjava
Project Jigsaw #kanjava
 
ぱぱっと理解するSpring Cloudの基本
ぱぱっと理解するSpring Cloudの基本ぱぱっと理解するSpring Cloudの基本
ぱぱっと理解するSpring Cloudの基本
 
とにかく楽してVue.jsでTypeScriptを使いたい
とにかく楽してVue.jsでTypeScriptを使いたいとにかく楽してVue.jsでTypeScriptを使いたい
とにかく楽してVue.jsでTypeScriptを使いたい
 
Spring 5に備えるリアクティブプログラミング入門
Spring 5に備えるリアクティブプログラミング入門Spring 5に備えるリアクティブプログラミング入門
Spring 5に備えるリアクティブプログラミング入門
 
4つの戦犯から考えるサービスづくりの失敗
4つの戦犯から考えるサービスづくりの失敗4つの戦犯から考えるサービスづくりの失敗
4つの戦犯から考えるサービスづくりの失敗
 
Spring Bootの本当の理解ポイント #jjug
Spring Bootの本当の理解ポイント #jjugSpring Bootの本当の理解ポイント #jjug
Spring Bootの本当の理解ポイント #jjug
 
AI and Machine Learning Demystified by Carol Smith at Midwest UX 2017
AI and Machine Learning Demystified by Carol Smith at Midwest UX 2017AI and Machine Learning Demystified by Carol Smith at Midwest UX 2017
AI and Machine Learning Demystified by Carol Smith at Midwest UX 2017
 

Similaire à Spring Framework 5.0による Reactive Web Application #JavaDayTokyo

Product Release Webinar- WSO2 Developer Studio 3.5
Product Release Webinar- WSO2 Developer Studio 3.5Product Release Webinar- WSO2 Developer Studio 3.5
Product Release Webinar- WSO2 Developer Studio 3.5
WSO2
 

Similaire à Spring Framework 5.0による Reactive Web Application #JavaDayTokyo (20)

Ongoing management of your PHP 7 application
Ongoing management of your PHP 7 applicationOngoing management of your PHP 7 application
Ongoing management of your PHP 7 application
 
Spring Cloud Servicesの紹介 #pcf_tokyo
Spring Cloud Servicesの紹介 #pcf_tokyoSpring Cloud Servicesの紹介 #pcf_tokyo
Spring Cloud Servicesの紹介 #pcf_tokyo
 
Data Microservices with Spring Cloud Stream, Task, and Data Flow #jsug #spri...
Data Microservices with Spring Cloud Stream, Task,  and Data Flow #jsug #spri...Data Microservices with Spring Cloud Stream, Task,  and Data Flow #jsug #spri...
Data Microservices with Spring Cloud Stream, Task, and Data Flow #jsug #spri...
 
OSMC 2018 | Distributed Tracing FAQ by Gianluca Arbezzano
OSMC 2018 | Distributed Tracing FAQ by Gianluca ArbezzanoOSMC 2018 | Distributed Tracing FAQ by Gianluca Arbezzano
OSMC 2018 | Distributed Tracing FAQ by Gianluca Arbezzano
 
Hands-On Lab: Building a Serverless Real-Time Chat Application with AWS AppSync
Hands-On Lab: Building a Serverless Real-Time Chat Application with AWS AppSyncHands-On Lab: Building a Serverless Real-Time Chat Application with AWS AppSync
Hands-On Lab: Building a Serverless Real-Time Chat Application with AWS AppSync
 
FactoryTalk® AssetCentre: Overview
FactoryTalk® AssetCentre: OverviewFactoryTalk® AssetCentre: Overview
FactoryTalk® AssetCentre: Overview
 
Hypha ROS X 星火計畫 ROS 2.0 Introduction [haochih, English ver]
Hypha ROS X 星火計畫 ROS 2.0 Introduction [haochih, English ver]Hypha ROS X 星火計畫 ROS 2.0 Introduction [haochih, English ver]
Hypha ROS X 星火計畫 ROS 2.0 Introduction [haochih, English ver]
 
Cloud Foundry Summit 2017
Cloud Foundry Summit 2017Cloud Foundry Summit 2017
Cloud Foundry Summit 2017
 
Streaming solutions for real time problems
Streaming solutions for real time problems Streaming solutions for real time problems
Streaming solutions for real time problems
 
Updates on webSpoon and other innovations from Hitachi R&D
Updates on webSpoon and other innovations from Hitachi R&DUpdates on webSpoon and other innovations from Hitachi R&D
Updates on webSpoon and other innovations from Hitachi R&D
 
Sviluppare un backend serverless in real time attraverso GraphQL
Sviluppare un backend serverless in real time attraverso GraphQLSviluppare un backend serverless in real time attraverso GraphQL
Sviluppare un backend serverless in real time attraverso GraphQL
 
Event Driven Microservices with Spring Cloud Stream #jjug_ccc #ccc_ab3
Event Driven Microservices with Spring Cloud Stream #jjug_ccc #ccc_ab3Event Driven Microservices with Spring Cloud Stream #jjug_ccc #ccc_ab3
Event Driven Microservices with Spring Cloud Stream #jjug_ccc #ccc_ab3
 
Journey to Cloud-Native: Continuous Delivery with Artificial Intelligence
Journey to Cloud-Native: Continuous Delivery with Artificial IntelligenceJourney to Cloud-Native: Continuous Delivery with Artificial Intelligence
Journey to Cloud-Native: Continuous Delivery with Artificial Intelligence
 
Product Release Webinar- WSO2 Developer Studio 3.5
Product Release Webinar- WSO2 Developer Studio 3.5Product Release Webinar- WSO2 Developer Studio 3.5
Product Release Webinar- WSO2 Developer Studio 3.5
 
Webinar: End-to-End CI/CD with GitLab and DC/OS
Webinar: End-to-End CI/CD with GitLab and DC/OSWebinar: End-to-End CI/CD with GitLab and DC/OS
Webinar: End-to-End CI/CD with GitLab and DC/OS
 
SplunkLive! London 2017 - DevOps Powered by Splunk
SplunkLive! London 2017 - DevOps Powered by SplunkSplunkLive! London 2017 - DevOps Powered by Splunk
SplunkLive! London 2017 - DevOps Powered by Splunk
 
APIdays 2016 - The State of Web API Languages
APIdays 2016  - The State of Web API LanguagesAPIdays 2016  - The State of Web API Languages
APIdays 2016 - The State of Web API Languages
 
Syncfusion: Flat License Options
Syncfusion: Flat License OptionsSyncfusion: Flat License Options
Syncfusion: Flat License Options
 
Cytoscape: Now and Future
Cytoscape: Now and FutureCytoscape: Now and Future
Cytoscape: Now and Future
 
SpringOnePlatform2017 recap
SpringOnePlatform2017 recapSpringOnePlatform2017 recap
SpringOnePlatform2017 recap
 

Plus de Toshiaki Maki

マイクロサービスに必要な技術要素はすべてSpring Cloudにある #DO07
マイクロサービスに必要な技術要素はすべてSpring Cloudにある #DO07マイクロサービスに必要な技術要素はすべてSpring Cloudにある #DO07
マイクロサービスに必要な技術要素はすべてSpring Cloudにある #DO07
Toshiaki Maki
 
実例で学ぶ、明日から使えるSpring Boot Tips #jsug
実例で学ぶ、明日から使えるSpring Boot Tips #jsug実例で学ぶ、明日から使えるSpring Boot Tips #jsug
実例で学ぶ、明日から使えるSpring Boot Tips #jsug
Toshiaki Maki
 

Plus de Toshiaki Maki (20)

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

Dernier

Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
vu2urc
 

Dernier (20)

TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Evaluating the top large language models.pdf
Evaluating the top large language models.pdfEvaluating the top large language models.pdf
Evaluating the top large language models.pdf
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 

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