SlideShare une entreprise Scribd logo
1  sur  80
Télécharger pour lire hors ligne
Resilience mit Hystrix 
Eine kurze Einführung für den geneigten Entwickler 
Uwe Friedrichsen (codecentric AG) – Java Usergroup Berlin-Brandenburg – Berlin, 22. Oktober 2014
@ufried 
Uwe Friedrichsen | uwe.friedrichsen@codecentric.de | http://slideshare.net/ufried | http://ufried.tumblr.com
It‘s all about production!
Business 
Production 
Availability 
Resilience
Resilience? Never heard of it …
re•sil•ience (rɪˈzɪl yəns) also re•sil′ien•cy, n. 
1. the power or ability to return to the original form, position, 
etc., after being bent, compressed, or stretched; elasticity. 
2. ability to recover readily from illness, depression, adversity, 
or the like; buoyancy. 
Random House Kernerman Webster's College Dictionary, © 2010 K Dictionaries Ltd. 
Copyright 2005, 1997, 1991 by Random House, Inc. All rights reserved. 
http://www.thefreedictionary.com/resilience
Resilience (IT) 
The ability of a system to handle unexpected situations 
- without the user noticing it (best case) 
- with a graceful degradation of service (worst case)
A distributed system is one in which the failure 
of a computer you didn't even know existed 
can render your own computer unusable. 
Leslie Lamport
Failures in todays complex, distributed, 
interconnected systems are not the exception. 
They are the normal case.
Implemented patterns 
• Timeout 
• Circuit breaker 
• Load shedder 
• Fallback
Supported patterns 
• Bulkheads 
(a.k.a. Failure Units) 
• Fail fast 
• Fail silently 
• Graceful degradation of service 
• Failover 
• Escalation 
• Retry 
• ...
That‘s been enough theory 
Give us some code – now!
Basics
Hello, world!
public class HelloCommand extends HystrixCommand<String> { 
private static final String COMMAND_GROUP = "default"; 
private final String name; 
public HelloCommand(String name) { 
super(HystrixCommandGroupKey.Factory.asKey(COMMAND_GROUP)); 
this.name = name; 
} 
@Override 
protected String run() throws Exception { 
return "Hello, " + name; 
} 
}
@Test 
public void shouldGreetWorld() { 
String result = new HelloCommand("World").execute(); 
assertEquals("Hello, World", result); 
}
Synchronous execution
@Test 
public void shouldExecuteSynchronously() { 
String s = new HelloCommand("Bob").execute(); 
assertEquals("Hello, Bob", s); 
}
Asynchronous execution
@Test 
public void shouldExecuteAsynchronously() { 
Future<String> f = new HelloCommand("Alice").queue(); 
String s = null; 
try { 
s = f.get(); 
} catch (InterruptedException | ExecutionException e) { 
// Handle Future.get() exceptions here 
} 
assertEquals("Hello, Alice", s); 
}
Reactive execution (simple)
@Test 
public void shouldExecuteReactiveSimple() { 
Observable<String> observable = 
new HelloCommand("Alice").observe(); 
String s = observable.toBlockingObservable().single(); 
assertEquals("Hello, Alice", s); 
}
Reactive execution (full)
public class CommandHelloObserver implements Observer<String> { 
// Needed for communication between observer and test case 
private final AtomicReference<String> aRef; 
private final Semaphore semaphore; 
public CommandHelloObserver(AtomicReference<String> aRef, 
Semaphore semaphore) { 
this.aRef = aRef; 
this.semaphore = semaphore; 
} 
@Override 
public void onCompleted() { // Not needed here } 
@Override 
public void onError(Throwable e) { // Not needed here } 
@Override 
public void onNext(String s) { 
aRef.set(s); 
semaphore.release(); 
} 
}
@Test 
public void shouldExecuteReactiveFull() { 
// Needed for communication between observer and test case 
AtomicReference<String> aRef = new AtomicReference<>(); 
Semaphore semaphore = new Semaphore(0); 
Observable<String> observable = new HelloCommand("Bob").observe(); 
Observer<String> observer = 
new CommandHelloObserver(aRef, semaphore); 
observable.subscribe(observer); 
// Wait until observer received a result 
try { 
semaphore.acquire(); 
} catch (InterruptedException e) { 
// Handle exceptions here 
} 
String s = aRef.get(); 
assertEquals("Hello, Bob", s); 
}
Fallback
public class FallbackCommand extends HystrixCommand<String> { 
private static final String COMMAND_GROUP = "default"; 
public FallbackCommand() { 
super(HystrixCommandGroupKey.Factory.asKey(COMMAND_GROUP)); 
} 
@Override 
protected String run() throws Exception { 
throw new RuntimeException("I will always fail"); 
} 
@Override 
protected String getFallback() { 
return "Powered by fallback"; 
} 
}
@Test 
public void shouldGetFallbackResponse() { 
String s = new FallbackCommand().execute(); 
assertEquals("Powered by fallback", s); 
}
Error propagation
public class ErrorPropagationCommand extends HystrixCommand<String> { 
private static final String COMMAND_GROUP = "default"; 
protected ErrorPropagationCommand() { 
super(HystrixCommandGroupKey.Factory.asKey(COMMAND_GROUP)); 
} 
@Override 
protected String run() throws Exception { 
throw new HystrixBadRequestException("I fail differently", 
new RuntimeException("I will always fail")); 
} 
@Override 
protected String getFallback() { 
return "Powered by fallback"; 
} 
}
@Test 
public void shouldGetFallbackResponse() { 
String s = null; 
try { 
s = new ErrorPropagationCommand().execute(); 
fail(); // Just to make sure 
} catch (HystrixBadRequestException e) { 
assertEquals("I will fail differently", e.getMessage()); 
assertEquals("I will always fail", e.getCause().getMessage()); 
} 
assertNull(s); // Fallback is not triggered 
}
How it works
Source: https://github.com/Netflix/Hystrix/wiki/How-it-Works
Source: https://github.com/Netflix/Hystrix/wiki/How-it-Works
Source: https://github.com/Netflix/Hystrix/wiki/How-it-Works
Configuration
Configuration 
• Based on Archaius by Netflix 
which extends the Apache Commons Configuration Library 
• Four levels of precedence 
1. Global default from code 
2. Dynamic global default property 
3. Instance default from code 
4. Dynamic instance property 
Provides many configuration & tuning options
Configuration – Some examples 
• hystrix.command.*.execution.isolation.strategy 
Either “THREAD” or “SEMAPHORE” (Default: THREAD) 
• hystrix.command.*.execution.isolation.thread.timeoutInMilliseconds 
Time to wait for the run() method to complete (Default: 1000) 
• h.c.*.execution.isolation.semaphore.maxConcurrentRequests 
Maximum number of concurrent requests when using semaphores (Default: 10) 
• hystrix.command.*.circuitBreaker.errorThresholdPercentage 
Error percentage at which the breaker trips open (Default: 50) 
• hystrix.command.*.circuitBreaker.sleepWindowInMilliseconds 
Time to wait before attempting to reset the breaker after tripping (Default: 5000) 
* must be either “default” or the command key name
Configuration – More examples 
• hystrix.threadpool.*.coreSize 
Maximum number of concurrent requests when using thread pools (Default: 10) 
• hystrix.threadpool.*.maxQueueSize 
Maximum LinkedBlockingQueue size - -1 for using SynchronousQueue (Default: -1) 
• hystrix.threadpool.default.queueSizeRejectionThreshold 
Queue size rejection threshold (Default: 5) 
… and many more 
* must be either “default” or the thread pool key name
Patterns
Timeout
public class LatentResource { 
private final long latency; 
public LatentResource(long latency) { 
this.latency = ((latency < 0L) ? 0L : latency); 
} 
public String getData() { 
addLatency(); // This is the important part 
return "Some value”; 
} 
private void addLatency() { 
try { 
Thread.sleep(latency); 
} catch (InterruptedException e) { 
// We do not care about this here 
} 
} 
}
public class TimeoutCommand extends HystrixCommand<String> { 
private static final String COMMAND_GROUP = "default"; 
private final LatentResource resource; 
public TimeoutCommand(int timeout, LatentResource resource) { 
super(Setter.withGroupKey( 
HystrixCommandGroupKey.Factory.asKey(COMMAND_GROUP)) 
.andCommandPropertiesDefaults( 
HystrixCommandProperties.Setter() 
.withExecutionIsolationThreadTimeoutInMilliseconds( 
timeout))); 
this.resource = resource; 
} 
@Override 
protected String run() throws Exception { 
return resource.getData(); 
} 
@Override 
protected String getFallback() { 
return "Resource timed out"; 
} 
}
@Test 
public void shouldGetNormalResponse() { 
LatentResource resource = new LatentResource(50L); 
TimeoutCommand command = new TimeoutCommand(100, resource); 
String s = command.execute(); 
assertEquals("Some value", s); 
} 
@Test 
public void shouldGetFallbackResponse() { 
LatentResource resource = new LatentResource(150L); 
TimeoutCommand command = new TimeoutCommand(100, resource); 
String s = command.execute(); 
assertEquals("Resource timed out", s); 
}
Circuit breaker
public class CircuitBreakerCommand extends HystrixCommand<String> { 
private static final String COMMAND_GROUP = "default"; 
public CircuitBreakerCommand(String name, boolean open) { 
super(Setter.withGroupKey( 
HystrixCommandGroupKey.Factory.asKey(COMMAND_GROUP)) 
.andCommandKey(HystrixCommandKey.Factory.asKey(name)) 
.andCommandPropertiesDefaults( 
HystrixCommandProperties.Setter() 
.withCircuitBreakerForceOpen(open))); 
} 
@Override 
protected String run() throws Exception { 
return("Some result"); 
} 
@Override 
protected String getFallback() { 
return "Fallback response"; 
} 
}
@Test 
public void shouldExecuteWithCircuitBreakerClosed() { 
CircuitBreakerCommand command = new 
CircuitBreakerCommand("ClosedBreaker", false); 
String s = command.execute(); 
assertEquals("Some result", s); 
HystrixCircuitBreaker breaker = 
HystrixCircuitBreaker.Factory 
.getInstance(command.getCommandKey()); 
assertTrue(breaker.allowRequest()); 
}
@Test 
public void shouldExecuteWithCircuitBreakerOpen() { 
CircuitBreakerCommand command = new 
CircuitBreakerCommand("OpenBreaker", true); 
String s = command.execute(); 
assertEquals("Fallback response", s); 
HystrixCircuitBreaker breaker = 
HystrixCircuitBreaker.Factory 
.getInstance(command.getCommandKey()); 
assertFalse(breaker.allowRequest()); 
}
Load shedder (Thread pool)
public class LatentCommand extends HystrixCommand<String> { 
private static final String COMMAND_GROUP = "default"; 
private final LatentResource resource; 
public LatentCommand(LatentResource resource) { 
super(HystrixCommandGroupKey.Factory.asKey(COMMAND_GROUP)); 
this.resource = resource; 
} 
@Override 
protected String run() throws Exception { 
return resource.getData(); 
} 
@Override 
protected String getFallback() { 
return "Fallback triggered"; 
} 
}
@Test 
public void shouldShedLoad() { 
List<Future<String>> l = new LinkedList<>(); 
LatentResource resource = new LatentResource(500L); // Make latent 
// Use up all available threads 
for (int i = 0; i < 10; i++) 
l.add(new LatentCommand(resource).queue()); 
// Call will be rejected as thread pool is exhausted 
String s = new LatentCommand(resource).execute(); 
assertEquals("Fallback triggered", s); 
// All other calls succeed 
for (Future<String> f : l) 
assertEquals("Some value", get(f)); // wrapper for f.get() 
}
Load shedder (Semaphore)
public class SemaphoreCommand extends HystrixCommand<String> { 
private static final String COMMAND_GROUP = "default"; 
private final LatentResource resource; 
public SemaphoreCommand(LatentResource resource) { 
super(Setter.withGroupKey( 
HystrixCommandGroupKey.Factory.asKey(COMMAND_GROUP)) 
.andCommandPropertiesDefaults( 
HystrixCommandProperties.Setter() 
.withExecutionIsolationStrategy(HystrixCommandProperties 
.ExecutionIsolationStrategy.SEMAPHORE))); 
this.resource = resource; 
} 
@Override 
protected String run() throws Exception { 
return resource.getData(); 
} 
@Override 
protected String getFallback() { 
return "Fallback triggered"; 
} 
}
private class SemaphoreCommandInvocation implements 
java.util.concurrent.Callable<String> { 
private final LatentResource resource; 
public SemaphoreCommandInvocation(LatentResource resource) { 
this.resource = resource; 
} 
@Override 
public String call() throws Exception { 
return new SemaphoreCommand(resource).execute(); 
} 
}
@Test 
public void shouldShedLoad() { 
List<Future<String>> l = new LinkedList<>(); 
LatentResource resource = new LatentResource(500L); // Make latent 
ExecutorService e = Executors.newFixedThreadPool(10); 
// Use up all available semaphores 
for (int i = 0; i < 10; i++) 
l.add(e.submit(new SemaphoreCommandInvocation(resource))); 
// Wait a moment to make sure all commands are started 
pause(250L); // Wrapper around Thread.sleep() 
// Call will be rejected as all semaphores are in use 
String s = new SemaphoreCommand(resource).execute(); 
assertEquals("Fallback triggered", s); 
// All other calls succeed 
for (Future<String> f : l) 
assertEquals("Some value", get(f)); 
}
Fail fast
public class FailFastCommand extends HystrixCommand<String> { 
private static final String COMMAND_GROUP = "default"; 
private final boolean preCondition; 
public FailFastCommand(boolean preCondition) { 
super(HystrixCommandGroupKey.Factory.asKey(COMMAND_GROUP)); 
this.preCondition = preCondition; 
} 
@Override 
protected String run() throws Exception { 
if (!preCondition) 
throw new RuntimeException(("Fail fast")); 
return "Some value"; 
} 
}
@Test 
public void shouldSucceed() { 
FailFastCommand command = new FailFastCommand(true); 
String s = command.execute(); 
assertEquals("Some value", s); 
} 
@Test 
public void shouldFailFast() { 
FailFastCommand command = new FailFastCommand(false); 
try { 
String s = command.execute(); 
fail("Did not fail fast"); 
} catch (Exception e) { 
assertEquals(HystrixRuntimeException.class, e.getClass()); 
assertEquals("Fail fast", e.getCause().getMessage()); 
} 
}
Fail silent
public class FailSilentCommand extends HystrixCommand<String> { 
private static final String COMMAND_GROUP = "default"; 
private final boolean preCondition; 
public FailSilentCommand(boolean preCondition) { 
super(HystrixCommandGroupKey.Factory.asKey(COMMAND_GROUP)); 
this.preCondition = preCondition; 
} 
@Override 
protected String run() throws Exception { 
if (!preCondition) 
throw new RuntimeException(("Fail fast")); 
return "Some value"; 
} 
@Override 
protected String getFallback() { 
return null; // Turn into silent failure 
} 
}
@Test 
public void shouldSucceed() { 
FailSilentCommand command = new FailSilentCommand(true); 
String s = command.execute(); 
assertEquals("Some value", s); 
} 
@Test 
public void shouldFailSilent() { 
FailSilentCommand command = new FailSilentCommand(false); 
String s = "Test value"; 
try { 
s = command.execute(); 
} catch (Exception e) { 
fail("Did not fail silently"); 
} 
assertNull(s); 
}
Static fallback
public class StaticFallbackCommand extends HystrixCommand<String> { 
private static final String COMMAND_GROUP = "default"; 
private final boolean preCondition; 
public StaticFallbackCommand(boolean preCondition) { 
super(HystrixCommandGroupKey.Factory.asKey(COMMAND_GROUP)); 
this.preCondition = preCondition; 
} 
@Override 
protected String run() throws Exception { 
if (!preCondition) 
throw new RuntimeException(("Fail fast")); 
return "Some value"; 
} 
@Override 
protected String getFallback() { 
return "Some static fallback value"; // Static fallback 
} 
}
@Test 
public void shouldSucceed() { 
StaticFallbackCommand command = new StaticFallbackCommand(true); 
String s = command.execute(); 
assertEquals("Some value", s); 
} 
@Test 
public void shouldProvideStaticFallback() { 
StaticFallbackCommand command = new StaticFallbackCommand(false); 
String s = null; 
try { 
s = command.execute(); 
} catch (Exception e) { 
fail("Did not fail silent"); 
} 
assertEquals("Some static fallback value", s); 
}
Cache fallback
public class CacheClient { 
private final Map<String, String> map; 
public CacheClient() { 
map = new ConcurrentHashMap<>(); 
} 
public void add(String key, String value) { 
map.put(key, value); 
} 
public String get(String key) { 
return map.get(key); 
} 
}
public class CacheCommand extends HystrixCommand<String> { 
private static final String COMMAND_GROUP = "primary"; 
private final CacheClient cache; 
private final boolean failPrimary; 
private final String req; 
public CacheCommand(CacheClient cache, boolean failPrimary, 
String request) { 
super(HystrixCommandGroupKey.Factory.asKey(COMMAND_GROUP)); 
this.cache = cache; 
this.failPrimary = failPrimary; 
this.req = request; 
} 
@Override 
protected String run() throws Exception { 
if (failPrimary) 
throw new RuntimeException("Failure of primary"); 
String s = req + "-o"; 
cache.add(req, s); 
return(s); 
} 
…
… 
@Override 
protected String getFallback() { 
return "Cached: " + new FBCommand(cache, req).execute(); 
} 
private static class FBCommand extends HystrixCommand<String> { 
private static final String COMMAND_GROUP = "fallback"; 
private final CacheClient cache; 
private final String request; 
public FBCommand(CacheClient cache, String request) { 
super(HystrixCommandGroupKey.Factory.asKey(COMMAND_GROUP)); 
this.cache = cache; 
this.request = request; 
} 
@Override 
protected String run() throws Exception { 
return cache.get(request); 
} 
} 
}
@Test 
public void shouldExecuteWithoutCache() { 
CacheClient cache = new CacheClient(); 
String s = new CacheCommand(cache, false, "ping”).execute(); 
assertEquals("ping-o", s); 
} 
@Test 
public void shouldRetrieveValueFromCache() { 
CacheClient cache = new CacheClient(); 
new CacheCommand(cache, false, "ping").execute(); 
String s = new CacheCommand(cache, true, "ping”).execute(); 
assertEquals("Cached: ping-o", s); 
} 
@Test 
public void shouldNotRetrieveAnyValue() { 
CacheClient cache = new CacheClient(); 
String s = new CacheCommand(cache, true, "ping”).execute(); 
assertEquals("Cached: null", s); 
}
… and so on
Advanced features
Advanced Features 
• Request Caching 
• Request Collapsing 
• Plugins 
Event Notifier, Metrics Publisher, Properties Strategy, 
Concurrency Strategy, Command Execution Hook 
• Contributions 
Metrics Event Stream, Metrics Publisher, Java Annotations, 
Clojure Bindings, … 
• Dashboard
Source: https://github.com/Netflix/Hystrix/wiki/Dashboard
Source: https://github.com/Netflix/Hystrix/wiki/Dashboard
Further reading 
1. Hystrix Wiki, 
https://github.com/Netflix/Hystrix/wiki 
2. Michael T. Nygard, Release It!, 
Pragmatic Bookshelf, 2007 
3. Robert S. Hanmer, 
Patterns for Fault Tolerant Software, 
Wiley, 2007 
4. Andrew Tanenbaum, Marten van Steen, 
Distributed Systems – Principles and 
Paradigms, 
Prentice Hall, 2nd Edition, 2006
Wrap-up 
• Resilient software design becomes a must 
• Hystrix is a resilience library 
• Provides isolation and latency control 
• Easy to start with 
• Yet some learning curve 
• Many fault-tolerance patterns implementable 
• Many configuration options 
• Customizable 
• Operations proven 
Become a resilient software developer!
It‘s all about production!
@ufried 
Uwe Friedrichsen | uwe.friedrichsen@codecentric.de | http://slideshare.net/ufried | http://ufried.tumblr.com
Resilience mit Hystrix

Contenu connexe

Tendances

The Ring programming language version 1.8 book - Part 9 of 202
The Ring programming language version 1.8 book - Part 9 of 202The Ring programming language version 1.8 book - Part 9 of 202
The Ring programming language version 1.8 book - Part 9 of 202Mahmoud Samir Fayed
 
201913046 wahyu septiansyah network programing
201913046 wahyu septiansyah network programing201913046 wahyu septiansyah network programing
201913046 wahyu septiansyah network programingwahyuseptiansyah
 
Tech Talks_25.04.15_Session 3_Tibor Sulyan_Distributed coordination with zook...
Tech Talks_25.04.15_Session 3_Tibor Sulyan_Distributed coordination with zook...Tech Talks_25.04.15_Session 3_Tibor Sulyan_Distributed coordination with zook...
Tech Talks_25.04.15_Session 3_Tibor Sulyan_Distributed coordination with zook...EPAM_Systems_Bulgaria
 
Message-based communication patterns in distributed Akka applications
Message-based communication patterns in distributed Akka applicationsMessage-based communication patterns in distributed Akka applications
Message-based communication patterns in distributed Akka applicationsAndrii Lashchenko
 
Python concurrency: libraries overview
Python concurrency: libraries overviewPython concurrency: libraries overview
Python concurrency: libraries overviewAndrii Mishkovskyi
 
Testing Java Code Effectively
Testing Java Code EffectivelyTesting Java Code Effectively
Testing Java Code EffectivelyAndres Almiray
 
Amazon Cognito使って認証したい?それならSpring Security使いましょう!
Amazon Cognito使って認証したい?それならSpring Security使いましょう!Amazon Cognito使って認証したい?それならSpring Security使いましょう!
Amazon Cognito使って認証したい?それならSpring Security使いましょう!Ryosuke Uchitate
 
Varnish presentation for the Symfony Zaragoza user group
Varnish presentation for the Symfony Zaragoza user groupVarnish presentation for the Symfony Zaragoza user group
Varnish presentation for the Symfony Zaragoza user groupJorge Nerín
 
Buenos Aires Drools Expert Presentation
Buenos Aires Drools Expert PresentationBuenos Aires Drools Expert Presentation
Buenos Aires Drools Expert PresentationMark Proctor
 
Vielseitiges In-Memory Computing mit Apache Ignite und Kubernetes
Vielseitiges In-Memory Computing mit Apache Ignite und KubernetesVielseitiges In-Memory Computing mit Apache Ignite und Kubernetes
Vielseitiges In-Memory Computing mit Apache Ignite und KubernetesQAware GmbH
 
Software Testing - Invited Lecture at UNSW Sydney
Software Testing - Invited Lecture at UNSW SydneySoftware Testing - Invited Lecture at UNSW Sydney
Software Testing - Invited Lecture at UNSW Sydneyjulien.ponge
 
What istheservicestack
What istheservicestackWhat istheservicestack
What istheservicestackDemis Bellot
 
Drools Introduction
Drools IntroductionDrools Introduction
Drools IntroductionJBug Italy
 
Programming with ZooKeeper - A basic tutorial
Programming with ZooKeeper - A basic tutorialProgramming with ZooKeeper - A basic tutorial
Programming with ZooKeeper - A basic tutorialJeff Smith
 
Kotlin from-scratch 3 - coroutines
Kotlin from-scratch 3 - coroutinesKotlin from-scratch 3 - coroutines
Kotlin from-scratch 3 - coroutinesFranco Lombardo
 
The uniform interface is 42
The uniform interface is 42The uniform interface is 42
The uniform interface is 42Yevhen Bobrov
 
제 8회 엑셈 수요 세미나 자료 연구컨텐츠팀
제 8회 엑셈 수요 세미나 자료 연구컨텐츠팀제 8회 엑셈 수요 세미나 자료 연구컨텐츠팀
제 8회 엑셈 수요 세미나 자료 연구컨텐츠팀EXEM
 

Tendances (18)

The Ring programming language version 1.8 book - Part 9 of 202
The Ring programming language version 1.8 book - Part 9 of 202The Ring programming language version 1.8 book - Part 9 of 202
The Ring programming language version 1.8 book - Part 9 of 202
 
201913046 wahyu septiansyah network programing
201913046 wahyu septiansyah network programing201913046 wahyu septiansyah network programing
201913046 wahyu septiansyah network programing
 
Tech Talks_25.04.15_Session 3_Tibor Sulyan_Distributed coordination with zook...
Tech Talks_25.04.15_Session 3_Tibor Sulyan_Distributed coordination with zook...Tech Talks_25.04.15_Session 3_Tibor Sulyan_Distributed coordination with zook...
Tech Talks_25.04.15_Session 3_Tibor Sulyan_Distributed coordination with zook...
 
Message-based communication patterns in distributed Akka applications
Message-based communication patterns in distributed Akka applicationsMessage-based communication patterns in distributed Akka applications
Message-based communication patterns in distributed Akka applications
 
Python concurrency: libraries overview
Python concurrency: libraries overviewPython concurrency: libraries overview
Python concurrency: libraries overview
 
Testing Java Code Effectively
Testing Java Code EffectivelyTesting Java Code Effectively
Testing Java Code Effectively
 
Amazon Cognito使って認証したい?それならSpring Security使いましょう!
Amazon Cognito使って認証したい?それならSpring Security使いましょう!Amazon Cognito使って認証したい?それならSpring Security使いましょう!
Amazon Cognito使って認証したい?それならSpring Security使いましょう!
 
Varnish presentation for the Symfony Zaragoza user group
Varnish presentation for the Symfony Zaragoza user groupVarnish presentation for the Symfony Zaragoza user group
Varnish presentation for the Symfony Zaragoza user group
 
Buenos Aires Drools Expert Presentation
Buenos Aires Drools Expert PresentationBuenos Aires Drools Expert Presentation
Buenos Aires Drools Expert Presentation
 
9P Code Walkthrough
9P Code Walkthrough9P Code Walkthrough
9P Code Walkthrough
 
Vielseitiges In-Memory Computing mit Apache Ignite und Kubernetes
Vielseitiges In-Memory Computing mit Apache Ignite und KubernetesVielseitiges In-Memory Computing mit Apache Ignite und Kubernetes
Vielseitiges In-Memory Computing mit Apache Ignite und Kubernetes
 
Software Testing - Invited Lecture at UNSW Sydney
Software Testing - Invited Lecture at UNSW SydneySoftware Testing - Invited Lecture at UNSW Sydney
Software Testing - Invited Lecture at UNSW Sydney
 
What istheservicestack
What istheservicestackWhat istheservicestack
What istheservicestack
 
Drools Introduction
Drools IntroductionDrools Introduction
Drools Introduction
 
Programming with ZooKeeper - A basic tutorial
Programming with ZooKeeper - A basic tutorialProgramming with ZooKeeper - A basic tutorial
Programming with ZooKeeper - A basic tutorial
 
Kotlin from-scratch 3 - coroutines
Kotlin from-scratch 3 - coroutinesKotlin from-scratch 3 - coroutines
Kotlin from-scratch 3 - coroutines
 
The uniform interface is 42
The uniform interface is 42The uniform interface is 42
The uniform interface is 42
 
제 8회 엑셈 수요 세미나 자료 연구컨텐츠팀
제 8회 엑셈 수요 세미나 자료 연구컨텐츠팀제 8회 엑셈 수요 세미나 자료 연구컨텐츠팀
제 8회 엑셈 수요 세미나 자료 연구컨텐츠팀
 

Similaire à Resilience mit Hystrix

Vert.x - Reactive & Distributed [Devoxx version]
Vert.x - Reactive & Distributed [Devoxx version]Vert.x - Reactive & Distributed [Devoxx version]
Vert.x - Reactive & Distributed [Devoxx version]Orkhan Gasimov
 
Слава Бобик «NancyFx для самых маленьких»
Слава Бобик «NancyFx для самых маленьких»Слава Бобик «NancyFx для самых маленьких»
Слава Бобик «NancyFx для самых маленьких»SpbDotNet Community
 
A new execution model for Nashorn in Java 9
A new execution model for Nashorn in Java 9A new execution model for Nashorn in Java 9
A new execution model for Nashorn in Java 9Marcus Lagergren
 
Exceptions and errors in Java
Exceptions and errors in JavaExceptions and errors in Java
Exceptions and errors in JavaManuela Grindei
 
Testing basics for developers
Testing basics for developersTesting basics for developers
Testing basics for developersAnton Udovychenko
 
Unit testing patterns for concurrent code
Unit testing patterns for concurrent codeUnit testing patterns for concurrent code
Unit testing patterns for concurrent codeDror Helper
 
Fault Tolerance in a High Volume, Distributed System
Fault Tolerance in a  High Volume, Distributed SystemFault Tolerance in a  High Volume, Distributed System
Fault Tolerance in a High Volume, Distributed SystemBen Christensen
 
JRuby and Invokedynamic - Japan JUG 2015
JRuby and Invokedynamic - Japan JUG 2015JRuby and Invokedynamic - Japan JUG 2015
JRuby and Invokedynamic - Japan JUG 2015Charles Nutter
 
PhpUnit - The most unknown Parts
PhpUnit - The most unknown PartsPhpUnit - The most unknown Parts
PhpUnit - The most unknown PartsBastian Feder
 
Testing in android
Testing in androidTesting in android
Testing in androidjtrindade
 
Use of Apache Commons and Utilities
Use of Apache Commons and UtilitiesUse of Apache Commons and Utilities
Use of Apache Commons and UtilitiesPramod Kumar
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownpartsBastian Feder
 
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnitinternational PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnitsmueller_sandsmedia
 

Similaire à Resilience mit Hystrix (20)

Resilience with Hystrix
Resilience with HystrixResilience with Hystrix
Resilience with Hystrix
 
Vert.x - Reactive & Distributed [Devoxx version]
Vert.x - Reactive & Distributed [Devoxx version]Vert.x - Reactive & Distributed [Devoxx version]
Vert.x - Reactive & Distributed [Devoxx version]
 
Java 104
Java 104Java 104
Java 104
 
Abstract factory
Abstract factoryAbstract factory
Abstract factory
 
Слава Бобик «NancyFx для самых маленьких»
Слава Бобик «NancyFx для самых маленьких»Слава Бобик «NancyFx для самых маленьких»
Слава Бобик «NancyFx для самых маленьких»
 
A new execution model for Nashorn in Java 9
A new execution model for Nashorn in Java 9A new execution model for Nashorn in Java 9
A new execution model for Nashorn in Java 9
 
Exceptions and errors in Java
Exceptions and errors in JavaExceptions and errors in Java
Exceptions and errors in Java
 
Fault tolerance made easy
Fault tolerance made easyFault tolerance made easy
Fault tolerance made easy
 
Faking Hell
Faking HellFaking Hell
Faking Hell
 
Testing basics for developers
Testing basics for developersTesting basics for developers
Testing basics for developers
 
Unit testing patterns for concurrent code
Unit testing patterns for concurrent codeUnit testing patterns for concurrent code
Unit testing patterns for concurrent code
 
Fault Tolerance in a High Volume, Distributed System
Fault Tolerance in a  High Volume, Distributed SystemFault Tolerance in a  High Volume, Distributed System
Fault Tolerance in a High Volume, Distributed System
 
Unit testing with mock libs
Unit testing with mock libsUnit testing with mock libs
Unit testing with mock libs
 
JRuby and Invokedynamic - Japan JUG 2015
JRuby and Invokedynamic - Japan JUG 2015JRuby and Invokedynamic - Japan JUG 2015
JRuby and Invokedynamic - Japan JUG 2015
 
PhpUnit - The most unknown Parts
PhpUnit - The most unknown PartsPhpUnit - The most unknown Parts
PhpUnit - The most unknown Parts
 
Testing in android
Testing in androidTesting in android
Testing in android
 
Use of Apache Commons and Utilities
Use of Apache Commons and UtilitiesUse of Apache Commons and Utilities
Use of Apache Commons and Utilities
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownparts
 
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnitinternational PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
 
Introduzione al TDD
Introduzione al TDDIntroduzione al TDD
Introduzione al TDD
 

Plus de Java Usergroup Berlin-Brandenburg

Die fabelhafte Welt Java(Script)-getriebener Enterprise-WebApps (mit Ext JS)
Die fabelhafte Welt Java(Script)-getriebener Enterprise-WebApps (mit Ext JS)Die fabelhafte Welt Java(Script)-getriebener Enterprise-WebApps (mit Ext JS)
Die fabelhafte Welt Java(Script)-getriebener Enterprise-WebApps (mit Ext JS)Java Usergroup Berlin-Brandenburg
 
Jbossas7alsplattformmodernerenterprise anwendungen-130604114410-phpapp02
Jbossas7alsplattformmodernerenterprise anwendungen-130604114410-phpapp02Jbossas7alsplattformmodernerenterprise anwendungen-130604114410-phpapp02
Jbossas7alsplattformmodernerenterprise anwendungen-130604114410-phpapp02Java Usergroup Berlin-Brandenburg
 

Plus de Java Usergroup Berlin-Brandenburg (19)

Microbenchmarks - Wer nicht weiß, was er misst misst Mist
Microbenchmarks - Wer nicht weiß, was er misst misst MistMicrobenchmarks - Wer nicht weiß, was er misst misst Mist
Microbenchmarks - Wer nicht weiß, was er misst misst Mist
 
Collections.compare(() -> JDK; Apache; Eclipse, Guava...});
Collections.compare(() -> JDK; Apache; Eclipse, Guava...});Collections.compare(() -> JDK; Apache; Eclipse, Guava...});
Collections.compare(() -> JDK; Apache; Eclipse, Guava...});
 
Built To Last - Nachhaltige Software-Entwicklung
Built To Last - Nachhaltige Software-EntwicklungBuilt To Last - Nachhaltige Software-Entwicklung
Built To Last - Nachhaltige Software-Entwicklung
 
Feature Toggles On Steroids
Feature Toggles On SteroidsFeature Toggles On Steroids
Feature Toggles On Steroids
 
Analysis of software systems using jQAssistant and Neo4j
Analysis of software systems using jQAssistant and Neo4jAnalysis of software systems using jQAssistant and Neo4j
Analysis of software systems using jQAssistant and Neo4j
 
Get Back in Control of your SQL
Get Back in Control of your SQLGet Back in Control of your SQL
Get Back in Control of your SQL
 
Die fabelhafte Welt Java(Script)-getriebener Enterprise-WebApps (mit Ext JS)
Die fabelhafte Welt Java(Script)-getriebener Enterprise-WebApps (mit Ext JS)Die fabelhafte Welt Java(Script)-getriebener Enterprise-WebApps (mit Ext JS)
Die fabelhafte Welt Java(Script)-getriebener Enterprise-WebApps (mit Ext JS)
 
Selbstvorstellung Steria Mummert Consulting
Selbstvorstellung Steria Mummert ConsultingSelbstvorstellung Steria Mummert Consulting
Selbstvorstellung Steria Mummert Consulting
 
Graphdatenbanken mit Neo4j
Graphdatenbanken mit Neo4jGraphdatenbanken mit Neo4j
Graphdatenbanken mit Neo4j
 
Jbosseapclustering 130605100557-phpapp02
Jbosseapclustering 130605100557-phpapp02Jbosseapclustering 130605100557-phpapp02
Jbosseapclustering 130605100557-phpapp02
 
Jbossas7alsplattformmodernerenterprise anwendungen-130604114410-phpapp02
Jbossas7alsplattformmodernerenterprise anwendungen-130604114410-phpapp02Jbossas7alsplattformmodernerenterprise anwendungen-130604114410-phpapp02
Jbossas7alsplattformmodernerenterprise anwendungen-130604114410-phpapp02
 
How long can you afford to Stop The World?
How long can you afford to Stop The World?How long can you afford to Stop The World?
How long can you afford to Stop The World?
 
JavaOne Update zur Java Plattform
JavaOne Update zur Java PlattformJavaOne Update zur Java Plattform
JavaOne Update zur Java Plattform
 
Java EE 7 - Overview and Status
Java EE 7  - Overview and StatusJava EE 7  - Overview and Status
Java EE 7 - Overview and Status
 
Restructuring
RestructuringRestructuring
Restructuring
 
Fighting Layout Bugs
Fighting Layout BugsFighting Layout Bugs
Fighting Layout Bugs
 
Die Java Plattform Strategie
Die Java Plattform StrategieDie Java Plattform Strategie
Die Java Plattform Strategie
 
Continuous Delivery
Continuous DeliveryContinuous Delivery
Continuous Delivery
 
Continuous Delivery in der Praxis
Continuous Delivery in der PraxisContinuous Delivery in der Praxis
Continuous Delivery in der Praxis
 

Dernier

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...Jittipong Loespradit
 
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Bert Jan Schrijver
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...masabamasaba
 
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfPayment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfkalichargn70th171
 
WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2
 
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...masabamasaba
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesVictorSzoltysek
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisamasabamasaba
 
Harnessing ChatGPT - Elevating Productivity in Today's Agile Environment
Harnessing ChatGPT  - Elevating Productivity in Today's Agile EnvironmentHarnessing ChatGPT  - Elevating Productivity in Today's Agile Environment
Harnessing ChatGPT - Elevating Productivity in Today's Agile EnvironmentVictorSzoltysek
 
tonesoftg
tonesoftgtonesoftg
tonesoftglanshi9
 
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 SimplicityWSO2
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024VictoriaMetrics
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension AidPhilip Schwarz
 
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 SoftwareJim McKeeth
 
%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 masabamasaba
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...Shane Coughlan
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Steffen Staab
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...SelfMade bd
 

Dernier (20)

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...
 
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
 
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfPayment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
 
WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?
 
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
Harnessing ChatGPT - Elevating Productivity in Today's Agile Environment
Harnessing ChatGPT  - Elevating Productivity in Today's Agile EnvironmentHarnessing ChatGPT  - Elevating Productivity in Today's Agile Environment
Harnessing ChatGPT - Elevating Productivity in Today's Agile Environment
 
tonesoftg
tonesoftgtonesoftg
tonesoftg
 
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
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
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
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
 

Resilience mit Hystrix

