Netflix Feign - Spring Cloud 整合 Feign 源码(十一)

82 阅读1分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。


HTTP组件发送请求报文

ServerOperation.call()方法根据选择的Server,使用Server.getHost和Server.getPort重构URI。

使用重构URI,将request【FeignLoadBalancer.RibbonRequest】的URI替换掉,并返回新的requestForServer【FeignLoadBalancer.RibbonRequest】。

http://192.168.1.2:8080/product/facade

LoadBalancerCommand的selectServer()方法中选择一个server,然后将server放到ServerOperation.call()方法中去。

在ServerOperation.call()方法中,根据处理好的请求URLhttp:///product/facade

加上选择出的server的地址:192.168.1.2:8080,拼接一起。

http://192.168.1.2:8080/product/facade,最终的请求URL地址。

AbstractLoadBalancerAwareClient.this.execute(requestForServer, requestConfig)

调用FeignLoadBalancer#execute()方法,向请求URL地址发送http请求。

发送请求的超时时间,请求时间最好不要超过200ms,一般接口最好是在几十ms,

Request.Options options = new Request.Options(this.connectTimeout, this.readTimeout);

最终发起实际的http请求的时候,超时时间,默认是1000毫秒。

Response response = request.client().execute(request.toRequest(), options);

发送http请求,将结果封装为RibbonResponse。

Feign处理响应结果

发送请求GET http://192.168.1.2:8080/product/facade HTTP/1.1,服务返回数据保存在Response的body属性中。

if (response.status() >= 200 && response.status() < 300) {
    if (void.class == metadata.returnType()) {
        return null;
    } else {
        Object result = decode(response);
        shouldClose = closeAfterDecode;
        return result;
    }
}

decode()方法,使用Decoder组件,对返回的body反序列化为指定的类型,默认的是ResponseEntityDecoder。

Object decode(Response response) throws Throwable {
    try {
        // MethodMetadata metadata
        // metadata.returnType:java.util.List<center.leon.eurekacommon.entity.ProductEntity>
        // ResponseEntityDecoder(SpringDecoder)
        return decoder.decode(response, metadata.returnType());
    } catch (FeignException e) {
        throw e;
    } catch (RuntimeException e) {
        throw new DecodeException(response.status(), e.getMessage(), response.request(), e);
    }
}

Feign & Ribbon & Eureka

Feign

  1. 使用负载均衡算法找到可以调用的Server,默认是随机。
  2. 然后调用外部传入client的具体方法去发送请求。

Ribbon

ServerList:关联注册中心客户端取获取服务列表。DiscoveryEnabledNIWSServerList通过EurekaClient取获取列表。

ServerListFilter:过滤服务列表

IRule:负载均衡规则

IPing:定时检测服务器的状态(不检查、判断Server状态、发送请求检查)

ServerListUpdater:更新服务器列表。PollingServerListUpdater默认30秒拉取一次列表。