当前位置:网站首页>feign客户端请求之LoadBalancerLifecycle生命周期
feign客户端请求之LoadBalancerLifecycle生命周期
2022-07-25 10:18:00 【艾米莉Emily】
LoadBalancerLifecycle接口允许在load-balancing执行前后应执行的操作,我们可以借此入口获取微服务请求的真实请求URL;
一、LoadBalancerLifecycle接口源码
public interface LoadBalancerLifecycle<RC, RES, T> {
/** * 判定服务实例对象是否允许执行方法回调 */
default boolean supports(Class requestContextClass, Class responseClass, Class serverTypeClass) {
return true;
}
/** * 在执行load-balancing之前(即获取真实服务实例url之前)的回调方法 */
void onStart(Request<RC> request);
/** * 已经选择一个真实的服务实例之后,在执行请求之前的回调方法 */
void onStartRequest(Request<RC> request, Response<T> lbResponse);
/** * 在load-balancing负载均衡真实服务请求之后执行 */
void onComplete(CompletionContext<RES, T, RC> completionContext);
}
二、基于loadbalance请求服务有两个FeignBlockingLoadBalancerClient(不支持重试)、RetryableFeignBlockingLoadBalancerClient(支持重试)
我们先看下FeignBlockingLoadBalancerClient的源码:
public class FeignBlockingLoadBalancerClient implements Client {
...
@Override
public Response execute(Request request, Request.Options options) throws IOException {
//获取请求URL
final URI originalUri = URI.create(request.url());
//获取微服务实例ID
String serviceId = originalUri.getHost();
Assert.state(serviceId != null, "Request URI does not contain a valid hostname: " + originalUri);
//获取配置命中值
String hint = getHint(serviceId);
//获取请求上线文对象
DefaultRequest<RequestDataContext> lbRequest = new DefaultRequest<>(
new RequestDataContext(buildRequestData(request), hint));
//获取符合当前请求实例的生命周期管理对象
Set<LoadBalancerLifecycle> supportedLifecycleProcessors = LoadBalancerLifecycleValidator
.getSupportedLifecycleProcessors(
loadBalancerClientFactory.getInstances(serviceId, LoadBalancerLifecycle.class),
RequestDataContext.class, ResponseData.class, ServiceInstance.class);
//调用生命 周期onStart回调方法
supportedLifecycleProcessors.forEach(lifecycle -> lifecycle.onStart(lbRequest));
//获取请求实例对应的微服务实例对象
ServiceInstance instance = loadBalancerClient.choose(serviceId, lbRequest);
//请求响应对象
org.springframework.cloud.client.loadbalancer.Response<ServiceInstance> lbResponse = new DefaultResponse(
instance);
//如果请求实例不存在,则直接调用生命周期完成方法onComplete
if (instance == null) {
String message = "Load balancer does not contain an instance for the service " + serviceId;
if (LOG.isWarnEnabled()) {
LOG.warn(message);
}
supportedLifecycleProcessors.forEach(lifecycle -> lifecycle
.onComplete(new CompletionContext<ResponseData, ServiceInstance, RequestDataContext>(
CompletionContext.Status.DISCARD, lbRequest, lbResponse)));
return Response.builder().request(request).status(HttpStatus.SERVICE_UNAVAILABLE.value())
.body(message, StandardCharsets.UTF_8).build();
}
//获取实例请求的真实请求对象
String reconstructedUrl = loadBalancerClient.reconstructURI(instance, originalUri).toString();
//构建Request请求对象
Request newRequest = buildRequest(request, reconstructedUrl);
//执行真实请求
return executeWithLoadBalancerLifecycleProcessing(delegate, options, newRequest, lbRequest, lbResponse,
supportedLifecycleProcessors);
}
protected Request buildRequest(Request request, String reconstructedUrl) {
return Request.create(request.httpMethod(), reconstructedUrl, request.headers(), request.body(),
request.charset(), request.requestTemplate());
}
// Visible for Sleuth instrumentation
public Client getDelegate() {
return delegate;
}
// 获取配置命中值
private String getHint(String serviceId) {
String defaultHint = properties.getHint().getOrDefault("default", "default");
String hintPropertyValue = properties.getHint().get(serviceId);
return hintPropertyValue != null ? hintPropertyValue : defaultHint;
}
}
executeWithLoadBalancerLifecycleProcessing请求方法:
static Response executeWithLoadBalancerLifecycleProcessing(Client feignClient, Request.Options options,
Request feignRequest, org.springframework.cloud.client.loadbalancer.Request lbRequest,
org.springframework.cloud.client.loadbalancer.Response<ServiceInstance> lbResponse,
Set<LoadBalancerLifecycle> supportedLifecycleProcessors, boolean loadBalanced) throws IOException {
//在获取真实请求URL之后,在发送真实请求之前执行onStartRequest回调方法
supportedLifecycleProcessors.forEach(lifecycle -> lifecycle.onStartRequest(lbRequest, lbResponse));
try {
//执行真实请求
Response response = feignClient.execute(feignRequest, options);
if (loadBalanced) {
//执行声明周期回调方法onComplete
supportedLifecycleProcessors.forEach(
lifecycle -> lifecycle.onComplete(new CompletionContext<>(CompletionContext.Status.SUCCESS,
lbRequest, lbResponse, buildResponseData(response))));
}
return response;
}
catch (Exception exception) {
if (loadBalanced) {
//执行声明周期回调方法onComplete
supportedLifecycleProcessors.forEach(lifecycle -> lifecycle.onComplete(
new CompletionContext<>(CompletionContext.Status.FAILED, exception, lbRequest, lbResponse)));
}
throw exception;
}
}
如果开启spring.cloud.loadbalancer.retry.enabled=true重试能力,则执行的是RetryableFeignBlockingLoadBalancerClient,其执行流程跟上述一致,不在做详细分析;
边栏推荐
- How to optimize the performance when the interface traffic increases suddenly?
- Learn NLP with Transformer (Chapter 4)
- Digital twin everything can be seen | connecting the real world and digital space
- How to notify users of wechat applet version update?
- C3d model pytorch source code sentence by sentence analysis (I)
- Probe into Druid query timeout configuration → who is the querytimeout of datasource and jdbctemplate effective?
- HDD杭州站全程体验有感
- AI technology stack is too huge! Wu Enda gives career planning: lifelong learning
- Software Testing Technology: cross platform mobile UI automated testing (Part 1)
- 2021 CEC written examination summary
猜你喜欢

