【SpringCloud负载均衡】【源码+图解】【二】LoadBalancer配置
3. LoadBalancer的工作原理
当客户端发起请求后被LoadBalancerInterceptor拦截,看下拦截的方法
public class LoadBalancerInterceptor implements ClientHttpRequestInterceptor {
// 即BlockingLoadBalancerClient
private LoadBalancerClient loadBalancer;
// 即LoadBalancerRequestFactory
private LoadBalancerRequestFactory requestFactory;
@Override
public ClientHttpResponse intercept(final HttpRequest request, final byte[] body,
final ClientHttpRequestExecution execution) throws IOException {
final URI originalUri = request.getURI();
// 获取url的host,如上文中UserController中的"http://product/prod",则serviceName(后文也指serviceId)为product
String serviceName = originalUri.getHost();
return this.loadBalancer.execute(serviceName, this.requestFactory.createRequest(request, body, execution));
}
}
当请求被拦截后LoadBalancer的整个工作流程
具体过程如下:
- 将普通httpRequest封装成BlockingLoadBalancerRequest
- 如果当前serviceId对应的上下文不存在则创建上下文
- 从上下文中获取负载均衡器
- 利用负载均衡器选取合适的serviceInstance
- 向具体的serviceInstance发送请求
3.1 创建LoadBalancerRequest
public class LoadBalancerRequestFactory {
public LoadBalancerRequest<ClientHttpResponse> createRequest(final HttpRequest request, final byte[] body,
final ClientHttpRequestExecution execution) {
// 将普通的HttpRequest包装成LoadBalancerRequest
return new BlockingLoadBalancerRequest(loadBalancer, transformers,
new BlockingLoadBalancerRequest.ClientHttpRequestData(request, body, execution));
}
}
BlockingLoadBalancerRequest的关键在于apply
函数,后续再详细分析
3.2 创建上下文
在LoadBalancer中LoadBalancerClientFactory负责管理yml文件中的配置、微服务的应用上下文ApplicationContext,每一个serviceId对应一个ApplicationContext,而这个ApplicationContext中最关键的是提供服务列表的Supplier和选择服务的ReactiveLoadBalancer。先看LoadBalancerClientFactory类图
然后我们将LoadBalancerClientFactory的属性具象化,方便理解,看下图
接下来详细介绍下这三个参数
3.2.1 properties
它的载体为LoadBalancerClientsProperties类,我们看下它的类图
结合类图,我们就可以列出关于loadBalance的相关配置
spring:
cloud:
loadbalancer:
health-check:
initial-delay: 0s
interval: 25s
refetch-instances: false
refetch-instances-interval: 25s
path:
default: /actuator/health
repeat-health-check: true
hint:
my-hint: hint-example
hint-header-name: "X-SC-LB-Hint"
retry:
enabled: true
retry-on-all-operations: false
max-retries-on-same-service-instance: 0
max-retries-on-next-service-instance: 1
retryable-status-codes:
- 404
backoff:
enabled: false
min-backoff: 5
max-backoff: 10
jitter: 0.5
sticky-session:
instance-id-cookie-name: sc-lb