61 lines
11 KiB
HTML
61 lines
11 KiB
HTML
<html><head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
|
<title>13. Circuit Breaker: Hystrix Clients</title><link rel="stylesheet" type="text/css" href="css/manual-multipage.css"><meta name="generator" content="DocBook XSL Stylesheets V1.79.1"><link rel="home" href="multi_spring-cloud.html" title="Spring Cloud"><link rel="up" href="multi__spring_cloud_netflix.html" title="Part III. Spring Cloud Netflix"><link rel="prev" href="multi_spring-cloud-eureka-server.html" title="12. Service Discovery: Eureka Server"><link rel="next" href="multi__circuit_breaker_hystrix_dashboard.html" title="14. Circuit Breaker: Hystrix Dashboard"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">13. Circuit Breaker: Hystrix Clients</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="multi_spring-cloud-eureka-server.html">Prev</a> </td><th width="60%" align="center">Part III. Spring Cloud Netflix</th><td width="20%" align="right"> <a accesskey="n" href="multi__circuit_breaker_hystrix_dashboard.html">Next</a></td></tr></table><hr></div><div class="chapter"><div class="titlepage"><div><div><h2 class="title"><a name="_circuit_breaker_hystrix_clients" href="#_circuit_breaker_hystrix_clients"></a>13. Circuit Breaker: Hystrix Clients</h2></div></div></div><p>Netflix has created a library called <a class="link" href="https://github.com/Netflix/Hystrix" target="_top">Hystrix</a> that implements the <a class="link" href="https://martinfowler.com/bliki/CircuitBreaker.html" target="_top">circuit breaker pattern</a>.
|
|
In a microservice architecture, it is common to have multiple layers of service calls, as shown in the following example:</p><div class="figure"><a name="d0e4627" href="#d0e4627"></a><p class="title"><b>Figure 13.1. Microservice Graph</b></p><div class="figure-contents"><div class="mediaobject"><img src="https://raw.githubusercontent.com/spring-cloud/spring-cloud-netflix/master/docs/src/main/asciidoc/images/Hystrix.png" alt="Hystrix"></div></div></div><br class="figure-break"><p>A service failure in the lower level of services can cause cascading failure all the way up to the user.
|
|
When calls to a particular service exceed <code class="literal">circuitBreaker.requestVolumeThreshold</code> (default: 20 requests) and the failure percentage is greater than <code class="literal">circuitBreaker.errorThresholdPercentage</code> (default: >50%) in a rolling window defined by <code class="literal">metrics.rollingStats.timeInMilliseconds</code> (default: 10 seconds), the circuit opens and the call is not made.
|
|
In cases of error and an open circuit, a fallback can be provided by the developer.</p><div class="figure"><a name="d0e4647" href="#d0e4647"></a><p class="title"><b>Figure 13.2. Hystrix fallback prevents cascading failures</b></p><div class="figure-contents"><div class="mediaobject"><img src="https://raw.githubusercontent.com/spring-cloud/spring-cloud-netflix/master/docs/src/main/asciidoc/images/HystrixFallback.png" alt="HystrixFallback"></div></div></div><br class="figure-break"><p>Having an open circuit stops cascading failures and allows overwhelmed or failing services time to recover.
|
|
The fallback can be another Hystrix protected call, static data, or a sensible empty value.
|
|
Fallbacks may be chained so that the first fallback makes some other business call, which in turn falls back to static data.</p><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_how_to_include_hystrix" href="#_how_to_include_hystrix"></a>13.1 How to Include Hystrix</h2></div></div></div><p>To include Hystrix in your project, use the starter with a group ID of <code class="literal">org.springframework.cloud</code>
|
|
and a artifact ID of <code class="literal">spring-cloud-starter-netflix-hystrix</code>.
|
|
See the <a class="link" href="https://projects.spring.io/spring-cloud/" target="_top">Spring Cloud Project page</a> for details on setting up your build system with the current Spring Cloud Release Train.</p><p>The following example shows a minimal Eureka server with a Hystrix circuit breaker:</p><pre class="screen">@SpringBootApplication
|
|
@EnableCircuitBreaker
|
|
public class Application {
|
|
|
|
public static void main(String[] args) {
|
|
new SpringApplicationBuilder(Application.class).web(true).run(args);
|
|
}
|
|
|
|
}
|
|
|
|
@Component
|
|
public class StoreIntegration {
|
|
|
|
@HystrixCommand(fallbackMethod = "defaultStores")
|
|
public Object getStores(Map<String, Object> parameters) {
|
|
//do stuff that might fail
|
|
}
|
|
|
|
public Object defaultStores(Map<String, Object> parameters) {
|
|
return /* something useful */;
|
|
}
|
|
}</pre><p>The <code class="literal">@HystrixCommand</code> is provided by a Netflix contrib library called <a class="link" href="https://github.com/Netflix/Hystrix/tree/master/hystrix-contrib/hystrix-javanica" target="_top"><span class="quote">“<span class="quote">javanica</span>”</span></a>.
|
|
Spring Cloud automatically wraps Spring beans with that annotation in a proxy that is connected to the Hystrix circuit breaker.
|
|
The circuit breaker calculates when to open and close the circuit and what to do in case of a failure.</p><p>To configure the <code class="literal">@HystrixCommand</code> you can use the <code class="literal">commandProperties</code>
|
|
attribute with a list of <code class="literal">@HystrixProperty</code> annotations. See
|
|
<a class="link" href="https://github.com/Netflix/Hystrix/tree/master/hystrix-contrib/hystrix-javanica#configuration" target="_top">here</a>
|
|
for more details. See the <a class="link" href="https://github.com/Netflix/Hystrix/wiki/Configuration" target="_top">Hystrix wiki</a>
|
|
for details on the properties available.</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="netflix-hystrix-starter" href="#netflix-hystrix-starter"></a>13.2 Propagating the Security Context or Using Spring Scopes</h2></div></div></div><p>If you want some thread local context to propagate into a <code class="literal">@HystrixCommand</code>, the default declaration does not work, because it executes the command in a thread pool (in case of timeouts).
|
|
You can switch Hystrix to use the same thread as the caller through configuration or directly in the annotation, by asking it to use a different <span class="quote">“<span class="quote">Isolation Strategy</span>”</span>.
|
|
The following example demonstrates setting the thread in the annotation:</p><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@HystrixCommand(fallbackMethod = "stubMyService",
|
|
commandProperties = {
|
|
@HystrixProperty(name="execution.isolation.strategy", value="SEMAPHORE")
|
|
}
|
|
)</span></em>
|
|
...</pre><p>The same thing applies if you are using <code class="literal">@SessionScope</code> or <code class="literal">@RequestScope</code>.
|
|
If you encounter a runtime exception that says it cannot find the scoped context, you need to use the same thread.</p><p>You also have the option to set the <code class="literal">hystrix.shareSecurityContext</code> property to <code class="literal">true</code>.
|
|
Doing so auto-configures a Hystrix concurrency strategy plugin hook to transfer the <code class="literal">SecurityContext</code> from your main thread to the one used by the Hystrix command.
|
|
Hystrix does not let multiple Hystrix concurrency strategy be registered so an extension mechanism is available by declaring your own <code class="literal">HystrixConcurrencyStrategy</code> as a Spring bean.
|
|
Spring Cloud looks for your implementation within the Spring context and wrap it inside its own plugin.</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_health_indicator_4" href="#_health_indicator_4"></a>13.3 Health Indicator</h2></div></div></div><p>The state of the connected circuit breakers are also exposed in the <code class="literal">/health</code> endpoint of the calling application, as shown in the following example:</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"hystrix"</span>: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"openCircuitBreakers"</span>: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">[</span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"StoreIntegration::getStoresByLocationLink"</span>
|
|
]<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">,</span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"status"</span>: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"CIRCUIT_OPEN"</span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">},</span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"status"</span>: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"UP"</span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">}</span></pre></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_hystrix_metrics_stream" href="#_hystrix_metrics_stream"></a>13.4 Hystrix Metrics Stream</h2></div></div></div><p>To enable the Hystrix metrics stream, include a dependency on <code class="literal">spring-boot-starter-actuator</code> and set
|
|
<code class="literal">management.endpoints.web.exposure.include: hystrix.stream</code>.
|
|
Doing so exposes the <code class="literal">/actuator/hystrix.stream</code> as a management endpoint, as shown in the following example:</p><pre class="programlisting"> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><dependency></span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><groupId></span>org.springframework.boot<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></groupId></span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><artifactId></span>spring-boot-starter-actuator<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></artifactId></span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></dependency></span></pre></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="multi_spring-cloud-eureka-server.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="multi__spring_cloud_netflix.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="multi__circuit_breaker_hystrix_dashboard.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">12. Service Discovery: Eureka Server </td><td width="20%" align="center"><a accesskey="h" href="multi_spring-cloud.html">Home</a></td><td width="40%" align="right" valign="top"> 14. Circuit Breaker: Hystrix Dashboard</td></tr></table></div></body></html> |