  • 1. Resilience mit Hystrix Eine kurze Einführung für den geneigten Entwickler Uwe Friedrichsen (codecentric AG) – Java Usergroup Berlin-Brandenburg – Berlin, 22. Oktober 2014
  • 2. @ufried Uwe Friedrichsen | uwe.friedrichsen@codecentric.de | http://slideshare.net/ufried | http://ufried.tumblr.com
  • 3. It‘s all about production!
  • 6. re•sil•ience (rɪˈzɪl yəns) also re•sil′ien•cy, n. 1. the power or ability to return to the original form, position, etc., after being bent, compressed, or stretched; elasticity. 2. ability to recover readily from illness, depression, adversity, or the like; buoyancy. Random House Kernerman Webster's College Dictionary, © 2010 K Dictionaries Ltd. Copyright 2005, 1997, 1991 by Random House, Inc. All rights reserved. http://www.thefreedictionary.com/resilience
  • 7. Resilience (IT) The ability of a system to handle unexpected situations - without the user noticing it (best case) - with a graceful degradation of service (worst case)
  • 8. A distributed system is one in which the failure of a computer you didn't even know existed can render your own computer unusable. Leslie Lamport
  • 9. Failures in todays complex, distributed, interconnected systems are not the exception. They are the normal case.
  • 10.
  • 11. Implemented patterns • Timeout • Circuit breaker • Load shedder • Fallback
  • 12. Supported patterns • Bulkheads (a.k.a. Failure Units) • Fail fast • Fail silently • Graceful degradation of service • Failover • Escalation • Retry • ...
  • 13. That‘s been enough theory Give us some code – now!
  • 16. public class HelloCommand extends HystrixCommand<String> { private static final String COMMAND_GROUP = "default"; private final String name; public HelloCommand(String name) { super(HystrixCommandGroupKey.Factory.asKey(COMMAND_GROUP)); this.name = name; } @Override protected String run() throws Exception { return "Hello, " + name; } }
  • 17. @Test public void shouldGreetWorld() { String result = new HelloCommand("World").execute(); assertEquals("Hello, World", result); }
  • 19. @Test public void shouldExecuteSynchronously() { String s = new HelloCommand("Bob").execute(); assertEquals("Hello, Bob", s); }
  • 21. @Test public void shouldExecuteAsynchronously() { Future<String> f = new HelloCommand("Alice").queue(); String s = null; try { s = f.get(); } catch (InterruptedException | ExecutionException e) { // Handle Future.get() exceptions here } assertEquals("Hello, Alice", s); }
  • 23. @Test public void shouldExecuteReactiveSimple() { Observable<String> observable = new HelloCommand("Alice").observe(); String s = observable.toBlockingObservable().single(); assertEquals("Hello, Alice", s); }
  • 25. public class CommandHelloObserver implements Observer<String> { // Needed for communication between observer and test case private final AtomicReference<String> aRef; private final Semaphore semaphore; public CommandHelloObserver(AtomicReference<String> aRef, Semaphore semaphore) { this.aRef = aRef; this.semaphore = semaphore; } @Override public void onCompleted() { // Not needed here } @Override public void onError(Throwable e) { // Not needed here } @Override public void onNext(String s) { aRef.set(s); semaphore.release(); } }
  • 26. @Test public void shouldExecuteReactiveFull() { // Needed for communication between observer and test case AtomicReference<String> aRef = new AtomicReference<>(); Semaphore semaphore = new Semaphore(0); Observable<String> observable = new HelloCommand("Bob").observe(); Observer<String> observer = new CommandHelloObserver(aRef, semaphore); observable.subscribe(observer); // Wait until observer received a result try { semaphore.acquire(); } catch (InterruptedException e) { // Handle exceptions here } String s = aRef.get(); assertEquals("Hello, Bob", s); }
  • 28. public class FallbackCommand extends HystrixCommand<String> { private static final String COMMAND_GROUP = "default"; public FallbackCommand() { super(HystrixCommandGroupKey.Factory.asKey(COMMAND_GROUP)); } @Override protected String run() throws Exception { throw new RuntimeException("I will always fail"); } @Override protected String getFallback() { return "Powered by fallback"; } }
  • 29. @Test public void shouldGetFallbackResponse() { String s = new FallbackCommand().execute(); assertEquals("Powered by fallback", s); }
  • 31. public class ErrorPropagationCommand extends HystrixCommand<String> { private static final String COMMAND_GROUP = "default"; protected ErrorPropagationCommand() { super(HystrixCommandGroupKey.Factory.asKey(COMMAND_GROUP)); } @Override protected String run() throws Exception { throw new HystrixBadRequestException("I fail differently", new RuntimeException("I will always fail")); } @Override protected String getFallback() { return "Powered by fallback"; } }
  • 32. @Test public void shouldGetFallbackResponse() { String s = null; try { s = new ErrorPropagationCommand().execute(); fail(); // Just to make sure } catch (HystrixBadRequestException e) { assertEquals("I will fail differently", e.getMessage()); assertEquals("I will always fail", e.getCause().getMessage()); } assertNull(s); // Fallback is not triggered }
  • 38. Configuration • Based on Archaius by Netflix which extends the Apache Commons Configuration Library • Four levels of precedence 1. Global default from code 2. Dynamic global default property 3. Instance default from code 4. Dynamic instance property Provides many configuration & tuning options
  • 39. Configuration – Some examples • hystrix.command.*.execution.isolation.strategy Either “THREAD” or “SEMAPHORE” (Default: THREAD) • hystrix.command.*.execution.isolation.thread.timeoutInMilliseconds Time to wait for the run() method to complete (Default: 1000) • h.c.*.execution.isolation.semaphore.maxConcurrentRequests Maximum number of concurrent requests when using semaphores (Default: 10) • hystrix.command.*.circuitBreaker.errorThresholdPercentage Error percentage at which the breaker trips open (Default: 50) • hystrix.command.*.circuitBreaker.sleepWindowInMilliseconds Time to wait before attempting to reset the breaker after tripping (Default: 5000) * must be either “default” or the command key name
  • 40. Configuration – More examples • hystrix.threadpool.*.coreSize Maximum number of concurrent requests when using thread pools (Default: 10) • hystrix.threadpool.*.maxQueueSize Maximum LinkedBlockingQueue size - -1 for using SynchronousQueue (Default: -1) • hystrix.threadpool.default.queueSizeRejectionThreshold Queue size rejection threshold (Default: 5) … and many more * must be either “default” or the thread pool key name
  • 43. public class LatentResource { private final long latency; public LatentResource(long latency) { this.latency = ((latency < 0L) ? 0L : latency); } public String getData() { addLatency(); // This is the important part return "Some value”; } private void addLatency() { try { Thread.sleep(latency); } catch (InterruptedException e) { // We do not care about this here } } }
  • 44. public class TimeoutCommand extends HystrixCommand<String> { private static final String COMMAND_GROUP = "default"; private final LatentResource resource; public TimeoutCommand(int timeout, LatentResource resource) { super(Setter.withGroupKey( HystrixCommandGroupKey.Factory.asKey(COMMAND_GROUP)) .andCommandPropertiesDefaults( HystrixCommandProperties.Setter() .withExecutionIsolationThreadTimeoutInMilliseconds( timeout))); this.resource = resource; } @Override protected String run() throws Exception { return resource.getData(); } @Override protected String getFallback() { return "Resource timed out"; } }
  • 45. @Test public void shouldGetNormalResponse() { LatentResource resource = new LatentResource(50L); TimeoutCommand command = new TimeoutCommand(100, resource); String s = command.execute(); assertEquals("Some value", s); } @Test public void shouldGetFallbackResponse() { LatentResource resource = new LatentResource(150L); TimeoutCommand command = new TimeoutCommand(100, resource); String s = command.execute(); assertEquals("Resource timed out", s); }
  • 47. public class CircuitBreakerCommand extends HystrixCommand<String> { private static final String COMMAND_GROUP = "default"; public CircuitBreakerCommand(String name, boolean open) { super(Setter.withGroupKey( HystrixCommandGroupKey.Factory.asKey(COMMAND_GROUP)) .andCommandKey(HystrixCommandKey.Factory.asKey(name)) .andCommandPropertiesDefaults( HystrixCommandProperties.Setter() .withCircuitBreakerForceOpen(open))); } @Override protected String run() throws Exception { return("Some result"); } @Override protected String getFallback() { return "Fallback response"; } }
  • 48. @Test public void shouldExecuteWithCircuitBreakerClosed() { CircuitBreakerCommand command = new CircuitBreakerCommand("ClosedBreaker", false); String s = command.execute(); assertEquals("Some result", s); HystrixCircuitBreaker breaker = HystrixCircuitBreaker.Factory .getInstance(command.getCommandKey()); assertTrue(breaker.allowRequest()); }
  • 49. @Test public void shouldExecuteWithCircuitBreakerOpen() { CircuitBreakerCommand command = new CircuitBreakerCommand("OpenBreaker", true); String s = command.execute(); assertEquals("Fallback response", s); HystrixCircuitBreaker breaker = HystrixCircuitBreaker.Factory .getInstance(command.getCommandKey()); assertFalse(breaker.allowRequest()); }
  • 51. public class LatentCommand extends HystrixCommand<String> { private static final String COMMAND_GROUP = "default"; private final LatentResource resource; public LatentCommand(LatentResource resource) { super(HystrixCommandGroupKey.Factory.asKey(COMMAND_GROUP)); this.resource = resource; } @Override protected String run() throws Exception { return resource.getData(); } @Override protected String getFallback() { return "Fallback triggered"; } }
  • 52. @Test public void shouldShedLoad() { List<Future<String>> l = new LinkedList<>(); LatentResource resource = new LatentResource(500L); // Make latent // Use up all available threads for (int i = 0; i < 10; i++) l.add(new LatentCommand(resource).queue()); // Call will be rejected as thread pool is exhausted String s = new LatentCommand(resource).execute(); assertEquals("Fallback triggered", s); // All other calls succeed for (Future<String> f : l) assertEquals("Some value", get(f)); // wrapper for f.get() }
  • 54. public class SemaphoreCommand extends HystrixCommand<String> { private static final String COMMAND_GROUP = "default"; private final LatentResource resource; public SemaphoreCommand(LatentResource resource) { super(Setter.withGroupKey( HystrixCommandGroupKey.Factory.asKey(COMMAND_GROUP)) .andCommandPropertiesDefaults( HystrixCommandProperties.Setter() .withExecutionIsolationStrategy(HystrixCommandProperties .ExecutionIsolationStrategy.SEMAPHORE))); this.resource = resource; } @Override protected String run() throws Exception { return resource.getData(); } @Override protected String getFallback() { return "Fallback triggered"; } }
  • 55. private class SemaphoreCommandInvocation implements java.util.concurrent.Callable<String> { private final LatentResource resource; public SemaphoreCommandInvocation(LatentResource resource) { this.resource = resource; } @Override public String call() throws Exception { return new SemaphoreCommand(resource).execute(); } }
  • 56. @Test public void shouldShedLoad() { List<Future<String>> l = new LinkedList<>(); LatentResource resource = new LatentResource(500L); // Make latent ExecutorService e = Executors.newFixedThreadPool(10); // Use up all available semaphores for (int i = 0; i < 10; i++) l.add(e.submit(new SemaphoreCommandInvocation(resource))); // Wait a moment to make sure all commands are started pause(250L); // Wrapper around Thread.sleep() // Call will be rejected as all semaphores are in use String s = new SemaphoreCommand(resource).execute(); assertEquals("Fallback triggered", s); // All other calls succeed for (Future<String> f : l) assertEquals("Some value", get(f)); }
  • 58. public class FailFastCommand extends HystrixCommand<String> { private static final String COMMAND_GROUP = "default"; private final boolean preCondition; public FailFastCommand(boolean preCondition) { super(HystrixCommandGroupKey.Factory.asKey(COMMAND_GROUP)); this.preCondition = preCondition; } @Override protected String run() throws Exception { if (!preCondition) throw new RuntimeException(("Fail fast")); return "Some value"; } }
  • 59. @Test public void shouldSucceed() { FailFastCommand command = new FailFastCommand(true); String s = command.execute(); assertEquals("Some value", s); } @Test public void shouldFailFast() { FailFastCommand command = new FailFastCommand(false); try { String s = command.execute(); fail("Did not fail fast"); } catch (Exception e) { assertEquals(HystrixRuntimeException.class, e.getClass()); assertEquals("Fail fast", e.getCause().getMessage()); } }
  • 61. public class FailSilentCommand extends HystrixCommand<String> { private static final String COMMAND_GROUP = "default"; private final boolean preCondition; public FailSilentCommand(boolean preCondition) { super(HystrixCommandGroupKey.Factory.asKey(COMMAND_GROUP)); this.preCondition = preCondition; } @Override protected String run() throws Exception { if (!preCondition) throw new RuntimeException(("Fail fast")); return "Some value"; } @Override protected String getFallback() { return null; // Turn into silent failure } }
  • 62. @Test public void shouldSucceed() { FailSilentCommand command = new FailSilentCommand(true); String s = command.execute(); assertEquals("Some value", s); } @Test public void shouldFailSilent() { FailSilentCommand command = new FailSilentCommand(false); String s = "Test value"; try { s = command.execute(); } catch (Exception e) { fail("Did not fail silently"); } assertNull(s); }
  • 64. public class StaticFallbackCommand extends HystrixCommand<String> { private static final String COMMAND_GROUP = "default"; private final boolean preCondition; public StaticFallbackCommand(boolean preCondition) { super(HystrixCommandGroupKey.Factory.asKey(COMMAND_GROUP)); this.preCondition = preCondition; } @Override protected String run() throws Exception { if (!preCondition) throw new RuntimeException(("Fail fast")); return "Some value"; } @Override protected String getFallback() { return "Some static fallback value"; // Static fallback } }
  • 65. @Test public void shouldSucceed() { StaticFallbackCommand command = new StaticFallbackCommand(true); String s = command.execute(); assertEquals("Some value", s); } @Test public void shouldProvideStaticFallback() { StaticFallbackCommand command = new StaticFallbackCommand(false); String s = null; try { s = command.execute(); } catch (Exception e) { fail("Did not fail silent"); } assertEquals("Some static fallback value", s); }
  • 67. public class CacheClient { private final Map<String, String> map; public CacheClient() { map = new ConcurrentHashMap<>(); } public void add(String key, String value) { map.put(key, value); } public String get(String key) { return map.get(key); } }
  • 68. public class CacheCommand extends HystrixCommand<String> { private static final String COMMAND_GROUP = "primary"; private final CacheClient cache; private final boolean failPrimary; private final String req; public CacheCommand(CacheClient cache, boolean failPrimary, String request) { super(HystrixCommandGroupKey.Factory.asKey(COMMAND_GROUP)); this.cache = cache; this.failPrimary = failPrimary; this.req = request; } @Override protected String run() throws Exception { if (failPrimary) throw new RuntimeException("Failure of primary"); String s = req + "-o"; cache.add(req, s); return(s); } …
  • 69. … @Override protected String getFallback() { return "Cached: " + new FBCommand(cache, req).execute(); } private static class FBCommand extends HystrixCommand<String> { private static final String COMMAND_GROUP = "fallback"; private final CacheClient cache; private final String request; public FBCommand(CacheClient cache, String request) { super(HystrixCommandGroupKey.Factory.asKey(COMMAND_GROUP)); this.cache = cache; this.request = request; } @Override protected String run() throws Exception { return cache.get(request); } } }
  • 70. @Test public void shouldExecuteWithoutCache() { CacheClient cache = new CacheClient(); String s = new CacheCommand(cache, false, "ping”).execute(); assertEquals("ping-o", s); } @Test public void shouldRetrieveValueFromCache() { CacheClient cache = new CacheClient(); new CacheCommand(cache, false, "ping").execute(); String s = new CacheCommand(cache, true, "ping”).execute(); assertEquals("Cached: ping-o", s); } @Test public void shouldNotRetrieveAnyValue() { CacheClient cache = new CacheClient(); String s = new CacheCommand(cache, true, "ping”).execute(); assertEquals("Cached: null", s); }
  • 73. Advanced Features • Request Caching • Request Collapsing • Plugins Event Notifier, Metrics Publisher, Properties Strategy, Concurrency Strategy, Command Execution Hook • Contributions Metrics Event Stream, Metrics Publisher, Java Annotations, Clojure Bindings, … • Dashboard
  • 76. Further reading 1. Hystrix Wiki, https://github.com/Netflix/Hystrix/wiki 2. Michael T. Nygard, Release It!, Pragmatic Bookshelf, 2007 3. Robert S. Hanmer, Patterns for Fault Tolerant Software, Wiley, 2007 4. Andrew Tanenbaum, Marten van Steen, Distributed Systems – Principles and Paradigms, Prentice Hall, 2nd Edition, 2006
  • 77. Wrap-up • Resilient software design becomes a must • Hystrix is a resilience library • Provides isolation and latency control • Easy to start with • Yet some learning curve • Many fault-tolerance patterns implementable • Many configuration options • Customizable • Operations proven Become a resilient software developer!
  • 78. It‘s all about production!
  • 79. @ufried Uwe Friedrichsen | uwe.friedrichsen@codecentric.de | http://slideshare.net/ufried | http://ufried.tumblr.com