SlideShare une entreprise Scribd logo
1  sur  81
Télécharger pour lire hors ligne
REACTIVE FAULT TOLERANT PROGRAMMING

with Hystrix and RxJava
Matt Stine (@mstine)
Matt StineSenior Product Manager - Pivotal Software, Inc.
Author of:
http://bit.ly/cloud-native-book
© Copyright 2015 Pivotal. All rights reserved. 3
MICROSERVICES!!!!!
Typical Microservices Architecture
ÂAPI
ÂAPI
!
!
!
µS
µS
µS
µS
µS
Trace a Request
ÂAPI
ÂAPI
!
!
!
µS
µS
µS
µS
µS
Consider this subgraph…
ÂAPI
µS
µS
public ResponseEntity<Foo> handleIncomingRequest() {
Foo foo = new Foo();
foo.addPart(serviceOne.getContributionToFoo());
foo.addPart(serviceTwo.getContributionToFoo());
return new ResponseEntity<>(foo, HttpStatus.OK);
}
Block and wait!
Meanwhile in Service Two…
!
!
µS µS
µS
public ResponseEntity<FooPart> handleIncomingRequest() {
FooPart fooPart = new FooPart();
fooPart.addSubPart(serviceThree.getContributionToFooPart());
fooPart.addSubPart(serviceFour.getContributionToFooPart());
return new ResponseEntity<>(fooPart, HttpStatus.OK);
}
Block and wait!
BUT

DAT

LATENCY

THO
Futures!
ExecutorService executor = createExecutorService();
public ResponseEntity<Foo> handleIncomingRequest() {
Foo foo = new Foo();
Future<FooPart> partOne = executor.submit(new CallToServiceOne());
Future<FooPart> partTwo = executor.submit(new CallToServiceTwo());
foo.addPart(partOne.get());
foo.addPart(partTwo.get());
return new ResponseEntity<>(foo, HttpStatus.OK);
}
The service graph changes…
public ResponseEntity<Foo> handleIncomingRequest() {
Foo foo = new Foo();
Future<FooPart> partOne = executor.submit(new CallToServiceOne());
Future<FooPart> partTwo = executor.submit(
new CallToServiceTwo(partOne.get()));
Future<FooPart> partThree = executor.submit(new CallToServiceThree())
foo.addPart(partTwo.get());
foo.addPart(partThree.get());
return new ResponseEntity<>(foo, HttpStatus.OK);
}
Block and wait!
Blocked until

