Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Spring Framework 5.0による Reactive Web Application #JavaDayTokyo

17,990 views

Published on

Spring Framework 5.0による Reactive Web Application

Published in: Technology

Spring Framework 5.0による Reactive Web Application #JavaDayTokyo

  1. 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. 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. 3. © 2017 Pivotal Software, Inc. All rights reserved. Reactive???
  4. 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. 5. © 2017 Pivotal Software, Inc. All rights reserved. Sync / Blocking https://speakerdeck.com/simonbasle/reactor-3
  6. 6. © 2017 Pivotal Software, Inc. All rights reserved. Sync / Blocking https://speakerdeck.com/simonbasle/reactor-3 I/O main thread processing resumes
  7. 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. 8. © 2017 Pivotal Software, Inc. All rights reserved. Async & Blocking https://speakerdeck.com/simonbasle/reactor-3
  9. 9. © 2017 Pivotal Software, Inc. All rights reserved. Async & Blocking https://speakerdeck.com/simonbasle/reactor-3 main thread wait & join
  10. 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. 11. © 2017 Pivotal Software, Inc. All rights reserved. Async & Non-Blocking
  12. 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. 13. © 2017 Pivotal Software, Inc. All rights reserved. Blocking + Thread pools (Servlet) HTTP request HTTP response 📖⏳ ⚙⏳ ✍⏳ Thread
  14. 14. © 2017 Pivotal Software, Inc. All rights reserved. Non-blocking and event-loop (Netty) IO Selector Thread Worker Threads 🔄 📖⚙ ⚙ ✍ ✍ ⚙ 📖⚙ 📖 ✍ ✍ ⚙ ⚙ ✍ 📖 📖🔄 🔄 🔄 🔄
  15. 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. 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. 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. 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. 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. 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. 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. 22. © 2017 Pivotal Software, Inc. All rights reserved. Going Reactive More for scalability and stability than for speed
  23. 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. 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. 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. 26. ‹#›© 2016 Pivotal Software, Inc. All rights reserved. Reactive Streams / Reactor
  27. 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. 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. 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. 30. © 2017 Pivotal Software, Inc. All rights reserved. Publisher Subscriber Data Flow
  31. 31. © 2017 Pivotal Software, Inc. All rights reserved. Publisher Subscriber subscribe Data Flow
  32. 32. © 2017 Pivotal Software, Inc. All rights reserved. Publisher Subscriber request(n) Backpressure Data Flow
  33. 33. © 2017 Pivotal Software, Inc. All rights reserved. Publisher Subscriber Backpressure onNext(data) onNext(data) onNext(data) Data Flow
  34. 34. © 2017 Pivotal Software, Inc. All rights reserved. Publisher Subscriber Backpressure Error|Complete Data Flow
  35. 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. 36. © 2017 Pivotal Software, Inc. All rights reserved. Reactive Streams based libraries
  37. 37. © 2017 Pivotal Software, Inc. All rights reserved. Reactive Streams based libraries RxJava Reactor Akka Streams
  38. 38. © 2017 Pivotal Software, Inc. All rights reserved. Reactive Streams based libraries RxJava Reactor Akka Streams
  39. 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. 40. © 2017 Pivotal Software, Inc. All rights reserved. Flux<T> Mono<T>
  41. 41. © 2017 Pivotal Software, Inc. All rights reserved. Flux<T> is a Publisher<T> for 0..n elements
  42. 42. © 2017 Pivotal Software, Inc. All rights reserved. Flux<T> Mono<T>
  43. 43. © 2017 Pivotal Software, Inc. All rights reserved. Mono<T> is a Publisher<T> for 0..1 element
  44. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 57. ‹#›© 2016 Pivotal Software, Inc. All rights reserved. Spring Framework 5.0
  58. 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. 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. 60. © 2017 Pivotal Software, Inc. All rights reserved.
  61. 61. © 2017 Pivotal Software, Inc. All rights reserved. @Controller, @RequestMapping Spring MVC Servlet API Servlet Container
  62. 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. 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. 64. © 2017 Pivotal Software, Inc. All rights reserved. Spring WebFlux
  65. 65. © 2017 Pivotal Software, Inc. All rights reserved. Spring WebFlux @RestController
 public class HelloController { @GetMapping Flux<String> hello() {
 return Flux.just("Hello", "World");
 }
 }
  66. 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. 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. 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. 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. 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. 71. © 2017 Pivotal Software, Inc. All rights reserved. WebClient •Reactive HTTP Client
  72. 72. © 2017 Pivotal Software, Inc. All rights reserved. WebClient •Reactive HTTP Client a nice RestTemplate alternative
  73. 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. 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. 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. 76. © 2017 Pivotal Software, Inc. All rights reserved. Flux<Tweet> WebClient Streaming API
  77. 77. © 2017 Pivotal Software, Inc. All rights reserved. Flux<Tweet> ✔ Reactive API ✔ Can consume (infinite) streams WebClient Streaming API
  78. 78. © 2017 Pivotal Software, Inc. All rights reserved. Flux.zip(tweets, issues) WebClient Streaming API REST API WebClient
  79. 79. © 2017 Pivotal Software, Inc. All rights reserved. Flux.zip(tweets, issues) ✔ Chain and compose WebClient Streaming API REST API WebClient
  80. 80. © 2017 Pivotal Software, Inc. All rights reserved. WebClient Web handler WebFlux
  81. 81. © 2017 Pivotal Software, Inc. All rights reserved. WebClient Web handler WebFlux
  82. 82. © 2017 Pivotal Software, Inc. All rights reserved. WebClient Web handler WebFlux ✔ Shared resources (event loop, buffers) ✔ Built-in mocking capabilities
  83. 83. © 2017 Pivotal Software, Inc. All rights reserved. Router Functions
  84. 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. 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. 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. 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. 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. 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. 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. 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. 92. © 2017 Pivotal Software, Inc. All rights reserved. Spring Boot 2.0 Spring Boot 2.0 supports Spring 5 and WebFlux ✨
  93. 93. © 2017 Pivotal Software, Inc. All rights reserved. start.spring.io
  94. 94. ‹#›© 2016 Pivotal Software, Inc. All rights reserved. DEMO
  95. 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. 96. © 2017 Pivotal Software, Inc. All rights reserved. Concurrent users = 100
  97. 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. 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. 99. © 2017 Pivotal Software, Inc. All rights reserved. Concurrent users = 200
  100. 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. 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. 102. © 2017 Pivotal Software, Inc. All rights reserved. Concurrent users = 300
  103. 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. 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. 105. © 2017 Pivotal Software, Inc. All rights reserved. Blocking in WebFlux?? @GetMapping Flux<String> hello() { Thread.sleep(1000); // blocking!
 return Flux.just("Hello");
 }
  106. 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. 107. ‹#›© 2016 Pivotal Software, Inc. All rights reserved. End-to-End Reactive
  108. 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. 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. 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. 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. 112. © 2017 Pivotal Software, Inc. All rights reserved. Spring Data Release Train Kay •Supports •Reactive Template •Reactive Repository
  113. 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. 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. 115. © 2017 Pivotal Software, Inc. All rights reserved. What about JPA/JDBC? 🤔
  116. 116. © 2017 Pivotal Software, Inc. All rights reserved. What about JPA/JDBC? •JDBC is blocking ⌛ •JPA is blocking ⌛ 🤔
  117. 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. 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. 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. 120. ‹#›© 2016 Pivotal Software, Inc. All rights reserved. Reactive Web Applications Example
  121. 121. © 2017 Pivotal Software, Inc. All rights reserved. 💻 💻 💻 Server-Sent Events POST PUBLISH SUBSCRIBE INCR Pub/Sub Application bit.ly/jdtd1d5
  122. 122. © 2017 Pivotal Software, Inc. All rights reserved. API Gateway • Rate Limiter • Web Application Firewall
  123. 123. © 2017 Pivotal Software, Inc. All rights reserved. API Gateway • Rate Limiter • Web Application Firewall ✅ Spring Cloud Gateway
  124. 124. © 2017 Pivotal Software, Inc. All rights reserved. Route Services in Cloud Foundry
  125. 125. © 2017 Pivotal Software, Inc. All rights reserved. FFB (Frontend for Backend) 💻 📱 Frontend Backend
  126. 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. 127. © 2017 Pivotal Software, Inc. All rights reserved. Spring WebFlux • https://blog.ik.am/entries/417 • https://blog.ik.am/entries/418 • ...
  128. 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

×