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