two completes!
CompletableFutures
public ResponseEntity<Foo> handleIncomingRequest() {
Foo foo = new Foo();
CompletableFuture<FooPart> partTwo = CompletableFuture.supplyAsync(
new CallToServiceOne())
.thenApplyAsync(new CallToServiceTwo());
CompletableFuture<FooPart> partThree = CompletableFuture.supplyAsync(
new CallToServiceThree());
foo.addPart(partTwo.get());
foo.addPart(partThree.get());
return new ResponseEntity<>(foo, HttpStatus.OK);
}
As composition becomes more complex,
CompletableFuture API is lacking…
An API like this would be nice…
List<Integer> transactionsIds =
transactions.stream()
.filter(t -> t.getType() == Transaction.GROCERY)
.sorted(comparing(Transaction::getValue).reversed())
.map(Transaction::getId)
.collect(toList());
Hold that thought…
RESPONSIVE
RESILIENT
ELASTIC
MESSAGE-DRIVEN
RxJava
http://reactivex.io
https://github.com/ReactiveX/RxJava
Observer Pattern
Hello Observable
Observable<Integer> observableString = Observable.create(
new Observable.OnSubscribe<Integer>() {
public void call(Subscriber<? super Integer> subscriber) {
for (int i = 0; i < 5; i++) {
subscriber.onNext(i);
}
subscriber.onCompleted();
}
});
Emit an item!
I’m done emitting items!
Observable<Integer> observableString = Observable.create(
subscriber -> {
for (int i = 0; i < 5; i++) {
subscriber.onNext(i);
}
subscriber.onCompleted();
});
Hello Observable (JDK 8)
Hello Subscription
Subscription subscription = observableString.subscribe(
new Observer<Integer>() {
public void onCompleted() {
System.out.println("Observable completed");
}
public void onError(Throwable throwable) {
System.out.println("Oh noes! Something wrong happened!");
}
public void onNext(Integer integer) {
System.out.println("Item is " + integer);
}
});
Hello Subscription (JDK 8)
Subscription subscription = observableString.subscribe(
item -> System.out.println("Lambda says: " + item),
throwable -> System.out.println("Lambda says: Oh noes! Something wrong happened!"),
() -> System.out.println("Lambda says: Observable completed"));
All together now…
Observable.create(
subscriber -> {
for (int i = 0; i < 5; i++) {
subscriber.onNext(i);
}
subscriber.onCompleted();
}).subscribe(
item -> System.out.println("Lambda says: " + item),
throwable -> System.out.println("Lambda says: Oh noes! Something wrong happened!"),
() -> System.out.println("Lambda says: Observable completed"));
Back to Our Service Graph
ÂAPI
ÂAPI
!
!
!
µS
µS
µS
µS
µS
With Callables
Observable.fromCallable(new CallToServiceOne())
.flatMap(serviceOneResult -> Observable.fromCallable(
new CallToServiceTwo(serviceOneResult)))
.zipWith(Observable.fromCallable(
new CallToServiceThree()),
(FooPart resultFromServiceTwo, FooPart resultFromServiceThree) -> {
Foo foo = new Foo();
foo.addPart(resultFromServiceTwo);
foo.addPart(resultFromServiceThree);
return foo;
}).subscribe(System.out::println);
With Lambdas
Observable.<FooPart>create(serviceOneSubscriber -> {
serviceOneSubscriber.onNext(new FooPart("one"));
serviceOneSubscriber.onCompleted();
}).flatMap(serviceOneResult -> Observable.<FooPart>create(serviceTwoSubscriber -> {
serviceTwoSubscriber.onNext(new FooPart(serviceOneResult + " + two"));
serviceTwoSubscriber.onCompleted();
})).zipWith(Observable.<FooPart>create(serviceThreeSubscriber -> {
serviceThreeSubscriber.onNext(new FooPart("three"));
serviceThreeSubscriber.onCompleted();
}), (resultFromServiceTwo, resultFromServiceThree) -> {
Foo foo = new Foo();
foo.addPart(resultFromServiceTwo);
foo.addPart(resultFromServiceThree);
return foo;
}).subscribe(System.out::println);
RxJava Operator Tour
Combining Observables
• merge() - combine multiple Observables so they act like a single Observable
• zip() - combine sets of items from multiple Observables via a Function, and emit the
results
https://github.com/ReactiveX/RxJava/wiki/Combining-Observables
Conditionals
• doWhile() - emit Observable sequence, then repeat the sequence as long as the
condition remains true
• ifThen() - only emit Observable sequence if a condition is true, otherwise emit empty or
default sequence
• skipUntil() - discard emitted items from Observable until a second Observable emits an
item, then emit the remainder
• takeUntil() - emit items from Observable until a second Observable emits or notifies
https://github.com/ReactiveX/RxJava/wiki/Conditional-and-Boolean-Operators
Boolean Operators
• all() - do all the emitted items meet some criteria?
• contains() - does the Observable emit a particular item?
• exists() / isEmpty() - does an Observable emit items or not?
• sequenceEqual() - do two Observables emit equal sequences?
https://github.com/ReactiveX/RxJava/wiki/Conditional-and-Boolean-Operators
Filtering
• filter() - filter Observable with a predicate
• take(n) - emit only the first n items
• skip(n) - ignore the first n items emitted
• sample() - sample items according to a periodic interval
https://github.com/ReactiveX/RxJava/wiki/Filtering-Observables
Transforming
• map() - apply a function to each emitted item
• flatMap() - transform items emitted by Observable into Observables, then flatten
• scan() - apply a function to each emitted item, then feedback result and repeat
• buffer() - gather emitted items into bundles and emit the bundles
https://github.com/ReactiveX/RxJava/wiki/Transforming-Observables
Backpressure!
– https://github.com/ReactiveX/RxJava/wiki/Backpressure
“…a quickly-producing Observable meets a slow-consuming observer.”
Backpressure Observable
Observable.create(subscriber -> IntStream.iterate(0, i -> i + 2)
.forEach(value -> subscriber.onNext(value)))
.onBackpressureBuffer()
.subscribe(new BackpressureSubscriber());
Backpressure Subscriber
public class BackpressureSubscriber extends Subscriber<Object> {
private int counter = 0;
@Override
public void onStart() {
request(10);
}
@Override
public void onNext(Object o) {
if (counter < 9) {
processItem(o);
} else {
processItem(o);
resetCounter();
request(10);
}
}
Please only give me this many!
OK, I can handle more now.
Backpressure Subscriber
private void processItem(Object o) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
counter++;
System.out.println(counter + " : " + o);
}
private void resetCounter() {
counter = 0;
System.out.println("FETCH MORE");
}
Simulate Processing Latency
}
WHAT ABOUT FAILURES?
What happens if we cut here?
ÂAPI
ÂAPI
!
!
!
µS
µS
µS
µS
µS
Or here?
ÂAPI
ÂAPI
!
!
!
µS
µS
µS
µS
µS
Or here?
ÂAPI
ÂAPI
!
!
!
µS
µS
µS
µS
µS
500 INTERNAL SERVER ERROR
Fault Tolerance at Netflix
http://techblog.netflix.com/2012/02/fault-tolerance-in-high-volume.html
Without taking steps to ensure fault tolerance, 30 dependencies
each with 99.99% uptime would result in 2+ hours downtime/
month (99.99%30
= 99.7% uptime = 2.16 hours/month).
http://techblog.netflix.com/2012/02/fault-tolerance-in-high-volume.html
The Circuit Breaker Pattern
Circuit Breaker State Machine
Closed
on call / pass through
call succeeds / reset count
call fails / count failure
threshold reached / trip breaker
Open
on call / fail
on timeout / attempt reset
Half-Open
on call / pass through
call succeeds / reset
call fails / trip breaker
trip
breaker
trip
breaker
attempt
reset
reset
https://github.com/Netflix/Hystrix
Hello Hystrix World
public class CommandHelloWorld extends HystrixCommand<String> {
private final String name;
public CommandHelloWorld(String name) {
super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"));
this.name = name;
}
@Override
protected String run() {
// Do something that might fail...
return "Hello " + name + "!";
}
}
Synchronous
String s = new CommandHelloWorld("Bob").execute();
Block and wait!
Asynchronous
Future<String> s = new CommandHelloWorld("Bob").queue();
Reactive!
Observable<String> s = new CommandHelloWorld("Bob").observe();
s.subscribe(val -> {
// value emitted here
});
Fail Fast
public class CommandThatFailsFast extends HystrixCommand<String> {
private final boolean throwException;
public CommandThatFailsFast(boolean throwException) {
super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"));
this.throwException = throwException;
}
@Override
protected String run() {
if (throwException) {
throw new RuntimeException("failure from CommandThatFailsFast");
} else {
return "success";
}
}
}
Fail Silently
public class CommandThatFailsSilently extends HystrixCommand<String> {
private final boolean throwException;
public CommandThatFailsSilently(boolean throwException) {
super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"));
this.throwException = throwException;
}
@Override
protected String run() {
if (throwException) {
throw new RuntimeException("failure from CommandThatFailsSilently");
} else {
return "success";
}
}
@Override
protected String getFallback() {
return null;
}
}
Fallback behavior!
}
Static Fallback
@Override
protected String run() {
if (throwException) {
throw new RuntimeException("failure from CommandWithStaticFallback");
} else {
return "success";
}
}
@Override
protected String getFallback() {
return "fallback";
}
Fallback behavior!
}
Stubbed Fallback
@Override
protected UserAccount run() {
// fetch UserAccount from remote service
// return UserAccountClient.getAccount(customerId);
throw new RuntimeException("forcing failure for example");
}
@Override
protected UserAccount getFallback() {
/**
* Return stubbed fallback with some static defaults, placeholders,
* and an injected value 'countryCodeFromGeoLookup' that we'll use
* instead of what we would have retrieved from the remote service.
*/
return new UserAccount(customerId, "Unknown Name",
countryCodeFromGeoLookup, true, true, false);
}
Fallback behavior!
}
Fallback: Cache via Network
Primary + Secondary with Fallback
How Hystrix Works!
Hystrix Dashboard
A Failing Circuit
RxJava + Hystrix
With Callables
Observable.fromCallable(new CallToServiceOne())
.flatMap(serviceOneResult -> Observable.fromCallable(
new CallToServiceTwo(serviceOneResult)))
.zipWith(Observable.fromCallable(
new CallToServiceThree()),
(FooPart resultFromServiceTwo, FooPart resultFromServiceThree) -> {
Foo foo = new Foo();
foo.addPart(resultFromServiceTwo);
foo.addPart(resultFromServiceThree);
return foo;
}).subscribe(System.out::println);
With HystrixObservableCommands
new CallToServiceOneCommand("callToServiceOne").observe()
.flatMap(serviceOneResult ->
new CallToServiceTwoCommand("callToServiceTwo", serviceOneResult).observe())
.zipWith(new CallToServiceThreeCommand("callToServiceThree").observe(),
(FooPart resultFromServiceTwo, FooPart resultFromServiceThree) -> {
Foo foo = new Foo();
foo.addPart(resultFromServiceTwo);
foo.addPart(resultFromServiceThree);
return foo;
}).subscribe(System.out::println);
Call to Service One
public class CallToServiceOneCommand extends HystrixObservableCommand<FooPart> {
public CallToServiceOneCommand(String name) {
super(HystrixCommandGroupKey.Factory.asKey(name));
}
@Override
protected Observable<FooPart> construct() {
return Observable.create(new Observable.OnSubscribe<FooPart>() {
@Override
public void call(Subscriber<? super FooPart> subscriber) {
subscriber.onNext(new FooPart("one"));
subscriber.onCompleted();
}
});
}
}
public class CallToServiceTwoCommand extends HystrixObservableCommand<FooPart> {
private final FooPart dependencyFromServiceOne;
private CallToServiceTwoCommand(String name, FooPart dependencyFromServiceOne) {
super(HystrixCommandGroupKey.Factory.asKey(name));
this.dependencyFromServiceOne = dependencyFromServiceOne;
}
@Override
protected Observable<FooPart> construct() {
return Observable.create(new Observable.OnSubscribe<FooPart>() {
@Override
public void call(Subscriber<? super FooPart> subscriber) {
subscriber.onNext(new FooPart(dependencyFromServiceOne + " + two"));
subscriber.onCompleted();
}
});
}
}
Call to Service Two
Spring Cloud
http://cloud.spring.io
Hystrix with Spring Cloud
@SpringBootApplication
@EnableDiscoveryClient
@EnableCircuitBreaker
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Hystrix with Spring Cloud
@Service
@EnableConfigurationProperties(FortuneProperties.class)
public class FortuneService {
@Autowired
FortuneProperties fortuneProperties;
@Autowired
RestTemplate restTemplate;
@HystrixCommand(fallbackMethod = "fallbackFortune")
public Fortune randomFortune() {
return restTemplate.getForObject("http://fortunes/random", Fortune.class);
}
private Fortune fallbackFortune() {
return new Fortune(42L, fortuneProperties.getFallbackFortune());
}
}
}
RxJava + Hystrix + Spring Cloud
@HystrixCommand(fallbackMethod = "stubMovie")
public Observable<Movie> getMovie(final String mlId) {
return new ObservableResult<Movie>() {
@Override
public Movie invoke() {
return restTemplate.getForObject(
"http://springbox-catalog/movies/{mlId}", Movie.class, mlId);
}
};
}
private Movie stubMovie(final String mlId) {
Movie stub = new Movie();
stub.setMlId(mlId);
stub.setTitle("Interesting...the wrong title. Sssshhhh!");
return stub;
}
RxJava + Hystrix + Spring Cloud
@RequestMapping("/movie/{mlId}")
public Observable<MovieDetails> movieDetails(@PathVariable String mlId) {
return Observable.zip(
catalogIntegrationService.getMovie(mlId),
reviewsIntegrationService.reviewsFor(mlId),
recommendationsIntegrationService.getRecommendations(mlId),
(movie, reviews, recommendations) -> {
MovieDetails movieDetails = new MovieDetails();
movieDetails.setMlId(movie.getMlId());
movieDetails.setTitle(movie.getTitle());
movieDetails.setReviews(reviews);
movieDetails.setRecommendations(recommendations);
return movieDetails;
}
);
}
Reactive Landscape
Reactive Streams
http://www.reactive-streams.org/
Project Reactor
https://projectreactor.io/
JDK 9 Flow API
http://download.java.net/jdk9/docs/api/java/util/concurrent/Flow.html
REACTIVE FAULT TOLERANT PROGRAMMING

