本文已参与「新人创作礼」活动,一起开启掘金创作之路。
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
- 使用负载均衡算法找到可以调用的Server,默认是随机。
- 然后调用外部传入client的具体方法去发送请求。
Ribbon
ServerList:关联注册中心客户端取获取服务列表。DiscoveryEnabledNIWSServerList通过EurekaClient取获取列表。
ServerListFilter:过滤服务列表
IRule:负载均衡规则
IPing:定时检测服务器的状态(不检查、判断Server状态、发送请求检查)
ServerListUpdater:更新服务器列表。PollingServerListUpdater默认30秒拉取一次列表。