sequence
This article focuses on the timeout Settings in the ribbon
configuration
The instance
ribbon:
ReadTimeout: 10000
ConnectTimeout: 10000
MaxAutoRetries: 0
MaxAutoRetriesNextServer: 1
eureka:
enabled: true
Copy the code
RibbonClientConfiguration
Spring – the cloud – netflix – ribbon – 2.0.0. RELEASE – sources. The jar! /org/springframework/cloud/netflix/ribbon/RibbonClientConfiguration.java
@SuppressWarnings("deprecation")
@Configuration
@EnableConfigurationProperties
//Order is important here, last should be the default, first should be optional
// see https://github.com/spring-cloud/spring-cloud-netflix/issues/2086#issuecomment-316281653
@Import({HttpClientConfiguration.class, OkHttpRibbonConfiguration.class, RestClientRibbonConfiguration.class, HttpClientRibbonConfiguration.class})
public class RibbonClientConfiguration {
public static final int DEFAULT_CONNECT_TIMEOUT = 1000;
public static final int DEFAULT_READ_TIMEOUT = 1000;
@RibbonClientName
private String name = "client";
// TODO: maybe re-instate autowired load balancers: identified by name they could be
// associated with ribbon clients
@Autowired
private PropertiesFactory propertiesFactory;
@Bean
@ConditionalOnMissingBean
public IClientConfig ribbonClientConfig() {
DefaultClientConfigImpl config = new DefaultClientConfigImpl();
config.loadProperties(this.name);
config.set(CommonClientConfigKey.ConnectTimeout, DEFAULT_CONNECT_TIMEOUT);
config.set(CommonClientConfigKey.ReadTimeout, DEFAULT_READ_TIMEOUT);
returnconfig; } / /... }Copy the code
- The default timeout value is set here, both 1000 ms, in DefaultClientConfigImpl
AbstractLoadBalancingClient
Spring – the cloud – netflix – ribbon – 2.0.0. RELEASE – sources. The jar! /org/springframework/cloud/netflix/ribbon/support/AbstractLoadBalancingClient.java
public abstract class AbstractLoadBalancingClient<S extends ContextAwareRequest, T extends IResponse, D> extends
AbstractLoadBalancerAwareClient<S, T> implements ServiceInstanceChooser {
protected int connectTimeout;
protected int readTimeout; / /... @Override public void initWithNiwsConfig(IClientConfig clientConfig) { super.initWithNiwsConfig(clientConfig); RibbonProperties ribbon = RibbonProperties.from(clientConfig); this.connectTimeout = ribbon.connectTimeout(DEFAULT_CONNECT_TIMEOUT); this.readTimeout = ribbon.readTimeout(DEFAULT_READ_TIMEOUT); this.secure = ribbon.isSecure(); this.followRedirects = ribbon.isFollowRedirects(); this.okToRetryOnAllOperations = ribbon.isOkToRetryOnAllOperations(); } / /... }Copy the code
- Here, the timeout parameters are read from RibbonProperties and placed in the class member variables connectTimeout and readTimeout
- RibbonProperties is finally retrieved from IClientConfig
RibbonLoadBalancingHttpClient
Spring – the cloud – netflix – ribbon – 2.0.0. RELEASE – sources. The jar! /org/springframework/cloud/netflix/ribbon/apache/RibbonLoadBalancingHttpClient.java
// TODO: rename (ie new class that extends this inDalston) to ApacheHttpLoadBalancingClient public class RibbonLoadBalancingHttpClient extends AbstractLoadBalancingClient<RibbonApacheHttpRequest, RibbonApacheHttpResponse, CloseableHttpClient> { //...... @Override public RibbonApacheHttpResponse execute(RibbonApacheHttpRequest request, final IClientConfig configOverride) throws Exception { IClientConfig config = configOverride ! = null ? configOverride : this.config; RibbonProperties ribbon = RibbonProperties.from(config); RequestConfig requestConfig = RequestConfig.custom() .setConnectTimeout(ribbon.connectTimeout(this.connectTimeout)) .setSocketTimeout(ribbon.readTimeout(this.readTimeout)) .setRedirectsEnabled(ribbon.isFollowRedirects(this.followRedirects)) .build(); request = getSecureRequest(request, configOverride); final HttpUriRequest httpUriRequest = request.toRequest(requestConfig); final HttpResponse httpResponse = this.delegate.execute(httpUriRequest);returnnew RibbonApacheHttpResponse(httpResponse, httpUriRequest.getURI()); } / /... }Copy the code
- The execute method constructs RequestConfig from IClientConfig, setting connectTimeout and socketTimeout
- If configOverride is null, the default configuration of the abstract class is used
OkHttpLoadBalancingClient
Spring – the cloud – netflix – ribbon – 2.0.0. RELEASE – sources. The jar! /org/springframework/cloud/netflix/ribbon/okhttp/OkHttpLoadBalancingClient.java
public class OkHttpLoadBalancingClient
extends AbstractLoadBalancingClient<OkHttpRibbonRequest, OkHttpRibbonResponse, OkHttpClient> {
//......
@Override
public OkHttpRibbonResponse execute(OkHttpRibbonRequest ribbonRequest,
final IClientConfig configOverride) throws Exception {
boolean secure = isSecure(configOverride);
if (secure) {
final URI secureUri = UriComponentsBuilder.fromUri(ribbonRequest.getUri())
.scheme("https").build().toUri();
ribbonRequest = ribbonRequest.withNewUri(secureUri);
}
OkHttpClient httpClient = getOkHttpClient(configOverride, secure);
final Request request = ribbonRequest.toRequest();
Response response = httpClient.newCall(request).execute();
returnnew OkHttpRibbonResponse(response, ribbonRequest.getUri()); } OkHttpClient getOkHttpClient(IClientConfig configOverride, boolean secure) { IClientConfig config = configOverride ! = null ? configOverride : this.config; RibbonProperties ribbon = RibbonProperties.from(config); OkHttpClient.Builder builder = this.delegate.newBuilder() .connectTimeout(ribbon.connectTimeout(this.connectTimeout), TimeUnit.MILLISECONDS) .readTimeout(ribbon.readTimeout(this.readTimeout), TimeUnit.MILLISECONDS) .followRedirects(ribbon.isFollowRedirects(this.followRedirects));if (secure) {
builder.followSslRedirects(ribbon.isFollowRedirects(this.followRedirects));
}
returnbuilder.build(); } / /... }Copy the code
- Here the OkHttpClient with the specified timeout parameter is built using configOverride or the default config
- OkHttpClient uses request config to set the timeout. This may cause a problem. OkHttpClient can’t use singletons
ClientConfig pass
RibbonHttpRequest
Spring – the cloud – netflix – ribbon – 2.0.0. RELEASE – sources. The jar! /org/springframework/cloud/netflix/ribbon/RibbonHttpRequest.java
public class RibbonHttpRequest extends AbstractClientHttpRequest {
//......
@Override
protected ClientHttpResponse executeInternal(HttpHeaders headers)
throws IOException {
try {
addHeaders(headers);
if(outputStream ! = null) { outputStream.close(); builder.entity(outputStream.toByteArray()); } HttpRequest request = builder.build(); HttpResponse response = client.executeWithLoadBalancer(request, config);returnnew RibbonHttpResponse(response); } catch (Exception e) { throw new IOException(e); }} / /... }Copy the code
- Client here. ExecuteWithLoadBalancer (request, the config) using the RibbonHttpRequest config configuration
RibbonClientHttpRequestFactory
Spring – the cloud – netflix – ribbon – 2.0.0. RELEASE – sources. The jar! /org/springframework/cloud/netflix/ribbon/RibbonClientHttpRequestFactory.java
public class RibbonClientHttpRequestFactory implements ClientHttpRequestFactory {
private final SpringClientFactory clientFactory;
public RibbonClientHttpRequestFactory(SpringClientFactory clientFactory) {
this.clientFactory = clientFactory;
}
@Override
@SuppressWarnings("deprecation")
public ClientHttpRequest createRequest(URI originalUri, HttpMethod httpMethod)
throws IOException {
String serviceId = originalUri.getHost();
if (serviceId == null) {
throw new IOException(
"Invalid hostname in the URI [" + originalUri.toASCIIString() + "]");
}
IClientConfig clientConfig = this.clientFactory.getClientConfig(serviceId);
RestClient client = this.clientFactory.getClient(serviceId, RestClient.class);
HttpRequest.Verb verb = HttpRequest.Verb.valueOf(httpMethod.name());
returnnew RibbonHttpRequest(originalUri, verb, client, clientConfig); }}Copy the code
- ClientHttpRequest is created by RibbonClientHttpRequestFactory this factory
- ClientConfig is RibbonClientHttpRequestFactory according to serviceId access, the factory default is DefaultClientConfigImpl, read from a configuration file, ServiceId’s own personalization parameters overwrite the default values. The default parameters cannot be read.
summary
The Ribbon of Spring Cloud and Netflix has ReadTimeout and ConnectTimeout configured, socketTimeout and ConnectTimeout respectively. When creating a request, the ribbon will read the specified configuration. If not, use the default Settings and set the timeout.
doc
- Client Side Load Balancing with Ribbon and Spring Cloud