前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >聊聊ribbon的超时时间设置

聊聊ribbon的超时时间设置

作者头像
code4it
发布2018-09-17 17:08:05
3.9K0
发布2018-09-17 17:08:05
举报
文章被收录于专栏:码匠的流水账码匠的流水账

本文主要研究一下ribbon的超时时间设置

配置

实例

代码语言:javascript
复制
ribbon:
  ReadTimeout: 10000
  ConnectTimeout: 10000
  MaxAutoRetries: 0
  MaxAutoRetriesNextServer: 1
  eureka:
    enabled: true

RibbonClientConfiguration

spring-cloud-netflix-ribbon-2.0.0.RELEASE-sources.jar!/org/springframework/cloud/netflix/ribbon/RibbonClientConfiguration.java

代码语言:javascript
复制
@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);
        return config;
    }

    //......
}
  • 这里设置默认的超时值,都是1000毫秒,设置在DefaultClientConfigImpl

AbstractLoadBalancingClient

spring-cloud-netflix-ribbon-2.0.0.RELEASE-sources.jar!/org/springframework/cloud/netflix/ribbon/support/AbstractLoadBalancingClient.java

代码语言:javascript
复制
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();
    }

    //......
}
  • 这里从RibbonProperties读取超时参数,然后放到类成员变量connectTimeout及readTimeout
  • RibbonProperties就最后是从IClientConfig读取

RibbonLoadBalancingHttpClient

spring-cloud-netflix-ribbon-2.0.0.RELEASE-sources.jar!/org/springframework/cloud/netflix/ribbon/apache/RibbonLoadBalancingHttpClient.java

代码语言:javascript
复制
// TODO: rename (ie new class that extends this in Dalston) 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);
        return new RibbonApacheHttpResponse(httpResponse, httpUriRequest.getURI());
    }

    //......
}
  • 这里execute方法从IClientConfig构造RequestConfig,会设置connectTimeout及socketTimeout
  • 如果configOverride为null,则使用抽象类的默认配置

OkHttpLoadBalancingClient

spring-cloud-netflix-ribbon-2.0.0.RELEASE-sources.jar!/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpLoadBalancingClient.java

代码语言:javascript
复制
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();
        return new 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));
        }

        return builder.build();
    }

    //......
}
  • 这里是通过configOverride或默认的config来构建指定超时参数的OkHttpClient
  • 相比较于apache httpclient通过request config来设置超时时间,OkHttpClient是通过client来设置的,这样可能存在一个问题,就是OkHttpClient没法用单例,每次都得new一个

clientConfig传递

RibbonHttpRequest

spring-cloud-netflix-ribbon-2.0.0.RELEASE-sources.jar!/org/springframework/cloud/netflix/ribbon/RibbonHttpRequest.java

代码语言:javascript
复制
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);
            return new RibbonHttpResponse(response);
        } catch (Exception e) {
            throw new IOException(e);
        }
    }

    //......
}
  • 这里client.executeWithLoadBalancer(request, config)使用的是RibbonHttpRequest的config配置

RibbonClientHttpRequestFactory

spring-cloud-netflix-ribbon-2.0.0.RELEASE-sources.jar!/org/springframework/cloud/netflix/ribbon/RibbonClientHttpRequestFactory.java

代码语言:javascript
复制
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());

        return new RibbonHttpRequest(originalUri, verb, client, clientConfig);
    }

}
  • ClientHttpRequest是通过RibbonClientHttpRequestFactory这个工厂创建的
  • clientConfig是RibbonClientHttpRequestFactory这个工厂根据serviceId获取的,默认是DefaultClientConfigImpl,从配置文件读取,serviceId自己的个性化配置参数会覆盖默认值,读取不到的就是默认的参数。

小结

spring cloud netflix的ribbon,其超时时间配置有ReadTimeout以及ConnectTimeout,分别是设置的socketTimeout以及connectTimeout,创建请求的时候,会读取指定配置,没有的话,就取默认的配置,设置超时时间。

doc

  • Client Side Load Balancing with Ribbon and Spring Cloud
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-07-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码匠的流水账 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 配置
    • 实例
      • RibbonClientConfiguration
      • AbstractLoadBalancingClient
      • RibbonLoadBalancingHttpClient
      • OkHttpLoadBalancingClient
      • clientConfig传递
        • RibbonHttpRequest
          • RibbonClientHttpRequestFactory
          • 小结
          • doc
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档