当前位置:网站首页>Loadbalancerlife lifecycle requested by feign client
Loadbalancerlife lifecycle requested by feign client
2022-07-25 11:20:00 【Emily】
LoadBalancerLifecycle Interfaces are allowed in load-balancing What should be done before and after execution , We can use this entry to get the real request of the microservice request URL;
One 、LoadBalancerLifecycle Interface source code
public interface LoadBalancerLifecycle<RC, RES, T> {
/** * Determine whether the service instance object allows method callbacks */
default boolean supports(Class requestContextClass, Class responseClass, Class serverTypeClass) {
return true;
}
/** * In execution load-balancing Before ( That is, get real service instances url Before ) The callback method */
void onStart(Request<RC> request);
/** * After selecting a real service instance , Callback method before executing the request */
void onStartRequest(Request<RC> request, Response<T> lbResponse);
/** * stay load-balancing Load balancing is performed after the real service request */
void onComplete(CompletionContext<RES, T, RC> completionContext);
}
Two 、 be based on loadbalance There are two requests for service FeignBlockingLoadBalancerClient( Retry is not supported )、RetryableFeignBlockingLoadBalancerClient( Support retry )
Let's take a look first FeignBlockingLoadBalancerClient Source code :
public class FeignBlockingLoadBalancerClient implements Client {
...
@Override
public Response execute(Request request, Request.Options options) throws IOException {
// Get request URL
final URI originalUri = URI.create(request.url());
// Get micro service instance ID
String serviceId = originalUri.getHost();
Assert.state(serviceId != null, "Request URI does not contain a valid hostname: " + originalUri);
// Get the configuration hit value
String hint = getHint(serviceId);
// Get the request online document object
DefaultRequest<RequestDataContext> lbRequest = new DefaultRequest<>(
new RequestDataContext(buildRequestData(request), hint));
// Get the lifecycle management object that meets the current request instance
Set<LoadBalancerLifecycle> supportedLifecycleProcessors = LoadBalancerLifecycleValidator
.getSupportedLifecycleProcessors(
loadBalancerClientFactory.getInstances(serviceId, LoadBalancerLifecycle.class),
RequestDataContext.class, ResponseData.class, ServiceInstance.class);
// Call life cycle onStart The callback method
supportedLifecycleProcessors.forEach(lifecycle -> lifecycle.onStart(lbRequest));
// Get the microservice instance object corresponding to the request instance
ServiceInstance instance = loadBalancerClient.choose(serviceId, lbRequest);
// Request response object
org.springframework.cloud.client.loadbalancer.Response<ServiceInstance> lbResponse = new DefaultResponse(
instance);
// If the request instance does not exist , Then directly call the lifecycle completion method 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();
}
// Get the real request object of the instance request
String reconstructedUrl = loadBalancerClient.reconstructURI(instance, originalUri).toString();
// structure Request Request object
Request newRequest = buildRequest(request, reconstructedUrl);
// Execute the real request
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;
}
// Get the configuration hit value
private String getHint(String serviceId) {
String defaultHint = properties.getHint().getOrDefault("default", "default");
String hintPropertyValue = properties.getHint().get(serviceId);
return hintPropertyValue != null ? hintPropertyValue : defaultHint;
}
}
executeWithLoadBalancerLifecycleProcessing Request method :
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 {
// Getting the real request URL after , Execute before sending the real request onStartRequest The callback method
supportedLifecycleProcessors.forEach(lifecycle -> lifecycle.onStartRequest(lbRequest, lbResponse));
try {
// Execute the real request
Response response = feignClient.execute(feignRequest, options);
if (loadBalanced) {
// Execute the declaration cycle callback method onComplete
supportedLifecycleProcessors.forEach(
lifecycle -> lifecycle.onComplete(new CompletionContext<>(CompletionContext.Status.SUCCESS,
lbRequest, lbResponse, buildResponseData(response))));
}
return response;
}
catch (Exception exception) {
if (loadBalanced) {
// Execute the declaration cycle callback method onComplete
supportedLifecycleProcessors.forEach(lifecycle -> lifecycle.onComplete(
new CompletionContext<>(CompletionContext.Status.FAILED, exception, lbRequest, lbResponse)));
}
throw exception;
}
}
If open spring.cloud.loadbalancer.retry.enabled=true Retry capability , Then it is executed RetryableFeignBlockingLoadBalancerClient, Its implementation process is consistent with the above , No more detailed analysis ;
GitHub Address :https://github.com/mingyang66/spring-parent
边栏推荐
- Probe into Druid query timeout configuration → who is the querytimeout of datasource and jdbctemplate effective?
- 复习背诵整理版
- Reinforcement Learning 强化学习(四)
- [树] 100. 相同的树
- Hcip experiment (03)
- MySQL master-slave replication and read-write separation
- 最详细的mysql索引解析(文末附赠思维导图)
- 推荐系统-协同过滤在Spark中的实现
- HCIA experiment (08)
- 玩游戏想记录一下自己超神的瞬间?那么就来看一下如何使用Unity截图吧
猜你喜欢

让运动自然发生,FITURE打造全新生活方式

C# Newtonsoft.Json 高级用法

From the perspective of open source, analyze the architecture design of SAP classic ERP that will not change in 30 years

HCIA experiment (10) nat

redis 哨兵,高可用的执行者

HCIP(13)

Learn NLP with Transformer (Chapter 6)
Learn NLP with Transformer (Chapter 3)

我,AI博士生,在线众筹研究主题

Motivation of enterprises to practice open source
随机推荐
TPS calculation in performance test [Hangzhou multi tester] [Hangzhou multi tester _ Wang Sir]
Openstack skyline component installation
ArcMap无法启动解决方法
Mlx90640 infrared thermal imager temperature measurement module development notes (V)
Learn NLP with Transformer (Chapter 7)
Learn PHP -- phpstudy tips mysqld Exe: Error While Setting Value ‘NO_ ENGINE_ Solution of substitution error
[high concurrency] how to realize distributed flow restriction under 100 million level traffic? You must master these theories!!
【高并发】如何实现亿级流量下的分布式限流?这些理论你必须掌握!!
HDD杭州站全程体验有感
HCIP(11)
Learn NLP with Transformer (Chapter 8)
Some usages of beautifulsoup
数字孪生万物可视 | 联接现实世界与数字空间
HCIA experiment (08)
SQL语言(六)
【Servlet】请求的解析
BeautifulSoup的一些用法
MLX90640 红外热成像仪测温模块开发笔记(五)
shell-第四天作业
SQL语言(五)