with Hystrix and RxJava
Get your FREE eBook!
http://bit.ly/cloud-native-book
Matt StineSenior Product Manager - Pivotal Software, Inc.

@mstine

matt.stine@gmail.com

http://mattstine.com

Contenu connexe

Tendances

Tendances (20)

Rxjava 介紹與 Android 中的 RxJava
Rxjava 介紹與 Android 中的 RxJavaRxjava 介紹與 Android 中的 RxJava
Rxjava 介紹與 Android 中的 RxJava
 
Introduction to Retrofit and RxJava
Introduction to Retrofit and RxJavaIntroduction to Retrofit and RxJava
Introduction to Retrofit and RxJava
 
Bulding a reactive game engine with Spring 5 & Couchbase
Bulding a reactive game engine with Spring 5 & CouchbaseBulding a reactive game engine with Spring 5 & Couchbase
Bulding a reactive game engine with Spring 5 & Couchbase
 
rx-java-presentation
rx-java-presentationrx-java-presentation
rx-java-presentation
 
Springを用いた社内ライブラリ開発
Springを用いた社内ライブラリ開発Springを用いた社内ライブラリ開発
Springを用いた社内ライブラリ開発
 
Javascript Promises/Q Library
Javascript Promises/Q LibraryJavascript Promises/Q Library
Javascript Promises/Q Library
 
The Road To Reactive with RxJava JEEConf 2016
The Road To Reactive with RxJava JEEConf 2016The Road To Reactive with RxJava JEEConf 2016
The Road To Reactive with RxJava JEEConf 2016
 
Avoiding Callback Hell with Async.js
Avoiding Callback Hell with Async.jsAvoiding Callback Hell with Async.js
Avoiding Callback Hell with Async.js
 