Keras deep learning practice (16) -- detailed explanation of self encoder

Introduction to onnx (open neural network exchange)

Disabled and readonly and focus issues

HCIA实验(08)

电磁场与电磁波实验一 熟悉Matlab软件在电磁场领域的应用

性能测试中TPS的计算【杭州多测师】【杭州多测师_王sir】

NB-IOT控制液晶屏(日期的设置与读取)

Flask框架——Flask-WTF表单:文件上传、验证码

Reinforcement Learning 强化学习(四)

Learn NLP with Transformer (Chapter 5)
随机推荐
Flask framework - Message flash
二合一的集度,任重道远
How to optimize the performance when the interface traffic increases suddenly?
2021 scenery written examination summary
SQL语言(五)
AI技术栈太庞大!吴恩达给出职业生涯规划:终生学习
信号完整性(SI)电源完整性(PI)学习笔记(三十四)100条估计信号完整性效应的经验法则
What is MySQL transaction
Last week's hot review (7.18-7.24)
企业实践开源的动机
Learn NLP with Transformer (Chapter 8)
100W了!
Basic experiment of microwave technology - Filter Design
数字孪生万物可视 | 联接现实世界与数字空间
HDD杭州站全程体验有感
Flame framework - Flame WTF form: file upload, verification code
HCIP(12)
[cloud enjoys freshness] community weekly · Vol 72 - the first opening ceremony of the 2022 Huawei developer competition in China was launched; Huawei cloud koomessage is in hot public beta
HCIP(13)
一文读懂小程序的生命周期和路由跳转