本文主要研究一下spring cloud的FeignLoadBalancer
spring-cloud-openfeign-core-2.2.0.M1-sources.jar!/org/springframework/cloud/openfeign/ribbon/FeignLoadBalancer.java
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); } //...... }
spring-cloud-openfeign-core-2.2.0.M1-sources.jar!/org/springframework/cloud/openfeign/ribbon/FeignLoadBalancer.java
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()); } }
spring-cloud-openfeign-core-2.2.0.M1-sources.jar!/org/springframework/cloud/openfeign/ribbon/FeignLoadBalancer.java
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(); } } }