Reactive Java (GeeCON 2014)
Reactive Java (GeeCON 2014)Reactive Java (GeeCON 2014)
Reactive Java (GeeCON 2014)
 
Spring Boot Actuator 2.0 & Micrometer
Spring Boot Actuator 2.0 & MicrometerSpring Boot Actuator 2.0 & Micrometer
Spring Boot Actuator 2.0 & Micrometer
 
RxJava on Android
RxJava on AndroidRxJava on Android
RxJava on Android
 
Docker and jvm. A good idea?
Docker and jvm. A good idea?Docker and jvm. A good idea?
Docker and jvm. A good idea?
 
Introduction to Reactive Java
Introduction to Reactive JavaIntroduction to Reactive Java
Introduction to Reactive Java
 
Introduction to rx java for android
Introduction to rx java for androidIntroduction to rx java for android
Introduction to rx java for android
 
Middy.js - A powerful Node.js middleware framework for your lambdas​
Middy.js - A powerful Node.js middleware framework for your lambdas​ Middy.js - A powerful Node.js middleware framework for your lambdas​
Middy.js - A powerful Node.js middleware framework for your lambdas​
 
Intro to RxJava/RxAndroid - GDG Munich Android
Intro to RxJava/RxAndroid - GDG Munich AndroidIntro to RxJava/RxAndroid - GDG Munich Android
Intro to RxJava/RxAndroid - GDG Munich Android
 
Project Reactor Now and Tomorrow
Project Reactor Now and TomorrowProject Reactor Now and Tomorrow
Project Reactor Now and Tomorrow
 
Reactive programming on Android
Reactive programming on AndroidReactive programming on Android
Reactive programming on Android
 
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
 
Intro to Functional Programming with RxJava
Intro to Functional Programming with RxJavaIntro to Functional Programming with RxJava
Intro to Functional Programming with RxJava
 

En vedette

台中青商微講堂 2015 雲端工具活用術 by Lala
台中青商微講堂 2015 雲端工具活用術 by Lala台中青商微講堂 2015 雲端工具活用術 by Lala
台中青商微講堂 2015 雲端工具活用術 by Lala
LaLa Mai
 

En vedette (20)

Resilient Architecture
Resilient ArchitectureResilient Architecture
Resilient Architecture
 
Cloud Foundry: The Best Place to Run Microservices
Cloud Foundry: The Best Place to Run MicroservicesCloud Foundry: The Best Place to Run Microservices
Cloud Foundry: The Best Place to Run Microservices
 
Resilience with Hystrix
Resilience with HystrixResilience with Hystrix
Resilience with Hystrix
 
Reactive programming and Hystrix fault tolerance by Max Myslyvtsev
Reactive programming and Hystrix fault tolerance by Max MyslyvtsevReactive programming and Hystrix fault tolerance by Max Myslyvtsev
Reactive programming and Hystrix fault tolerance by Max Myslyvtsev
 
ZOTO
ZOTOZOTO
ZOTO
 
Lattice: A Cloud-Native Platform for Your Spring Applications
Lattice: A Cloud-Native Platform for Your Spring ApplicationsLattice: A Cloud-Native Platform for Your Spring Applications
Lattice: A Cloud-Native Platform for Your Spring Applications
 
Agile Development with OSGi
Agile Development with OSGiAgile Development with OSGi
Agile Development with OSGi
 
Iguazú: A Long-Running Job Scheduler using Docker and Mesos
Iguazú: A Long-Running Job Scheduler using Docker and MesosIguazú: A Long-Running Job Scheduler using Docker and Mesos
Iguazú: A Long-Running Job Scheduler using Docker and Mesos
 
Cloud Foundry Roadmap in 2016
Cloud Foundry Roadmap in 2016Cloud Foundry Roadmap in 2016
Cloud Foundry Roadmap in 2016
 
Gradle起步走: 以CLI Application為例 @ JCConf 2014
Gradle起步走: 以CLI Application為例 @ JCConf 2014Gradle起步走: 以CLI Application為例 @ JCConf 2014
Gradle起步走: 以CLI Application為例 @ JCConf 2014
 
Garden introduction for dea users public
Garden introduction for dea users   publicGarden introduction for dea users   public
Garden introduction for dea users public
 
Consumer Driven Contracts for microservices
Consumer Driven Contracts for microservicesConsumer Driven Contracts for microservices
Consumer Driven Contracts for microservices
 
Devoxx 2016: A Developer's Guide to OCI and runC
Devoxx 2016: A Developer's Guide to OCI and runCDevoxx 2016: A Developer's Guide to OCI and runC
Devoxx 2016: A Developer's Guide to OCI and runC
 
I Love APIs 2015: Scaling Mobile-focused Microservices at Verizon
I Love APIs 2015: Scaling Mobile-focused Microservices at VerizonI Love APIs 2015: Scaling Mobile-focused Microservices at Verizon
I Love APIs 2015: Scaling Mobile-focused Microservices at Verizon
 
Futures and Rx Observables: powerful abstractions for consuming web services ...
Futures and Rx Observables: powerful abstractions for consuming web services ...Futures and Rx Observables: powerful abstractions for consuming web services ...
Futures and Rx Observables: powerful abstractions for consuming web services ...
 
Reactive Jersey Client
Reactive Jersey ClientReactive Jersey Client
Reactive Jersey Client
 
从玩具到生产 - Cloud Foundry 上海峰会2015年
从玩具到生产 - Cloud Foundry 上海峰会2015年从玩具到生产 - Cloud Foundry 上海峰会2015年
从玩具到生产 - Cloud Foundry 上海峰会2015年
 
RxJava - introduction & design
RxJava - introduction & designRxJava - introduction & design
RxJava - introduction & design
 
Establish The Core of Cloud Computing Application by Using Hazelcast (Chinese)
Establish The Core of  Cloud Computing Application  by Using Hazelcast (Chinese)Establish The Core of  Cloud Computing Application  by Using Hazelcast (Chinese)
Establish The Core of Cloud Computing Application by Using Hazelcast (Chinese)
 
台中青商微講堂 2015 雲端工具活用術 by Lala
台中青商微講堂 2015 雲端工具活用術 by Lala台中青商微講堂 2015 雲端工具活用術 by Lala
台中青商微講堂 2015 雲端工具活用術 by Lala
 

Similaire à Reactive Fault Tolerant Programming with Hystrix and RxJava

