前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >聊聊spring cloud的FeignLoadBalancer

聊聊spring cloud的FeignLoadBalancer

原创
作者头像
code4it
修改2019-07-12 10:04:14
1.2K0
修改2019-07-12 10:04:14
举报
文章被收录于专栏:码匠的流水账码匠的流水账

本文主要研究一下spring cloud的FeignLoadBalancer

FeignLoadBalancer

spring-cloud-openfeign-core-2.2.0.M1-sources.jar!/org/springframework/cloud/openfeign/ribbon/FeignLoadBalancer.java

代码语言:javascript
复制
public class FeignLoadBalancer extends
        AbstractLoadBalancerAwareClient<FeignLoadBalancer.RibbonRequest, FeignLoadBalancer.RibbonResponse> {
​
    private final RibbonProperties ribbon;
​
    protected int connectTimeout;
​
    protected int readTimeout;
​
    protected IClientConfig clientConfig;
​
    protected ServerIntrospector serverIntrospector;
​
    public FeignLoadBalancer(ILoadBalancer lb, IClientConfig clientConfig,
            ServerIntrospector serverIntrospector) {
        super(lb, clientConfig);
        this.setRetryHandler(RetryHandler.DEFAULT);
        this.clientConfig = clientConfig;
        this.ribbon = RibbonProperties.from(clientConfig);
        RibbonProperties ribbon = this.ribbon;
        this.connectTimeout = ribbon.getConnectTimeout();
        this.readTimeout = ribbon.getReadTimeout();
        this.serverIntrospector = serverIntrospector;
    }
​
    @Override
    public RibbonResponse execute(RibbonRequest request, IClientConfig configOverride)
            throws IOException {
        Request.Options options;
        if (configOverride != null) {
            RibbonProperties override = RibbonProperties.from(configOverride);
            options = new Request.Options(override.connectTimeout(this.connectTimeout),
                    override.readTimeout(this.readTimeout));
        }
        else {
            options = new Request.Options(this.connectTimeout, this.readTimeout);
        }
        Response response = request.client().execute(request.toRequest(), options);
        return new RibbonResponse(request.getUri(), response);
    }
​
    @Override
    public RequestSpecificRetryHandler getRequestSpecificRetryHandler(
            RibbonRequest request, IClientConfig requestConfig) {
        if (this.ribbon.isOkToRetryOnAllOperations()) {
            return new RequestSpecificRetryHandler(true, true, this.getRetryHandler(),
                    requestConfig);
        }
        if (!request.toRequest().httpMethod().name().equals("GET")) {
            return new RequestSpecificRetryHandler(true, false, this.getRetryHandler(),
                    requestConfig);
        }
        else {
            return new RequestSpecificRetryHandler(true, true, this.getRetryHandler(),
                    requestConfig);
        }
    }
​
    @Override
    public URI reconstructURIWithServer(Server server, URI original) {
        URI uri = updateToSecureConnectionIfNeeded(original, this.clientConfig,
                this.serverIntrospector, server);
        return super.reconstructURIWithServer(server, uri);
    }
​
    //......
}
  • FeignLoadBalancer继承了AbstractLoadBalancerAwareClient,它的构造器接收ILoadBalancer、IClientConfig、ServerIntrospector,设置的retryHandler为RetryHandler.DEFAULT
  • 其execute方法首先构造Request.Options,然后通过request.client().execute来获取Response,最后返回RibbonResponse
  • FeignLoadBalancer还覆盖了getRequestSpecificRetryHandler方法,针对ribbon.isOkToRetryOnAllOperations()来构建不同的RequestSpecificRetryHandler;还覆盖了reconstructURIWithServer方法,它使用RibbonUtils的updateToSecureConnectionIfNeeded来构建URI

RibbonRequest

spring-cloud-openfeign-core-2.2.0.M1-sources.jar!/org/springframework/cloud/openfeign/ribbon/FeignLoadBalancer.java

