


Detailed explanation of the Ribbon integrated by RestTemplate of springcloud components
This article talks about how springcloud integrates ribbon. Different springcloud components (feign, zuul, RestTemplate) integrate ribbon differently. This article first takes a look at RestTemplate.
The class diagram of RestTemplate is as follows
##HttpAccessor
is mainly created based on
ClientHttpRequestFactory##ClientHttpRequest
##InterceptingHttpAccessor- extends
HttpAccessor
Interceptorto create an intercepted
InterceptingClientHttpRequest, where the interception will be set Device
ClientHttpRequestInterceptor, which is the core of the integrated ribbon. When
RestTemplateinitiates an http request call, it will first go through the interceptor and then actually initiate the http request.
ClientHttpRequestInterceptor
LoadBalancerAutoConfiguration class, there is the following code:
@LoadBalanced @Autowired(required = false) private List<RestTemplate> restTemplates = Collections.emptyList();
As long as the annotation
@LoadBalanced is added, the RestTemplate will be injected. If spring retry is not introduced, When loading the component, load the following configuration:
@Configuration @ConditionalOnMissingClass("org.springframework.retry.support.RetryTemplate") static class LoadBalancerInterceptorConfig { @Bean public LoadBalancerInterceptor ribbonInterceptor( LoadBalancerClient loadBalancerClient, LoadBalancerRequestFactory requestFactory) { return new LoadBalancerInterceptor(loadBalancerClient, requestFactory); } @Bean @ConditionalOnMissingBean public RestTemplateCustomizer restTemplateCustomizer( final LoadBalancerInterceptor loadBalancerInterceptor) { return new RestTemplateCustomizer() { @Override public void customize(RestTemplate restTemplate) { List<ClientHttpRequestInterceptor> list = new ArrayList<>( restTemplate.getInterceptors()); list.add(loadBalancerInterceptor); restTemplate.setInterceptors(list); } }; } }
In this way,
RestTemplate is set to LoadBalancerInterceptor. Let’s take a look at the entire calling processThe whole process is a bit complicated. The core is to initiate a load balancing call through the interceptor LoadBalancerInterceptor and RibbonLoadBalancerClient. RibbonLoadBalancerClientI combines LoadBalancer, so it has the ability to load balance, which is the ribbon principle we explained in the previous article.
SimpleClientHttpRequestFactory
. The class diagram ofClientHttpRequestFactory is as follows:
##We can see from the calling sequence diagram that at first we called InterceptingClientHttpRequestFactory to obtain
, which are combined The method integrates ClientHttpRequestFactory
and the interceptor. When InterceptingClientHttpRequest
initiates the call, it delegates its internal class InterceptingRequestExecution
to handle it. The core logic is: <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>@Override
public ClientHttpResponse execute(HttpRequest request, byte[] body) throws IOException {
if (this.iterator.hasNext()) {
ClientHttpRequestInterceptor nextInterceptor = this.iterator.next();
return nextInterceptor.intercept(request, body, this);
}else {
ClientHttpRequest delegate = requestFactory.createRequest(request.getURI(), request.getMethod());
for (Map.Entry<String, List<String>> entry : request.getHeaders().entrySet()) {
List<String> values = entry.getValue();
for (String value : values) {
delegate.getHeaders().add(entry.getKey(), value);
}
}
if (body.length > 0) {
StreamUtils.copy(body, delegate.getBody());
}
return delegate.execute();
}
}</pre><div class="contentsignin">Copy after login</div></div>
First, the first execution of the interceptor collection will be taken out. When the execution of the interceptor is completed, it will be called back, execute the else code, and actually initiate the http request. There are two main ways to implement the ClientHttpRequestFactory
interface:
One is
- , which uses the method provided by J2SE (the method provided by the java.net package) to create the underlying Http request connection
HttpComponentsClientHttpRequestFactoryOne way is to use the
method. The bottom layer uses HttpClient to access the remote Http service. You can use HttpClient to configure the connection pool, certificate and other information. RestTemplate defaults to using SimpleClientHttpRequestFactory, which internally calls HttpConnection of jdk. The default timeout is -1. You can set the timeout like this:
@Bean @LoadBalanced public RestTemplate restTemplate() { SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); factory.setConnectTimeout(1000 * 2);//连接超时时间 factory.setReadTimeout(1000 * 1);//读超时时间 return new RestTemplate(factory); }
Copy after loginUse
You can use a connection pool (recommended), and you can also set a retry strategy (not studied specifically)
If you want to enable the retry mechanism, we can introduce spring's retry component<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'><dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
<version>版本号</version>
</dependency></pre><div class="contentsignin">Copy after login</div></div>
In this way, springcloud-ribbon will add the following configuration:
@Configuration @ConditionalOnClass(RetryTemplate.class) public static class RetryAutoConfiguration { @Bean public RetryTemplate retryTemplate() { RetryTemplate template = new RetryTemplate(); template.setThrowLastExceptionOnExhausted(true); return template; } @Bean @ConditionalOnMissingBean public LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory() { return new LoadBalancedRetryPolicyFactory.NeverRetryFactory(); } } @Configuration @ConditionalOnClass(RetryTemplate.class) public static class RetryInterceptorAutoConfiguration { @Bean @ConditionalOnMissingBean public RetryLoadBalancerInterceptor ribbonInterceptor( LoadBalancerClient loadBalancerClient, LoadBalancerRetryProperties properties, LoadBalancedRetryPolicyFactory lbRetryPolicyFactory, LoadBalancerRequestFactory requestFactory) { return new RetryLoadBalancerInterceptor(loadBalancerClient, properties, lbRetryPolicyFactory, requestFactory); } @Bean @ConditionalOnMissingBean public RestTemplateCustomizer restTemplateCustomizer( final RetryLoadBalancerInterceptor loadBalancerInterceptor) { return new RestTemplateCustomizer() { @Override public void customize(RestTemplate restTemplate) { List<ClientHttpRequestInterceptor> list = new ArrayList<>( restTemplate.getInterceptors()); list.add(loadBalancerInterceptor); restTemplate.setInterceptors(list); } }; } }
@Bean @ConditionalOnClass(name = "org.springframework.retry.support.RetryTemplate") @ConditionalOnMissingBean public LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory(SpringClientFactory clientFactory) { return new RibbonLoadBalancedRetryPolicyFactory(clientFactory); }
The interceptor is replaced with
RetryLoadBalancerInterceptor, where the retry component retryTemplate is integrated. The retry strategy is configured by the
RetryHandler interface. The default implementation class is DefaultLoadBalancerRetryHandler
. The following are the default configuration parameters <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>#最大的重试次数
ribbon.MaxAutoRetries=0
#最大重试server的个数
ribbon.MaxAutoRetriesNextServer=1
#是否开启任何异常都重试(默认在get请求下会重试,其他情况不会重试,除非设置为true)
ribbon.OkToRetryOnAllOperations=false
#指定重试的http状态码
ribbon.retryableStatusCodes=500,501</pre><div class="contentsignin">Copy after login</div></div>. The above is globally effective. If ## is added #xxx.ribbon.MaxAutoRetries=1<code>This will only take effect on a certain ribbon client. MaxAutoRetries and MaxAutoRetriesNextServer are used together. The maximum number of retries is for each server. If MaxAutoRetries=1 and MaxAutoRetriesNextServer=1 are set, the maximum number of retries triggered is 4 times.
The above is the detailed content of Detailed explanation of the Ribbon integrated by RestTemplate of springcloud components. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics



Guide to Square Root in Java. Here we discuss how Square Root works in Java with example and its code implementation respectively.

Guide to Perfect Number in Java. Here we discuss the Definition, How to check Perfect number in Java?, examples with code implementation.

Guide to Random Number Generator in Java. Here we discuss Functions in Java with examples and two different Generators with ther examples.

Guide to the Armstrong Number in Java. Here we discuss an introduction to Armstrong's number in java along with some of the code.

Guide to Weka in Java. Here we discuss the Introduction, how to use weka java, the type of platform, and advantages with examples.

Guide to Smith Number in Java. Here we discuss the Definition, How to check smith number in Java? example with code implementation.

In this article, we have kept the most asked Java Spring Interview Questions with their detailed answers. So that you can crack the interview.

Java 8 introduces the Stream API, providing a powerful and expressive way to process data collections. However, a common question when using Stream is: How to break or return from a forEach operation? Traditional loops allow for early interruption or return, but Stream's forEach method does not directly support this method. This article will explain the reasons and explore alternative methods for implementing premature termination in Stream processing systems. Further reading: Java Stream API improvements Understand Stream forEach The forEach method is a terminal operation that performs one operation on each element in the Stream. Its design intention is