Anton Moldovan "Load testing which you always wanted"
Anton Moldovan "Load testing which you always wanted"Anton Moldovan "Load testing which you always wanted"
Anton Moldovan "Load testing which you always wanted"
Fwdays
 

Similaire à Reactive Fault Tolerant Programming with Hystrix and RxJava (20)

How we sleep well at night using Hystrix at Finn.no
How we sleep well at night using Hystrix at Finn.noHow we sleep well at night using Hystrix at Finn.no
How we sleep well at night using Hystrix at Finn.no
 
Saving lives with rx java
Saving lives with rx javaSaving lives with rx java
Saving lives with rx java
 
Anton Moldovan "Load testing which you always wanted"
Anton Moldovan "Load testing which you always wanted"Anton Moldovan "Load testing which you always wanted"
Anton Moldovan "Load testing which you always wanted"
 
Wrapping java in awesomeness aka condensator
Wrapping java in awesomeness aka condensatorWrapping java in awesomeness aka condensator
Wrapping java in awesomeness aka condensator
 
Ondemand scaling-aws
Ondemand scaling-awsOndemand scaling-aws
Ondemand scaling-aws
 
Practical RxJava for Android
Practical RxJava for AndroidPractical RxJava for Android
Practical RxJava for Android
 
Intro to Reactive Thinking and RxJava 2
Intro to Reactive Thinking and RxJava 2Intro to Reactive Thinking and RxJava 2
Intro to Reactive Thinking and RxJava 2
 
Angular and The Case for RxJS
Angular and The Case for RxJSAngular and The Case for RxJS
Angular and The Case for RxJS
 
RxJava2 Slides
RxJava2 SlidesRxJava2 Slides
RxJava2 Slides
 
Presto anatomy
Presto anatomyPresto anatomy
Presto anatomy
 
Going Reactive with Relational Databases
Going Reactive with Relational DatabasesGoing Reactive with Relational Databases
Going Reactive with Relational Databases
 
Finagle and Java Service Framework at Pinterest
Finagle and Java Service Framework at PinterestFinagle and Java Service Framework at Pinterest
Finagle and Java Service Framework at Pinterest
 
[NDC 2019] Enterprise-Grade Serverless
[NDC 2019] Enterprise-Grade Serverless[NDC 2019] Enterprise-Grade Serverless
[NDC 2019] Enterprise-Grade Serverless
 
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
 
Javantura v3 - Going Reactive with RxJava – Hrvoje Crnjak
Javantura v3 - Going Reactive with RxJava – Hrvoje CrnjakJavantura v3 - Going Reactive with RxJava – Hrvoje Crnjak
Javantura v3 - Going Reactive with RxJava – Hrvoje Crnjak
 
[245] presto 내부구조 파헤치기
[245] presto 내부구조 파헤치기[245] presto 내부구조 파헤치기
[245] presto 내부구조 파헤치기
 
Programming Sideways: Asynchronous Techniques for Android
Programming Sideways: Asynchronous Techniques for AndroidProgramming Sideways: Asynchronous Techniques for Android
Programming Sideways: Asynchronous Techniques for Android
 
Reactive programming every day
Reactive programming every dayReactive programming every day
Reactive programming every day
 
apidays LIVE Australia 2020 - Strangling the monolith with a reactive GraphQL...
apidays LIVE Australia 2020 - Strangling the monolith with a reactive GraphQL...apidays LIVE Australia 2020 - Strangling the monolith with a reactive GraphQL...
apidays LIVE Australia 2020 - Strangling the monolith with a reactive GraphQL...
 
RxJava applied [JavaDay Kyiv 2016]
RxJava applied [JavaDay Kyiv 2016]RxJava applied [JavaDay Kyiv 2016]
RxJava applied [JavaDay Kyiv 2016]
 

Plus de Matt Stine

Cloud Foundry Diego: Modular and Extensible Substructure for Microservices
Cloud Foundry Diego: Modular and Extensible Substructure for MicroservicesCloud Foundry Diego: Modular and Extensible Substructure for Microservices
Cloud Foundry Diego: Modular and Extensible Substructure for Microservices
Matt Stine
 
Cloud Foundry and Microservices: A Mutualistic Symbiotic Relationship
Cloud Foundry and Microservices: A Mutualistic Symbiotic RelationshipCloud Foundry and Microservices: A Mutualistic Symbiotic Relationship
Cloud Foundry and Microservices: A Mutualistic Symbiotic Relationship
Matt Stine
 
Information Sciences Solutions to Core Facility Problems at St. Jude Children...
Information Sciences Solutions to Core Facility Problems at St. Jude Children...Information Sciences Solutions to Core Facility Problems at St. Jude Children...
Information Sciences Solutions to Core Facility Problems at St. Jude Children...
Matt Stine
 
Java(tm) Technology On Google App Engine
Java(tm) Technology On Google App EngineJava(tm) Technology On Google App Engine
Java(tm) Technology On Google App Engine
Matt Stine
 
Deploying Grails to Morph App Space
Deploying Grails to Morph App SpaceDeploying Grails to Morph App Space
Deploying Grails to Morph App Space
Matt Stine
 

Plus de Matt Stine (20)

Architectures That Bend but Don't Break
Architectures That Bend but Don't BreakArchitectures That Bend but Don't Break
Architectures That Bend but Don't Break
 
Cloud Native Architecture Patterns Tutorial
Cloud Native Architecture Patterns TutorialCloud Native Architecture Patterns Tutorial
Cloud Native Architecture Patterns Tutorial
 
The Cloud Native Journey
The Cloud Native JourneyThe Cloud Native Journey
The Cloud Native Journey
 
To Microservices and Beyond
To Microservices and BeyondTo Microservices and Beyond
To Microservices and Beyond
 
Deploying Microservices to Cloud Foundry
Deploying Microservices to Cloud FoundryDeploying Microservices to Cloud Foundry
Deploying Microservices to Cloud Foundry
 
Cloud Foundry Diego: Modular and Extensible Substructure for Microservices
Cloud Foundry Diego: Modular and Extensible Substructure for MicroservicesCloud Foundry Diego: Modular and Extensible Substructure for Microservices
Cloud Foundry Diego: Modular and Extensible Substructure for Microservices
 