代码语言:javascript
复制
    protected static class RibbonRequest extends ClientRequest implements Cloneable {
​
        private final Request request;
​
        private final Client client;
​
        protected RibbonRequest(Client client, Request request, URI uri) {
            this.client = client;
            setUri(uri);
            this.request = toRequest(request);
        }
​
        private Request toRequest(Request request) {
            Map<String, Collection<String>> headers = new LinkedHashMap<>(
                    request.headers());
            return Request.create(request.httpMethod(), getUri().toASCIIString(), headers,
                    request.requestBody());
        }
​
        Request toRequest() {
            return toRequest(this.request);
        }
​
        Client client() {
            return this.client;
        }
​
        HttpRequest toHttpRequest() {
            return new HttpRequest() {
                @Override
                public HttpMethod getMethod() {
                    return HttpMethod
                            .resolve(RibbonRequest.this.toRequest().httpMethod().name());
                }
​
                @Override
                public String getMethodValue() {
                    return getMethod().name();
                }
​
                @Override
                public URI getURI() {
                    return RibbonRequest.this.getUri();
                }
​
                @Override
                public HttpHeaders getHeaders() {
                    Map<String, List<String>> headers = new HashMap<>();
                    Map<String, Collection<String>> feignHeaders = RibbonRequest.this
                            .toRequest().headers();
                    for (String key : feignHeaders.keySet()) {
                        headers.put(key, new ArrayList<String>(feignHeaders.get(key)));
                    }
                    HttpHeaders httpHeaders = new HttpHeaders();
                    httpHeaders.putAll(headers);
                    return httpHeaders;
​
                }
            };
        }
​
        public Request getRequest() {
            return this.request;
        }
​
        public Client getClient() {
            return this.client;
        }
​
        @Override
        public Object clone() {
            return new RibbonRequest(this.client, this.request, getUri());
        }
​
    }
  • RibbonRequest继承了ClientRequest实现了Cloneable接口,它提供了toHttpRequest方法来将feign的Request转换为spring的HttpRequest

RibbonResponse

spring-cloud-openfeign-core-2.2.0.M1-sources.jar!/org/springframework/cloud/openfeign/ribbon/FeignLoadBalancer.java

代码语言:javascript
复制
    protected static class RibbonResponse implements IResponse {
​
        private final URI uri;
​
        private final Response response;
​
        protected RibbonResponse(URI uri, Response response) {
            this.uri = uri;
            this.response = response;
        }
​
        @Override
        public Object getPayload() throws ClientException {
            return this.response.body();
        }
​
        @Override
        public boolean hasPayload() {
            return this.response.body() != null;
        }
​
        @Override
        public boolean isSuccess() {
            return this.response.status() == 200;
        }
​
        @Override
        public URI getRequestedURI() {
            return this.uri;
        }
​
        @Override
        public Map<String, Collection<String>> getHeaders() {
            return this.response.headers();
        }
​
        Response toResponse() {
            return this.response;
        }
​
        @Override
        public void close() throws IOException {
            if (this.response != null && this.response.body() != null) {
                this.response.body().close();
            }
        }
​
    }
  • RibbonResponse实现了IResponse接口,将feign的Response适配为netflix的IResponse

小结

  • FeignLoadBalancer继承了AbstractLoadBalancerAwareClient,它的构造器接收ILoadBalancer、IClientConfig、ServerIntrospector,设置的retryHandler为RetryHandler.DEFAULT
  • 其execute方法首先构造Request.Options,然后通过request.client().execute来获取Response,最后返回RibbonResponse
  • FeignLoadBalancer还覆盖了getRequestSpecificRetryHandler方法,针对ribbon.isOkToRetryOnAllOperations()来构建不同的RequestSpecificRetryHandler;还覆盖了reconstructURIWithServer方法,它使用RibbonUtils的updateToSecureConnectionIfNeeded来构建URI

doc

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

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

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • FeignLoadBalancer
  • RibbonRequest
  • RibbonResponse
  • 小结
  • doc
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档