当前位置:网站首页>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
边栏推荐
猜你喜欢

AI系统前沿动态第43期:OneFlow v0.8.0正式发布;GPU发现人脑连接;AI博士生在线众筹研究主题

学习路之PHP--TP5.0使用中文当别名,报“不支持的数据表达式”

100W了!
Learn NLP with Transformer (Chapter 2)

Ue4.26 source code version black screen problem of client operation when learning Wan independent server

PostgreSQL踩坑 | ERROR: operator does not exist: uuid = character varying

What is MySQL transaction

HCIP(12)

Hcip experiment (01)

Esp32c3 based on the example tutorial of esp32 Rainmaker development under Arduino framework
随机推荐
AI系统前沿动态第43期:OneFlow v0.8.0正式发布;GPU发现人脑连接;AI博士生在线众筹研究主题
Signal integrity (SI) power integrity (PI) learning notes (XXXIII) 102 general design rules to minimize signal integrity problems
[树] 100. 相同的树
Learn NLP with Transformer (Chapter 7)
用Unity不会几个插件怎么能行?Unity各类插件及教程推荐
NowCoderTOP12-16——持续更新ing
JS convert pseudo array to array
From the perspective of open source, analyze the architecture design of SAP classic ERP that will not change in 30 years
MySQL | GROUP_CONCAT函数,将某一列的值用逗号拼接
学习路之PHP--Phpstudy 提示 Mysqld.Exe: Error While Setting Value ‘NO_ENGINE_SUBSTITUTION 错误的解决办法
Tree dynamic programming
Nowcodertop1-6 - continuous updating
BeautifulSoup的一些用法
[high concurrency] how to realize distributed flow restriction under 100 million level traffic? You must master these theories!!
Ue4.26 source code version black screen problem of client operation when learning Wan independent server
让运动自然发生,FITURE打造全新生活方式
Code representation learning: introduction to codebert and other related models
The University of Gottingen proposed clipseg: a model that can perform three segmentation tasks simultaneously using text and image prompts
复习背诵整理版
Some usages of beautifulsoup