Building Distributed Systems with Netflix OSS and Spring Cloud
Building Distributed Systems with Netflix OSS and Spring CloudBuilding Distributed Systems with Netflix OSS and Spring Cloud
Building Distributed Systems with Netflix OSS and Spring Cloud
 
Pivotal Cloud Platform Roadshow: Sign Up for Pivotal Web Services
Pivotal Cloud Platform Roadshow: Sign Up for Pivotal Web ServicesPivotal Cloud Platform Roadshow: Sign Up for Pivotal Web Services
Pivotal Cloud Platform Roadshow: Sign Up for Pivotal Web Services
 
A Recovering Java Developer Learns to Go
A Recovering Java Developer Learns to GoA Recovering Java Developer Learns to Go
A Recovering Java Developer Learns to Go
 
Cloud Foundry and Microservices: A Mutualistic Symbiotic Relationship
Cloud Foundry and Microservices: A Mutualistic Symbiotic RelationshipCloud Foundry and Microservices: A Mutualistic Symbiotic Relationship
Cloud Foundry and Microservices: A Mutualistic Symbiotic Relationship
 
It's the End of the Cloud as We Know It
It's the End of the Cloud as We Know ItIt's the End of the Cloud as We Know It
It's the End of the Cloud as We Know It
 
Vert.x
Vert.xVert.x
Vert.x
 
Functional solid
Functional solidFunctional solid
Functional solid
 
The Seven Wastes of Software Development
The Seven Wastes of Software DevelopmentThe Seven Wastes of Software Development
The Seven Wastes of Software Development
 
Information Sciences Solutions to Core Facility Problems at St. Jude Children...
Information Sciences Solutions to Core Facility Problems at St. Jude Children...Information Sciences Solutions to Core Facility Problems at St. Jude Children...
Information Sciences Solutions to Core Facility Problems at St. Jude Children...
 
Achieve Your Goals
Achieve Your GoalsAchieve Your Goals
Achieve Your Goals
 
Getting Things Done
Getting Things DoneGetting Things Done
Getting Things Done
 
Feelin' Groovy: An Afternoon of Reflexive Metaprogramming
Feelin' Groovy: An Afternoon of Reflexive MetaprogrammingFeelin' Groovy: An Afternoon of Reflexive Metaprogramming
Feelin' Groovy: An Afternoon of Reflexive Metaprogramming
 
Java(tm) Technology On Google App Engine
Java(tm) Technology On Google App EngineJava(tm) Technology On Google App Engine
Java(tm) Technology On Google App Engine
 
Deploying Grails to Morph App Space
Deploying Grails to Morph App SpaceDeploying Grails to Morph App Space
Deploying Grails to Morph App Space
 

Dernier

%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
masabamasaba
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
masabamasaba
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
masabamasaba
 

Dernier (20)

%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
 
WSO2CON 2024 Slides - Open Source to SaaS
WSO2CON 2024 Slides - Open Source to SaaSWSO2CON 2024 Slides - Open Source to SaaS
WSO2CON 2024 Slides - Open Source to SaaS
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
 
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
 
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With SimplicityWSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
 
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
 
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
 
WSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - KeynoteWSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - Keynote
 
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park %in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
 
%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni
 
WSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security ProgramWSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security Program
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK Software
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
 
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open SourceWSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 

