feat: Adds RestTemplate default ConnectTimeout / ConnectRequestTimeout (#4148)
This commit is contained in:
@@ -112,6 +112,19 @@ NOTE: Because of a limitation in Eureka, it is not possible to support per-serve
|
||||
|
||||
If you want to customize the RestTemplate used by the Eureka HTTP Client you may want to create a bean of `EurekaClientHttpRequestFactorySupplier` and provide your own logic for generating a `ClientHttpRequestFactory` instance.
|
||||
|
||||
All default timeout-related properties for RestTemplate used by the Eureka HTTP Client are set to infinite. Therefore, to specify the timeout values, you must specify the value directly with the properties in `eureka.client.rest-template-timeout`. (All timeout properties are in milliseconds.)
|
||||
|
||||
.application.yml
|
||||
[source,yaml]
|
||||
----
|
||||
eureka:
|
||||
client:
|
||||
rest-template-timeout:
|
||||
connect-timeout: 5000
|
||||
connect-request-timeout: 8000
|
||||
socket-timeout: 10000
|
||||
----
|
||||
|
||||
=== Status Page and Health Indicator
|
||||
|
||||
The status page and health indicators for a Eureka instance default to `/info` and `/health` respectively, which are the default locations of useful endpoints in a Spring Boot Actuator application.
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright 2013-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.eureka;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.cloud.netflix.eureka.http.RestTemplateEurekaHttpClient;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
/**
|
||||
* Properties for configuring timeouts used in {@link RestTemplate} required by
|
||||
* {@link RestTemplateEurekaHttpClient}.
|
||||
*
|
||||
* @author Jiwon Jeon
|
||||
* @since 4.0.0
|
||||
*/
|
||||
@ConfigurationProperties("eureka.client.rest-template-timeout")
|
||||
public class RestTemplateTimeoutProperties {
|
||||
|
||||
/**
|
||||
* Default values are set to -1 according to {@link RequestConfig .DEFAULT}.
|
||||
*/
|
||||
private int connectTimeout = -1;
|
||||
|
||||
private int connectRequestTimeout = -1;
|
||||
|
||||
private int socketTimeout = -1;
|
||||
|
||||
public int getConnectTimeout() {
|
||||
return connectTimeout;
|
||||
}
|
||||
|
||||
public int getConnectRequestTimeout() {
|
||||
return connectRequestTimeout;
|
||||
}
|
||||
|
||||
public int getSocketTimeout() {
|
||||
return socketTimeout;
|
||||
}
|
||||
|
||||
public void setConnectTimeout(int connectTimeout) {
|
||||
this.connectTimeout = connectTimeout;
|
||||
}
|
||||
|
||||
public void setConnectRequestTimeout(int connectRequestTimeout) {
|
||||
this.connectRequestTimeout = connectRequestTimeout;
|
||||
}
|
||||
|
||||
public void setSocketTimeout(int socketTimeout) {
|
||||
this.socketTimeout = socketTimeout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
RestTemplateTimeoutProperties that = (RestTemplateTimeoutProperties) o;
|
||||
|
||||
return connectTimeout == that.connectTimeout && connectRequestTimeout == that.connectRequestTimeout
|
||||
&& socketTimeout == that.socketTimeout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(connectTimeout, connectRequestTimeout, socketTimeout);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "RestTemplateTimeoutProperties{" + ", connectTimeout=" + connectTimeout + ", connectRequestTimeout="
|
||||
+ connectRequestTimeout + ", socketTimeout=" + socketTimeout + '}';
|
||||
}
|
||||
|
||||
}
|
||||
@@ -31,9 +31,11 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClas
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.autoconfigure.condition.SearchStrategy;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.cloud.configuration.SSLContextFactory;
|
||||
import org.springframework.cloud.configuration.TlsProperties;
|
||||
import org.springframework.cloud.netflix.eureka.MutableDiscoveryClientOptionalArgs;
|
||||
import org.springframework.cloud.netflix.eureka.RestTemplateTimeoutProperties;
|
||||
import org.springframework.cloud.netflix.eureka.http.DefaultEurekaClientHttpRequestFactorySupplier;
|
||||
import org.springframework.cloud.netflix.eureka.http.EurekaClientHttpRequestFactorySupplier;
|
||||
import org.springframework.cloud.netflix.eureka.http.RestTemplateDiscoveryClientOptionalArgs;
|
||||
@@ -46,6 +48,7 @@ import org.springframework.web.reactive.function.client.WebClient;
|
||||
* @author Daniel Lavoie
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@EnableConfigurationProperties(RestTemplateTimeoutProperties.class)
|
||||
public class DiscoveryClientOptionalArgsConfiguration {
|
||||
|
||||
protected static final Log logger = LogFactory.getLog(DiscoveryClientOptionalArgsConfiguration.class);
|
||||
@@ -75,8 +78,9 @@ public class DiscoveryClientOptionalArgsConfiguration {
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnClass(name = "org.springframework.web.client.RestTemplate")
|
||||
EurekaClientHttpRequestFactorySupplier defaultEurekaClientHttpRequestFactorySupplier() {
|
||||
return new DefaultEurekaClientHttpRequestFactorySupplier();
|
||||
EurekaClientHttpRequestFactorySupplier defaultEurekaClientHttpRequestFactorySupplier(
|
||||
RestTemplateTimeoutProperties restTemplateTimeoutProperties) {
|
||||
return new DefaultEurekaClientHttpRequestFactorySupplier(restTemplateTimeoutProperties);
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -19,10 +19,12 @@ package org.springframework.cloud.netflix.eureka.http;
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.SSLContext;
|
||||
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
|
||||
import org.springframework.cloud.netflix.eureka.RestTemplateTimeoutProperties;
|
||||
import org.springframework.http.client.ClientHttpRequestFactory;
|
||||
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
|
||||
import org.springframework.lang.Nullable;
|
||||
@@ -36,6 +38,16 @@ import org.springframework.lang.Nullable;
|
||||
*/
|
||||
public class DefaultEurekaClientHttpRequestFactorySupplier implements EurekaClientHttpRequestFactorySupplier {
|
||||
|
||||
private final RestTemplateTimeoutProperties restTemplateTimeoutProperties;
|
||||
|
||||
public DefaultEurekaClientHttpRequestFactorySupplier() {
|
||||
this.restTemplateTimeoutProperties = new RestTemplateTimeoutProperties();
|
||||
}
|
||||
|
||||
public DefaultEurekaClientHttpRequestFactorySupplier(RestTemplateTimeoutProperties restTemplateTimeoutProperties) {
|
||||
this.restTemplateTimeoutProperties = restTemplateTimeoutProperties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClientHttpRequestFactory get(SSLContext sslContext, @Nullable HostnameVerifier hostnameVerifier) {
|
||||
HttpClientBuilder httpClientBuilder = HttpClients.custom();
|
||||
@@ -45,10 +57,20 @@ public class DefaultEurekaClientHttpRequestFactorySupplier implements EurekaClie
|
||||
if (hostnameVerifier != null) {
|
||||
httpClientBuilder = httpClientBuilder.setSSLHostnameVerifier(hostnameVerifier);
|
||||
}
|
||||
if (restTemplateTimeoutProperties != null) {
|
||||
httpClientBuilder.setDefaultRequestConfig(buildRequestConfig());
|
||||
}
|
||||
|
||||
CloseableHttpClient httpClient = httpClientBuilder.build();
|
||||
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
|
||||
requestFactory.setHttpClient(httpClient);
|
||||
return requestFactory;
|
||||
}
|
||||
|
||||
private RequestConfig buildRequestConfig() {
|
||||
return RequestConfig.custom().setConnectTimeout(restTemplateTimeoutProperties.getConnectTimeout())
|
||||
.setConnectionRequestTimeout(restTemplateTimeoutProperties.getConnectRequestTimeout())
|
||||
.setSocketTimeout(restTemplateTimeoutProperties.getSocketTimeout()).build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user