专业的编程技术博客社区

网站首页 > 博客文章 正文

聊聊spring cloud的FeignLoadBalancer

baijin 2024-09-20 12:33:15 博客文章 3 ℃ 0 评论

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

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);
 }
?
 //......
}
  • 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

 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

 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

  • FeignLoadBalancer

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表