Reactive Fault Tolerant Programming with Hystrix and RxJava

  • 1. REACTIVE FAULT TOLERANT PROGRAMMING with Hystrix and RxJava Matt Stine (@mstine)
  • 2. Matt StineSenior Product Manager - Pivotal Software, Inc. Author of: http://bit.ly/cloud-native-book
  • 3. © Copyright 2015 Pivotal. All rights reserved. 3 MICROSERVICES!!!!!
  • 7. public ResponseEntity<Foo> handleIncomingRequest() { Foo foo = new Foo(); foo.addPart(serviceOne.getContributionToFoo()); foo.addPart(serviceTwo.getContributionToFoo()); return new ResponseEntity<>(foo, HttpStatus.OK); } Block and wait!
  • 8. Meanwhile in Service Two… ! ! µS µS µS
  • 9. public ResponseEntity<FooPart> handleIncomingRequest() { FooPart fooPart = new FooPart(); fooPart.addSubPart(serviceThree.getContributionToFooPart()); fooPart.addSubPart(serviceFour.getContributionToFooPart()); return new ResponseEntity<>(fooPart, HttpStatus.OK); } Block and wait!
  • 11. Futures! ExecutorService executor = createExecutorService(); public ResponseEntity<Foo> handleIncomingRequest() { Foo foo = new Foo(); Future<FooPart> partOne = executor.submit(new CallToServiceOne()); Future<FooPart> partTwo = executor.submit(new CallToServiceTwo()); foo.addPart(partOne.get()); foo.addPart(partTwo.get()); return new ResponseEntity<>(foo, HttpStatus.OK); }
  • 12. The service graph changes… public ResponseEntity<Foo> handleIncomingRequest() { Foo foo = new Foo(); Future<FooPart> partOne = executor.submit(new CallToServiceOne()); Future<FooPart> partTwo = executor.submit( new CallToServiceTwo(partOne.get())); Future<FooPart> partThree = executor.submit(new CallToServiceThree()) foo.addPart(partTwo.get()); foo.addPart(partThree.get()); return new ResponseEntity<>(foo, HttpStatus.OK); } Block and wait! Blocked until two completes!
  • 13. CompletableFutures public ResponseEntity<Foo> handleIncomingRequest() { Foo foo = new Foo(); CompletableFuture<FooPart> partTwo = CompletableFuture.supplyAsync( new CallToServiceOne()) .thenApplyAsync(new CallToServiceTwo()); CompletableFuture<FooPart> partThree = CompletableFuture.supplyAsync( new CallToServiceThree()); foo.addPart(partTwo.get()); foo.addPart(partThree.get()); return new ResponseEntity<>(foo, HttpStatus.OK); }
  • 14. As composition becomes more complex, CompletableFuture API is lacking…
  • 15. An API like this would be nice… List<Integer> transactionsIds = transactions.stream() .filter(t -> t.getType() == Transaction.GROCERY) .sorted(comparing(Transaction::getValue).reversed()) .map(Transaction::getId) .collect(toList());
  • 17.
  • 22.
  • 25. Hello Observable Observable<Integer> observableString = Observable.create( new Observable.OnSubscribe<Integer>() { public void call(Subscriber<? super Integer> subscriber) { for (int i = 0; i < 5; i++) { subscriber.onNext(i); } subscriber.onCompleted(); } }); Emit an item! I’m done emitting items!
  • 26. Observable<Integer> observableString = Observable.create( subscriber -> { for (int i = 0; i < 5; i++) { subscriber.onNext(i); } subscriber.onCompleted(); }); Hello Observable (JDK 8)
  • 27. Hello Subscription Subscription subscription = observableString.subscribe( new Observer<Integer>() { public void onCompleted() { System.out.println("Observable completed"); } public void onError(Throwable throwable) { System.out.println("Oh noes! Something wrong happened!"); } public void onNext(Integer integer) { System.out.println("Item is " + integer); } });
  • 28. Hello Subscription (JDK 8) Subscription subscription = observableString.subscribe( item -> System.out.println("Lambda says: " + item), throwable -> System.out.println("Lambda says: Oh noes! Something wrong happened!"), () -> System.out.println("Lambda says: Observable completed"));
  • 29. All together now… Observable.create( subscriber -> { for (int i = 0; i < 5; i++) { subscriber.onNext(i); } subscriber.onCompleted(); }).subscribe( item -> System.out.println("Lambda says: " + item), throwable -> System.out.println("Lambda says: Oh noes! Something wrong happened!"), () -> System.out.println("Lambda says: Observable completed"));
  • 30. Back to Our Service Graph ÂAPI ÂAPI ! ! ! µS µS µS µS µS
  • 31. With Callables Observable.fromCallable(new CallToServiceOne()) .flatMap(serviceOneResult -> Observable.fromCallable( new CallToServiceTwo(serviceOneResult))) .zipWith(Observable.fromCallable( new CallToServiceThree()), (FooPart resultFromServiceTwo, FooPart resultFromServiceThree) -> { Foo foo = new Foo(); foo.addPart(resultFromServiceTwo); foo.addPart(resultFromServiceThree); return foo; }).subscribe(System.out::println);
  • 32. With Lambdas Observable.<FooPart>create(serviceOneSubscriber -> { serviceOneSubscriber.onNext(new FooPart("one")); serviceOneSubscriber.onCompleted(); }).flatMap(serviceOneResult -> Observable.<FooPart>create(serviceTwoSubscriber -> { serviceTwoSubscriber.onNext(new FooPart(serviceOneResult + " + two")); serviceTwoSubscriber.onCompleted(); })).zipWith(Observable.<FooPart>create(serviceThreeSubscriber -> { serviceThreeSubscriber.onNext(new FooPart("three")); serviceThreeSubscriber.onCompleted(); }), (resultFromServiceTwo, resultFromServiceThree) -> { Foo foo = new Foo(); foo.addPart(resultFromServiceTwo); foo.addPart(resultFromServiceThree); return foo; }).subscribe(System.out::println);
  • 34. Combining Observables • merge() - combine multiple Observables so they act like a single Observable • zip() - combine sets of items from multiple Observables via a Function, and emit the results https://github.com/ReactiveX/RxJava/wiki/Combining-Observables
  • 35. Conditionals • doWhile() - emit Observable sequence, then repeat the sequence as long as the condition remains true • ifThen() - only emit Observable sequence if a condition is true, otherwise emit empty or default sequence • skipUntil() - discard emitted items from Observable until a second Observable emits an item, then emit the remainder • takeUntil() - emit items from Observable until a second Observable emits or notifies https://github.com/ReactiveX/RxJava/wiki/Conditional-and-Boolean-Operators
  • 36. Boolean Operators • all() - do all the emitted items meet some criteria? • contains() - does the Observable emit a particular item? • exists() / isEmpty() - does an Observable emit items or not? • sequenceEqual() - do two Observables emit equal sequences? https://github.com/ReactiveX/RxJava/wiki/Conditional-and-Boolean-Operators
  • 37. Filtering • filter() - filter Observable with a predicate • take(n) - emit only the first n items • skip(n) - ignore the first n items emitted • sample() - sample items according to a periodic interval https://github.com/ReactiveX/RxJava/wiki/Filtering-Observables
  • 38. Transforming • map() - apply a function to each emitted item • flatMap() - transform items emitted by Observable into Observables, then flatten • scan() - apply a function to each emitted item, then feedback result and repeat • buffer() - gather emitted items into bundles and emit the bundles https://github.com/ReactiveX/RxJava/wiki/Transforming-Observables
  • 41. Backpressure Observable Observable.create(subscriber -> IntStream.iterate(0, i -> i + 2) .forEach(value -> subscriber.onNext(value))) .onBackpressureBuffer() .subscribe(new BackpressureSubscriber());
  • 42. Backpressure Subscriber public class BackpressureSubscriber extends Subscriber<Object> { private int counter = 0; @Override public void onStart() { request(10); } @Override public void onNext(Object o) { if (counter < 9) { processItem(o); } else { processItem(o); resetCounter(); request(10); } } Please only give me this many! OK, I can handle more now.
  • 43. Backpressure Subscriber private void processItem(Object o) { try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } counter++; System.out.println(counter + " : " + o); } private void resetCounter() { counter = 0; System.out.println("FETCH MORE"); } Simulate Processing Latency }
  • 45. What happens if we cut here? ÂAPI ÂAPI ! ! ! µS µS µS µS µS
  • 49. Fault Tolerance at Netflix http://techblog.netflix.com/2012/02/fault-tolerance-in-high-volume.html
  • 50. Without taking steps to ensure fault tolerance, 30 dependencies each with 99.99% uptime would result in 2+ hours downtime/ month (99.99%30 = 99.7% uptime = 2.16 hours/month). http://techblog.netflix.com/2012/02/fault-tolerance-in-high-volume.html
  • 52. Circuit Breaker State Machine Closed on call / pass through call succeeds / reset count call fails / count failure threshold reached / trip breaker Open on call / fail on timeout / attempt reset Half-Open on call / pass through call succeeds / reset call fails / trip breaker trip breaker trip breaker attempt reset reset
  • 54. Hello Hystrix World public class CommandHelloWorld extends HystrixCommand<String> { private final String name; public CommandHelloWorld(String name) { super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup")); this.name = name; } @Override protected String run() { // Do something that might fail... return "Hello " + name + "!"; } }
  • 55. Synchronous String s = new CommandHelloWorld("Bob").execute(); Block and wait!
  • 56. Asynchronous Future<String> s = new CommandHelloWorld("Bob").queue();
  • 57. Reactive! Observable<String> s = new CommandHelloWorld("Bob").observe(); s.subscribe(val -> { // value emitted here });
  • 58. Fail Fast public class CommandThatFailsFast extends HystrixCommand<String> { private final boolean throwException; public CommandThatFailsFast(boolean throwException) { super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup")); this.throwException = throwException; } @Override protected String run() { if (throwException) { throw new RuntimeException("failure from CommandThatFailsFast"); } else { return "success"; } } }
  • 59. Fail Silently public class CommandThatFailsSilently extends HystrixCommand<String> { private final boolean throwException; public CommandThatFailsSilently(boolean throwException) { super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup")); this.throwException = throwException; } @Override protected String run() { if (throwException) { throw new RuntimeException("failure from CommandThatFailsSilently"); } else { return "success"; } } @Override protected String getFallback() { return null; } } Fallback behavior! }
  • 60. Static Fallback @Override protected String run() { if (throwException) { throw new RuntimeException("failure from CommandWithStaticFallback"); } else { return "success"; } } @Override protected String getFallback() { return "fallback"; } Fallback behavior! }
  • 61. Stubbed Fallback @Override protected UserAccount run() { // fetch UserAccount from remote service // return UserAccountClient.getAccount(customerId); throw new RuntimeException("forcing failure for example"); } @Override protected UserAccount getFallback() { /** * Return stubbed fallback with some static defaults, placeholders, * and an injected value 'countryCodeFromGeoLookup' that we'll use * instead of what we would have retrieved from the remote service. */ return new UserAccount(customerId, "Unknown Name", countryCodeFromGeoLookup, true, true, false); } Fallback behavior! }
  • 63. Primary + Secondary with Fallback
  • 68. With Callables Observable.fromCallable(new CallToServiceOne()) .flatMap(serviceOneResult -> Observable.fromCallable( new CallToServiceTwo(serviceOneResult))) .zipWith(Observable.fromCallable( new CallToServiceThree()), (FooPart resultFromServiceTwo, FooPart resultFromServiceThree) -> { Foo foo = new Foo(); foo.addPart(resultFromServiceTwo); foo.addPart(resultFromServiceThree); return foo; }).subscribe(System.out::println);
  • 69. With HystrixObservableCommands new CallToServiceOneCommand("callToServiceOne").observe() .flatMap(serviceOneResult -> new CallToServiceTwoCommand("callToServiceTwo", serviceOneResult).observe()) .zipWith(new CallToServiceThreeCommand("callToServiceThree").observe(), (FooPart resultFromServiceTwo, FooPart resultFromServiceThree) -> { Foo foo = new Foo(); foo.addPart(resultFromServiceTwo); foo.addPart(resultFromServiceThree); return foo; }).subscribe(System.out::println);
  • 70. Call to Service One public class CallToServiceOneCommand extends HystrixObservableCommand<FooPart> { public CallToServiceOneCommand(String name) { super(HystrixCommandGroupKey.Factory.asKey(name)); } @Override protected Observable<FooPart> construct() { return Observable.create(new Observable.OnSubscribe<FooPart>() { @Override public void call(Subscriber<? super FooPart> subscriber) { subscriber.onNext(new FooPart("one")); subscriber.onCompleted(); } }); } }
  • 71. public class CallToServiceTwoCommand extends HystrixObservableCommand<FooPart> { private final FooPart dependencyFromServiceOne; private CallToServiceTwoCommand(String name, FooPart dependencyFromServiceOne) { super(HystrixCommandGroupKey.Factory.asKey(name)); this.dependencyFromServiceOne = dependencyFromServiceOne; } @Override protected Observable<FooPart> construct() { return Observable.create(new Observable.OnSubscribe<FooPart>() { @Override public void call(Subscriber<? super FooPart> subscriber) { subscriber.onNext(new FooPart(dependencyFromServiceOne + " + two")); subscriber.onCompleted(); } }); } } Call to Service Two
  • 73. Hystrix with Spring Cloud @SpringBootApplication @EnableDiscoveryClient @EnableCircuitBreaker public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
  • 74. Hystrix with Spring Cloud @Service @EnableConfigurationProperties(FortuneProperties.class) public class FortuneService { @Autowired FortuneProperties fortuneProperties; @Autowired RestTemplate restTemplate; @HystrixCommand(fallbackMethod = "fallbackFortune") public Fortune randomFortune() { return restTemplate.getForObject("http://fortunes/random", Fortune.class); } private Fortune fallbackFortune() { return new Fortune(42L, fortuneProperties.getFallbackFortune()); } } }
  • 75. RxJava + Hystrix + Spring Cloud @HystrixCommand(fallbackMethod = "stubMovie") public Observable<Movie> getMovie(final String mlId) { return new ObservableResult<Movie>() { @Override public Movie invoke() { return restTemplate.getForObject( "http://springbox-catalog/movies/{mlId}", Movie.class, mlId); } }; } private Movie stubMovie(final String mlId) { Movie stub = new Movie(); stub.setMlId(mlId); stub.setTitle("Interesting...the wrong title. Sssshhhh!"); return stub; }
  • 76. RxJava + Hystrix + Spring Cloud @RequestMapping("/movie/{mlId}") public Observable<MovieDetails> movieDetails(@PathVariable String mlId) { return Observable.zip( catalogIntegrationService.getMovie(mlId), reviewsIntegrationService.reviewsFor(mlId), recommendationsIntegrationService.getRecommendations(mlId), (movie, reviews, recommendations) -> { MovieDetails movieDetails = new MovieDetails(); movieDetails.setMlId(movie.getMlId()); movieDetails.setTitle(movie.getTitle()); movieDetails.setReviews(reviews); movieDetails.setRecommendations(recommendations); return movieDetails; } ); }
  • 80. JDK 9 Flow API http://download.java.net/jdk9/docs/api/java/util/concurrent/Flow.html
  • 81. REACTIVE FAULT TOLERANT PROGRAMMING with Hystrix and RxJava Get your FREE eBook! http://bit.ly/cloud-native-book Matt StineSenior Product Manager - Pivotal Software, Inc.
 @mstine
 matt.stine@gmail.com
 http://mattstine.com