mirror of
https://github.com/spring-cloud/spring-cloud-netflix.git
synced 2026-09-29 07:49:00 +00:00
Sync docs from master to gh-pages
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
<html><head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>13. HTTP Clients</title><link rel="stylesheet" type="text/css" href="css/manual-multipage.css"><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"><link rel="home" href="multi_spring-cloud-netflix.html" title="Spring Cloud Netflix"><link rel="up" href="multi_spring-cloud-netflix.html" title="Spring Cloud Netflix"><link rel="prev" href="multi_retrying-failed-requests.html" title="12. Retrying Failed Requests"></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. HTTP Clients</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="multi_retrying-failed-requests.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> </td></tr></table><hr></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="_http_clients" href="#_http_clients"></a>13. HTTP Clients</h1></div></div></div><p>Spring Cloud Netflix automatically creates the HTTP client used by Ribbon, Feign, and Zuul for you.
|
||||
<title>11. HTTP Clients</title><link rel="stylesheet" type="text/css" href="css/manual-multipage.css"><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"><link rel="home" href="multi_spring-cloud-netflix.html" title="Spring Cloud Netflix"><link rel="up" href="multi_spring-cloud-netflix.html" title="Spring Cloud Netflix"><link rel="prev" href="multi_retrying-failed-requests.html" title="10. Retrying Failed Requests"></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">11. HTTP Clients</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="multi_retrying-failed-requests.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> </td></tr></table><hr></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="_http_clients" href="#_http_clients"></a>11. HTTP Clients</h1></div></div></div><p>Spring Cloud Netflix automatically creates the HTTP client used by Ribbon, Feign, and Zuul for you.
|
||||
However, you can also provide your own HTTP clients customized as you need them to be.
|
||||
To do so, you can create a bean of type <code class="literal">ClosableHttpClient</code> if you
|
||||
are using the Apache Http Cient or <code class="literal">OkHttpClient</code> if you are using OK HTTP.</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/note.png"></td><th align="left">Note</th></tr><tr><td align="left" valign="top"><p>When you create your own HTTP client, you are also responsible for implementing the correct connection management strategies for these clients.
|
||||
Doing so improperly can result in resource management issues.</p></td></tr></table></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="multi_retrying-failed-requests.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> </td></tr><tr><td width="40%" align="left" valign="top">12. Retrying Failed Requests </td><td width="20%" align="center"><a accesskey="h" href="multi_spring-cloud-netflix.html">Home</a></td><td width="40%" align="right" valign="top"> </td></tr></table></div></body></html>
|
||||
Doing so improperly can result in resource management issues.</p></td></tr></table></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="multi_retrying-failed-requests.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> </td></tr><tr><td width="40%" align="left" valign="top">10. Retrying Failed Requests </td><td width="20%" align="center"><a accesskey="h" href="multi_spring-cloud-netflix.html">Home</a></td><td width="40%" align="right" valign="top"> </td></tr></table></div></body></html>
|
||||
@@ -1,6 +1,6 @@
|
||||
<html><head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>9. Polyglot support with Sidecar</title><link rel="stylesheet" type="text/css" href="css/manual-multipage.css"><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"><link rel="home" href="multi_spring-cloud-netflix.html" title="Spring Cloud Netflix"><link rel="up" href="multi_spring-cloud-netflix.html" title="Spring Cloud Netflix"><link rel="prev" href="multi__router_and_filter_zuul.html" title="8. Router and Filter: Zuul"><link rel="next" href="multi_netflix-metrics.html" title="10. Metrics: Spectator, Servo, and Atlas"></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">9. Polyglot support with Sidecar</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="multi__router_and_filter_zuul.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="multi_netflix-metrics.html">Next</a></td></tr></table><hr></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="_polyglot_support_with_sidecar" href="#_polyglot_support_with_sidecar"></a>9. Polyglot support with Sidecar</h1></div></div></div><p>Do you have non-JVM languages with which you want to take advantage of Eureka, Ribbon, and Config Server?
|
||||
<title>9. Polyglot support with Sidecar</title><link rel="stylesheet" type="text/css" href="css/manual-multipage.css"><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"><link rel="home" href="multi_spring-cloud-netflix.html" title="Spring Cloud Netflix"><link rel="up" href="multi_spring-cloud-netflix.html" title="Spring Cloud Netflix"><link rel="prev" href="multi__router_and_filter_zuul.html" title="8. Router and Filter: Zuul"><link rel="next" href="multi_retrying-failed-requests.html" title="10. Retrying Failed Requests"></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">9. Polyglot support with Sidecar</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="multi__router_and_filter_zuul.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="multi_retrying-failed-requests.html">Next</a></td></tr></table><hr></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="_polyglot_support_with_sidecar" href="#_polyglot_support_with_sidecar"></a>9. Polyglot support with Sidecar</h1></div></div></div><p>Do you have non-JVM languages with which you want to take advantage of Eureka, Ribbon, and Config Server?
|
||||
The Spring Cloud Netflix Sidecar was inspired by <a class="link" href="https://github.com/Netflix/Prana" target="_top">Netflix Prana</a>.
|
||||
It includes an HTTP API to get all of the instances (by host and port) for a given service.
|
||||
You can also proxy service calls through an embedded Zuul proxy that gets its route entries from Eureka.
|
||||
@@ -55,4 +55,4 @@ might result in a YAML document resembling the following:</p><pre class="program
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute"> password</span>: password
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">info</span>:
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute"> description</span>: Spring Cloud Samples
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute"> url</span>: https://github.com/spring-cloud-samples</pre></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="multi__router_and_filter_zuul.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="multi_netflix-metrics.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">8. Router and Filter: Zuul </td><td width="20%" align="center"><a accesskey="h" href="multi_spring-cloud-netflix.html">Home</a></td><td width="40%" align="right" valign="top"> 10. Metrics: Spectator, Servo, and Atlas</td></tr></table></div></body></html>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute"> url</span>: https://github.com/spring-cloud-samples</pre></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="multi__router_and_filter_zuul.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="multi_retrying-failed-requests.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">8. Router and Filter: Zuul </td><td width="20%" align="center"><a accesskey="h" href="multi_spring-cloud-netflix.html">Home</a></td><td width="40%" align="right" valign="top"> 10. Retrying Failed Requests</td></tr></table></div></body></html>
|
||||
@@ -1,11 +1,11 @@
|
||||
<html><head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>12. Retrying Failed Requests</title><link rel="stylesheet" type="text/css" href="css/manual-multipage.css"><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"><link rel="home" href="multi_spring-cloud-netflix.html" title="Spring Cloud Netflix"><link rel="up" href="multi_spring-cloud-netflix.html" title="Spring Cloud Netflix"><link rel="prev" href="multi_netflix-metrics-atlas.html" title="11. Metrics Backend: Atlas"><link rel="next" href="multi__http_clients.html" title="13. HTTP Clients"></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">12. Retrying Failed Requests</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="multi_netflix-metrics-atlas.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="multi__http_clients.html">Next</a></td></tr></table><hr></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="retrying-failed-requests" href="#retrying-failed-requests"></a>12. Retrying Failed Requests</h1></div></div></div><p>Spring Cloud Netflix offers a variety of ways to make HTTP requests.
|
||||
<title>10. Retrying Failed Requests</title><link rel="stylesheet" type="text/css" href="css/manual-multipage.css"><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"><link rel="home" href="multi_spring-cloud-netflix.html" title="Spring Cloud Netflix"><link rel="up" href="multi_spring-cloud-netflix.html" title="Spring Cloud Netflix"><link rel="prev" href="multi__polyglot_support_with_sidecar.html" title="9. Polyglot support with Sidecar"><link rel="next" href="multi__http_clients.html" title="11. HTTP Clients"></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">10. Retrying Failed Requests</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="multi__polyglot_support_with_sidecar.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="multi__http_clients.html">Next</a></td></tr></table><hr></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="retrying-failed-requests" href="#retrying-failed-requests"></a>10. Retrying Failed Requests</h1></div></div></div><p>Spring Cloud Netflix offers a variety of ways to make HTTP requests.
|
||||
You can use a load balanced <code class="literal">RestTemplate</code>, Ribbon, or Feign.
|
||||
No matter how you choose to create your HTTP requests, there is always a chance that a request may fail.
|
||||
When a request fails, you may want to have the request be retried automatically.
|
||||
To do so when using Sping Cloud Netflix, you need to include <a class="link" href="https://github.com/spring-projects/spring-retry" target="_top">Spring Retry</a> on your application’s classpath.
|
||||
When Spring Retry is present, load-balanced <code class="literal">RestTemplates</code>, Feign, and Zuul automatically retry any failed requests (assuming your configuration allows doing so).</p><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_backoff_policies" href="#_backoff_policies"></a>12.1 BackOff Policies</h2></div></div></div><p>By default, no backoff policy is used when retrying requests.
|
||||
When Spring Retry is present, load-balanced <code class="literal">RestTemplates</code>, Feign, and Zuul automatically retry any failed requests (assuming your configuration allows doing so).</p><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_backoff_policies" href="#_backoff_policies"></a>10.1 BackOff Policies</h2></div></div></div><p>By default, no backoff policy is used when retrying requests.
|
||||
If you would like to configure a backoff policy, you need to create a bean of type <code class="literal">LoadBalancedBackOffPolicyFactory</code>, which is used to create a <code class="literal">BackOffPolicy</code> for a given service, as shown in the following example:</p><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@Configuration</span></em>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">class</span> MyConfiguration {
|
||||
<em><span class="hl-annotation" style="color: gray">@Bean</span></em>
|
||||
@@ -17,11 +17,11 @@ If you would like to configure a backoff policy, you need to create a bean of ty
|
||||
}
|
||||
};
|
||||
}
|
||||
}</pre></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_configuration" href="#_configuration"></a>12.2 Configuration</h2></div></div></div><p>When you use Ribbon with Spring Retry, you can control the retry functionality by configuring certain Ribbon properties.
|
||||
}</pre></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_configuration" href="#_configuration"></a>10.2 Configuration</h2></div></div></div><p>When you use Ribbon with Spring Retry, you can control the retry functionality by configuring certain Ribbon properties.
|
||||
To do so, set the <code class="literal">client.ribbon.MaxAutoRetries</code>, <code class="literal">client.ribbon.MaxAutoRetriesNextServer</code>, and <code class="literal">client.ribbon.OkToRetryOnAllOperations</code> properties.
|
||||
See the <a class="link" href="https://github.com/Netflix/ribbon/wiki/Getting-Started#the-properties-file-sample-clientproperties" target="_top">Ribbon documentation</a> for a description of what these properties do.</p><div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Warning"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Warning]" src="images/warning.png"></td><th align="left">Warning</th></tr><tr><td align="left" valign="top"><p>Enabling <code class="literal">client.ribbon.OkToRetryOnAllOperations</code> includes retrying POST requests, which can have an impact
|
||||
on the server’s resources, due to the buffering of the request body.</p></td></tr></table></div><p>In addition, you may want to retry requests when certain status codes are returned in the response.
|
||||
You can list the response codes you would like the Ribbon client to retry by setting the <code class="literal">clientName.ribbon.retryableStatusCodes</code> property, as shown in the following example:</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">clientName</span>:
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute"> ribbon</span>:
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute"> retryableStatusCodes</span>: <span class="hl-number">404</span>,<span class="hl-number">502</span></pre><p>You can also create a bean of type <code class="literal">LoadBalancedRetryPolicy</code> and implement the <code class="literal">retryableStatusCode</code> method to retry a request given the status code.</p><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_zuul" href="#_zuul"></a>12.2.1 Zuul</h3></div></div></div><p>You can turn off Zuul’s retry functionality by setting <code class="literal">zuul.retryable</code> to <code class="literal">false</code>.
|
||||
You can also disable retry functionality on a route-by-route basis by setting <code class="literal">zuul.routes.routename.retryable</code> to <code class="literal">false</code>.</p></div></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="multi_netflix-metrics-atlas.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="multi__http_clients.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">11. Metrics Backend: Atlas </td><td width="20%" align="center"><a accesskey="h" href="multi_spring-cloud-netflix.html">Home</a></td><td width="40%" align="right" valign="top"> 13. HTTP Clients</td></tr></table></div></body></html>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute"> retryableStatusCodes</span>: <span class="hl-number">404</span>,<span class="hl-number">502</span></pre><p>You can also create a bean of type <code class="literal">LoadBalancedRetryPolicy</code> and implement the <code class="literal">retryableStatusCode</code> method to retry a request given the status code.</p><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_zuul" href="#_zuul"></a>10.2.1 Zuul</h3></div></div></div><p>You can turn off Zuul’s retry functionality by setting <code class="literal">zuul.retryable</code> to <code class="literal">false</code>.
|
||||
You can also disable retry functionality on a route-by-route basis by setting <code class="literal">zuul.routes.routename.retryable</code> to <code class="literal">false</code>.</p></div></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="multi__polyglot_support_with_sidecar.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="multi__http_clients.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">9. Polyglot support with Sidecar </td><td width="20%" align="center"><a accesskey="h" href="multi_spring-cloud-netflix.html">Home</a></td><td width="40%" align="right" valign="top"> 11. HTTP Clients</td></tr></table></div></body></html>
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1945,240 +1945,6 @@ info:
|
||||
description: Spring Cloud Samples
|
||||
url: https://github.com/spring-cloud-samples</programlisting>
|
||||
</chapter>
|
||||
<chapter xml:id="netflix-metrics">
|
||||
<title>Metrics: Spectator, Servo, and Atlas</title>
|
||||
<simpara>When used together, Spectator (or Servo) and Atlas provide a near real-time operational insight platform.
|
||||
Spectator and Servo are Netflix’s metrics collection libraries.
|
||||
Atlas is a Netflix metrics backend that manages dimensional time-series data.</simpara>
|
||||
<simpara>Servo served Netflix for several years and is still usable but is gradually being phased out in favor of Spectator, which is designed to work only with Java 8.
|
||||
Spring Cloud Netflix provides support for both, but Java 8-based applications are encouraged to use Spectator.</simpara>
|
||||
<section xml:id="_dimensional_versus_hierarchical_metrics">
|
||||
<title>Dimensional Versus Hierarchical Metrics</title>
|
||||
<simpara>Spring Boot Actuator metrics are hierarchical, and the metrics are separated only by name.
|
||||
These names often follow a naming convention that embeds key/value attribute pairs (dimensions) into the name (separated by periods).
|
||||
Consider the following metrics for two endpoints, <literal>root</literal> and <literal>star-star</literal>:</simpara>
|
||||
<programlisting language="json" linenumbering="unnumbered">{
|
||||
"counter.status.200.root": 20,
|
||||
"counter.status.400.root": 3,
|
||||
"counter.status.200.star-star": 5,
|
||||
}</programlisting>
|
||||
<simpara>The first metric gives us a normalized count of successful requests against the root endpoint per unit of time.
|
||||
But what if the system has 20 endpoints and you want to get a count of successful requests against all the endpoints?
|
||||
Some hierarchical metrics backends would let you specify a wildcard, such as <literal>counter.status.200.*</literal>, that would read all 20 metrics and aggregate the results.
|
||||
Alternatively, you could provide a <literal>HandlerInterceptorAdapter</literal> that intercepts and records a metric such as <literal>counter.status.200.all</literal> for all successful requests irrespective of the endpoint, but now you must write 20+1 different metrics.
|
||||
Similarly, if you want to know the total number of successful requests for all endpoints in the service, you could specify a wildcard such as <literal>counter.status.2*.*</literal>.</simpara>
|
||||
<simpara>Even in the presence of wildcarding support on a hierarchical metrics backend, naming consistency can be difficult.
|
||||
Specifically, the position of these tags in the name string can slip with time, breaking queries.
|
||||
For example, suppose we add an additional dimension to the earlier hierarchical metrics for an HTTP method.
|
||||
Then <literal>counter.status.200.root</literal> becomes <literal>counter.status.200.method.get.root</literal> (or <literal>post</literal> and so on).
|
||||
Suddenly, Our <literal>counter.status.200.*</literal> no longer has the same semantic meaning.
|
||||
Furthermore, if the new dimension is not applied uniformly across the codebase, certain queries may become impossible.
|
||||
This can quickly get out of hand.</simpara>
|
||||
<simpara>Netflix metrics are tagged (in other words, they are dimensional).
|
||||
Each metric has a name, but this single named metric can contain multiple statistics and 'tag' key/value pairs, which allows more querying flexibility.
|
||||
In fact, the statistics themselves are recorded in a special tag.</simpara>
|
||||
<simpara>When recorded with Netflix Servo or Spectator, a timer for the root endpoint described earlier contains four statistics for each status code, where the count statistic is identical to Spring Boot Actuator’s counter.
|
||||
When we have encountered an HTTP 200 and 400 with the preceding examples, there are eight available data points, as shown in the following example:</simpara>
|
||||
<programlisting language="json" linenumbering="unnumbered">{
|
||||
"root(status=200,stastic=count)": 20,
|
||||
"root(status=200,stastic=max)": 0.7265630630000001,
|
||||
"root(status=200,stastic=totalOfSquares)": 0.04759702862580789,
|
||||
"root(status=200,stastic=totalTime)": 0.2093076914666667,
|
||||
"root(status=400,stastic=count)": 1,
|
||||
"root(status=400,stastic=max)": 0,
|
||||
"root(status=400,stastic=totalOfSquares)": 0,
|
||||
"root(status=400,stastic=totalTime)": 0,
|
||||
}</programlisting>
|
||||
</section>
|
||||
<section xml:id="_default_metrics_collection">
|
||||
<title>Default Metrics Collection</title>
|
||||
<simpara>Without any additional dependencies or configuration, a Spring Cloud based service autoconfigures a Servo <literal>MonitorRegistry</literal> and begins collecting metrics on every Spring MVC request.
|
||||
By default, a Servo timer with a name of <literal>rest</literal> is recorded for each MVC request, which is tagged with the following information:</simpara>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<simpara>HTTP method (<literal>GET</literal>, <literal>POST</literal>, and so on).</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara>HTTP status (<literal>200</literal>, <literal>400</literal>, <literal>500</literal>, and so on).</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara>URI (or <literal>root</literal> if the URI is empty), sanitized for Atlas.</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara>The exception class name, if the request handler threw an exception.</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara>The caller, if a request header with a key matching <literal>netflix.metrics.rest.callerHeader</literal> is set on the request.
|
||||
There is no default key for <literal>netflix.metrics.rest.callerHeader</literal>.
|
||||
You must add it to your application properties if you wish to collect caller information.</simpara>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<simpara>Set the <literal>netflix.metrics.rest.metricName</literal> property to change the name of the metric from <literal>rest</literal> to the name you provide.</simpara>
|
||||
<simpara>If Spring AOP is enabled and <literal>org.aspectj:aspectjweaver</literal> is present on your runtime classpath, Spring Cloud also collects metrics on every client call made with <literal>RestTemplate</literal>.
|
||||
A Servo timer with a name of <literal>restclient</literal> is recorded for each MVC request, which is tagged with the following information:</simpara>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<simpara>HTTP method ('GET', 'POST', and so on).</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara>HTTP status (<literal>200</literal>, <literal>400</literal>, <literal>500</literal>, and so on) and possibly <literal>CLIENT_ERROR</literal> if the response returned null or <literal>IO_ERROR</literal> if an <literal>IOException</literal> occurred during the execution of the <literal>RestTemplate</literal> method.</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara>URI, sanitized for Atlas.</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara>Client name.</simpara>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<warning>
|
||||
<simpara>Avoid using hard-coded URL parameters within <literal>RestTemplate</literal>.
|
||||
When targeting dynamic endpoints, use URL variables.
|
||||
Doing so avoids potential “GC Overhead Limit Reached” issues where <literal>ServoMonitorCache</literal> treats each URL as a unique key.
|
||||
The following example shows both the recommended and the problematic ways to set URL parameters:</simpara>
|
||||
</warning>
|
||||
<programlisting language="java" linenumbering="unnumbered">// recommended
|
||||
String orderid = "1";
|
||||
restTemplate.getForObject("http://testeurekabrixtonclient/orders/{orderid}", String.class, orderid)
|
||||
|
||||
// avoid
|
||||
restTemplate.getForObject("http://testeurekabrixtonclient/orders/1", String.class)</programlisting>
|
||||
</section>
|
||||
<section xml:id="netflix-metrics-spectator">
|
||||
<title>Metrics Collection: Spectator</title>
|
||||
<simpara>To enable Spectator metrics, include a dependency on <literal>spring-boot-starter-spectator</literal>, as follows:</simpara>
|
||||
<programlisting language="xml" linenumbering="unnumbered"> <dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-netflix-spectator</artifactId>
|
||||
</dependency></programlisting>
|
||||
<simpara>In Spectator parlance, a meter is a named, typed, and tagged configuration, while a metric represents the value of a given meter at a point in time.
|
||||
Spectator meters are created and controlled by a registry, which currently has several different implementations.
|
||||
Spectator provides four meter types: counter, timer, gauge, and distribution summary.</simpara>
|
||||
<simpara>Spring Cloud Spectator integration configures an injectable <literal>com.netflix.spectator.api.Registry</literal> instance for you.
|
||||
Specifically, it configures a <literal>ServoRegistry</literal> instance in order to unify the collection of REST metrics and the exporting of metrics to the Atlas backend under a single Servo API.
|
||||
Practically, this means that your code may use a mixture of Servo monitors and Spectator meters.
|
||||
Spring Boot scoops up both Actuator <literal>MetricReader</literal> instances and ships them to the Atlas backend.</simpara>
|
||||
<section xml:id="_spectator_counter">
|
||||
<title>Spectator Counter</title>
|
||||
<simpara>A counter measures the rate at which some event is occurring, as shown in the following example:</simpara>
|
||||
<programlisting language="java" linenumbering="unnumbered">// create a counter with a name and a set of tags
|
||||
Counter counter = registry.counter("counterName", "tagKey1", "tagValue1", ...);
|
||||
counter.increment(); // increment when an event occurs
|
||||
counter.increment(10); // increment by a discrete amount</programlisting>
|
||||
<simpara>The counter records a single time-normalized statistic.</simpara>
|
||||
</section>
|
||||
<section xml:id="_spectator_timer">
|
||||
<title>Spectator Timer</title>
|
||||
<simpara>A timer measures how long some event takes.
|
||||
Spring Cloud automatically records timers for Spring MVC requests and, conditionally, <literal>RestTemplate</literal> requests, which can later be used to create dashboards for request related metrics like latency, as shown in the following example:</simpara>
|
||||
<figure>
|
||||
<title>Request Latency</title>
|
||||
<mediaobject>
|
||||
<imageobject>
|
||||
<imagedata fileref="https://raw.githubusercontent.com/spring-cloud/spring-cloud-netflix/master/docs/src/main/asciidoc/images/RequestLatency.png"/>
|
||||
</imageobject>
|
||||
<textobject><phrase>RequestLatency</phrase></textobject>
|
||||
</mediaobject>
|
||||
</figure>
|
||||
<programlisting language="java" linenumbering="unnumbered">// create a timer with a name and a set of tags
|
||||
Timer timer = registry.timer("timerName", "tagKey1", "tagValue1", ...);
|
||||
|
||||
// execute an operation and time it at the same time
|
||||
T result = timer.record(() -> fooReturnsT());
|
||||
|
||||
// alternatively, if you must manually record the time
|
||||
Long start = System.nanoTime();
|
||||
T result = fooReturnsT();
|
||||
timer.record(System.nanoTime() - start, TimeUnit.NANOSECONDS);</programlisting>
|
||||
<simpara>The timer simultaneously records four statistics: <literal>count</literal>, <literal>max</literal>, <literal>totalOfSquares</literal>, and <literal>totalTime</literal>.
|
||||
The count statistic always matches the single normalized value provided by a counter as though you had called <literal>increment()</literal> once on the counter for each time you recorded a timing, so it is rarely necessary to count and time separately for a single operation.</simpara>
|
||||
<simpara>For <link xl:href="https://github.com/Netflix/spectator/wiki/Timer-Usage#longtasktimer">long-running operations</link>, Spectator provides a special <literal>LongTaskTimer</literal>.</simpara>
|
||||
</section>
|
||||
<section xml:id="_spectator_gauge">
|
||||
<title>Spectator Gauge</title>
|
||||
<simpara>Gauges show some current value, such as the size of a queue or number of threads in a running state.
|
||||
Since gauges are sampled, they provide no information about how these values fluctuate between samples.</simpara>
|
||||
<simpara>The normal use of a gauge involves registering the gauge once on initialization with an ID, a reference to the object to be sampled, and a function to get or compute a numeric value based on the object.
|
||||
The reference to the object is passed in separately, and the Spectator registry keeps a weak reference to the object.
|
||||
If the object is garbage collected, Spectator automatically drops the registration.
|
||||
See <link xl:href="https://github.com/Netflix/spectator/wiki/Gauge-Usage#using-lambda">the note</link> in Spectator’s documentation about potential memory leaks if this API is misused.
|
||||
The following listing shows how to automatically and manually sample a gauge:</simpara>
|
||||
<programlisting language="java" linenumbering="unnumbered">// the registry automatically samples this gauge periodically
|
||||
registry.gauge("gaugeName", pool, Pool::numberOfRunningThreads);
|
||||
|
||||
// manually sample a value in code at periodic intervals -- last resort!
|
||||
registry.gauge("gaugeName", Arrays.asList("tagKey1", "tagValue1", ...), 1000);</programlisting>
|
||||
</section>
|
||||
<section xml:id="_spectator_distribution_summaries">
|
||||
<title>Spectator Distribution Summaries</title>
|
||||
<simpara>A distribution summary tracks the distribution of events.
|
||||
It is similar to a timer but more general in that the size does not have to be a period of time.
|
||||
For example, a distribution summary could be used to measure the payload sizes of requests hitting a server.
|
||||
The following example defines a distribution summary:</simpara>
|
||||
<programlisting language="java" linenumbering="unnumbered">// the registry automatically samples this gauge periodically
|
||||
DistributionSummary ds = registry.distributionSummary("dsName", "tagKey1", "tagValue1", ...);
|
||||
ds.record(request.sizeInBytes());</programlisting>
|
||||
</section>
|
||||
</section>
|
||||
<section xml:id="netflix-metrics-servo">
|
||||
<title>Metrics Collection: Servo</title>
|
||||
<note>
|
||||
<simpara>If your code is compiled on Java 8, use Spectator instead of Servo, as Spectator is destined to replace Servo entirely.</simpara>
|
||||
</note>
|
||||
<simpara>In Servo parlance, a monitor is a named, typed, and tagged configuration, and a metric represents the value of a given monitor at a point in time.
|
||||
Servo monitors are logically equivalent to Spectator meters.
|
||||
Servo monitors are created and controlled by a <literal>MonitorRegistry</literal>.
|
||||
While it is still available, Servo has a <link xl:href="https://github.com/Netflix/servo/wiki/Getting-Started">wider array</link> of monitor options than Spectator has meters.</simpara>
|
||||
<simpara>Spring Cloud integration configures an injectable <literal>com.netflix.servo.MonitorRegistry</literal> instance for you.
|
||||
Once you have created the appropriate <literal>Monitor</literal> type in Servo, the process of recording data is similar to that of Spectator.</simpara>
|
||||
<section xml:id="_creating_servo_monitors">
|
||||
<title>Creating Servo Monitors</title>
|
||||
<simpara>If you use the Servo <literal>MonitorRegistry</literal> instance provided by Spring Cloud (specifically, an instance of <literal>DefaultMonitorRegistry</literal>), Servo provides convenience classes for retrieving <link xl:href="https://github.com/Netflix/spectator/wiki/Servo-Comparison#dynamiccounter">counters</link> and <link xl:href="https://github.com/Netflix/spectator/wiki/Servo-Comparison#dynamictimer">timers</link>.
|
||||
These convenience classes ensure that only one <literal>Monitor</literal> is registered for each unique combination of name and tags.</simpara>
|
||||
<simpara>To manually create a Monitor type in Servo, especially for the more exotic monitor types for which convenience methods are not provided, instantiate the appropriate type by providing a <literal>MonitorConfig</literal> instance, as shown in the following example:</simpara>
|
||||
<programlisting language="java" linenumbering="unnumbered">MonitorConfig config = MonitorConfig.builder("timerName").withTag("tagKey1", "tagValue1").build();
|
||||
|
||||
// somewhere we should cache this Monitor by MonitorConfig
|
||||
Timer timer = new BasicTimer(config);
|
||||
monitorRegistry.register(timer);</programlisting>
|
||||
</section>
|
||||
</section>
|
||||
</chapter>
|
||||
<chapter xml:id="netflix-metrics-atlas">
|
||||
<title>Metrics Backend: Atlas</title>
|
||||
<simpara>Atlas was developed by Netflix to manage dimensional time-series data for near real-time operational insight.
|
||||
Atlas features in-memory data storage, letting it gather and report large numbers of metrics quickly.</simpara>
|
||||
<simpara>Atlas captures operational intelligence.
|
||||
Whereas business intelligence is data gathered for analyzing trends over time, operational intelligence provides a picture of what is currently happening within a system.</simpara>
|
||||
<simpara>Spring Cloud provides a <literal>spring-cloud-starter-netflix-atlas</literal> that has all the dependencies you need.
|
||||
Then you can annotate your Spring Boot application with <literal>@EnableAtlas</literal> and provide a location for your running Atlas server by setting the <literal>netflix.atlas.uri</literal> property.</simpara>
|
||||
<section xml:id="_global_tags">
|
||||
<title>Global Tags</title>
|
||||
<simpara>Spring Cloud lets you add tags to every metric sent to the Atlas backend.
|
||||
Global tags can be used to separate metrics by application name, environment, region, and so on.</simpara>
|
||||
<simpara>Each bean implementing <literal>AtlasTagProvider</literal> contributes to the global tag list, as shown in the following example:</simpara>
|
||||
<programlisting language="java" linenumbering="unnumbered">@Bean
|
||||
AtlasTagProvider atlasCommonTags(
|
||||
@Value("${spring.application.name}") String appName) {
|
||||
return () -> Collections.singletonMap("app", appName);
|
||||
}</programlisting>
|
||||
<section xml:id="_using_atlas">
|
||||
<title>Using Atlas</title>
|
||||
<simpara>To bootstrap an in-memory standalone Atlas instance, use the following commands:</simpara>
|
||||
<programlisting language="bash" linenumbering="unnumbered">$ curl -LO https://github.com/Netflix/atlas/releases/download/v1.4.2/atlas-1.4.2-standalone.jar
|
||||
$ java -jar atlas-1.4.2-standalone.jar</programlisting>
|
||||
<tip>
|
||||
<simpara>An Atlas standalone node running on an r3.2xlarge (61GB RAM) can handle roughly 2 million metrics per minute for a given six-hour window.</simpara>
|
||||
</tip>
|
||||
<simpara>Once the application is running and you have collected a handful of metrics, you can verify that your setup is correct by listing tags on the Atlas server, as shown in the following example:</simpara>
|
||||
<programlisting language="bash" linenumbering="unnumbered">$ curl http://ATLAS/api/v1/tags</programlisting>
|
||||
<tip>
|
||||
<simpara>After running several requests against your service, you can gather some basic information on the request latency of every request by pasting the following URL in your browser: <literal><link xl:href="http://ATLAS/api/v1/graph?q=name,rest,:eq,:avg">http://ATLAS/api/v1/graph?q=name,rest,:eq,:avg</link></literal></simpara>
|
||||
</tip>
|
||||
<simpara>The Atlas wiki contains a <link xl:href="https://github.com/Netflix/atlas/wiki/Single-Line">compilation of sample queries</link> for various scenarios.</simpara>
|
||||
<simpara>See the <link xl:href="https://github.com/Netflix/atlas/wiki/Alerting-Philosophy">alerting philosophy</link> and docs on using <link xl:href="https://github.com/Netflix/atlas/wiki/DES">double exponential smoothing</link> to generate dynamic alert thresholds.</simpara>
|
||||
</section>
|
||||
</section>
|
||||
</chapter>
|
||||
<chapter xml:id="retrying-failed-requests">
|
||||
<title>Retrying Failed Requests</title>
|
||||
<simpara>Spring Cloud Netflix offers a variety of ways to make HTTP requests.
|
||||
|
||||
Reference in New Issue
Block a user