网站首页 > 博客文章 正文
序
本文主要研究一下AsyncLoadBalancerAutoConfiguration
AsyncLoadBalancerAutoConfiguration
spring-cloud-commons-2.0.0.RELEASE-sources.jar!/org/springframework/cloud/client/loadbalancer/AsyncLoadBalancerAutoConfiguration.java
/**
* Auto configuration for Ribbon (client side load balancing).
*
* @author Rob Worsnop
*/
@Configuration
@ConditionalOnBean(LoadBalancerClient.class)
@ConditionalOnClass(AsyncRestTemplate.class)
public class AsyncLoadBalancerAutoConfiguration {
@Configuration
static class AsyncRestTemplateCustomizerConfig {
@LoadBalanced
@Autowired(required = false)
private List<AsyncRestTemplate> restTemplates = Collections.emptyList();
@Bean
public SmartInitializingSingleton loadBalancedAsyncRestTemplateInitializer(
final List<AsyncRestTemplateCustomizer> customizers) {
return new SmartInitializingSingleton() {
@Override
public void afterSingletonsInstantiated() {
for (AsyncRestTemplate restTemplate : AsyncRestTemplateCustomizerConfig.this.restTemplates) {
for (AsyncRestTemplateCustomizer customizer : customizers) {
customizer.customize(restTemplate);
}
}
}
};
}
}
@Configuration
static class LoadBalancerInterceptorConfig {
@Bean
public AsyncLoadBalancerInterceptor asyncLoadBalancerInterceptor(LoadBalancerClient loadBalancerClient) {
return new AsyncLoadBalancerInterceptor(loadBalancerClient);
}
@Bean
public AsyncRestTemplateCustomizer asyncRestTemplateCustomizer(
final AsyncLoadBalancerInterceptor loadBalancerInterceptor) {
return new AsyncRestTemplateCustomizer() {
@Override
public void customize(AsyncRestTemplate restTemplate) {
List<AsyncClientHttpRequestInterceptor> list = new ArrayList<>(
restTemplate.getInterceptors());
list.add(loadBalancerInterceptor);
restTemplate.setInterceptors(list);
}
};
}
}
}
- 这里创建一个AsyncRestTemplateCustomizerConfig,用于加载AsyncRestTemplateCustomizer
- 还有一个LoadBalancerInterceptorConfig,配置了AsyncLoadBalancerInterceptor及AsyncRestTemplateCustomizer
AsyncRestTemplateCustomizer
spring-cloud-commons-2.0.0.RELEASE-sources.jar!/org/springframework/cloud/client/loadbalancer/AsyncRestTemplateCustomizer.java
public interface AsyncRestTemplateCustomizer {
void customize(AsyncRestTemplate restTemplate);
}
- 这里采用匿名类实现,主要就是设置AsyncClientHttpRequestInterceptor
AsyncClientHttpRequestInterceptor
spring-cloud-commons-2.0.0.RELEASE-sources.jar!/org/springframework/cloud/client/loadbalancer/AsyncLoadBalancerInterceptor.java
public class AsyncLoadBalancerInterceptor implements AsyncClientHttpRequestInterceptor {
private LoadBalancerClient loadBalancer;
public AsyncLoadBalancerInterceptor(LoadBalancerClient loadBalancer) {
this.loadBalancer = loadBalancer;
}
@Override
public ListenableFuture<ClientHttpResponse> intercept(final HttpRequest request, final byte[] body,
final AsyncClientHttpRequestExecution execution) throws IOException {
final URI originalUri = request.getURI();
String serviceName = originalUri.getHost();
return this.loadBalancer.execute(serviceName,
new LoadBalancerRequest<ListenableFuture<ClientHttpResponse>>() {
@Override
public ListenableFuture<ClientHttpResponse> apply(final ServiceInstance instance)
throws Exception {
HttpRequest serviceRequest = new ServiceRequestWrapper(request,
instance, loadBalancer);
return execution.executeAsync(serviceRequest, body);
}
});
}
}
- 这个拦截器从url获取serviceName,然后调用loadBalancer.execute方法
- 这里构造的LoadBalancerRequest,采用ServiceRequestWrapper,调用的是execution.executeAsync
AbstractAsyncClientHttpRequest
spring-web-5.0.7.RELEASE-sources.jar!/org/springframework/http/client/AbstractAsyncClientHttpRequest.java
/**
* Abstract base for {@link AsyncClientHttpRequest} that makes sure that headers and body
* are not written multiple times.
*
* @author Arjen Poutsma
* @since 4.0
* @deprecated as of Spring 5.0, in favor of {@link org.springframework.http.client.reactive.AbstractClientHttpRequest}
*/
@Deprecated
abstract class AbstractAsyncClientHttpRequest implements AsyncClientHttpRequest {
private final HttpHeaders headers = new HttpHeaders();
private boolean executed = false;
@Override
public final HttpHeaders getHeaders() {
return (this.executed ? HttpHeaders.readOnlyHttpHeaders(this.headers) : this.headers);
}
@Override
public final OutputStream getBody() throws IOException {
assertNotExecuted();
return getBodyInternal(this.headers);
}
@Override
public ListenableFuture<ClientHttpResponse> executeAsync() throws IOException {
assertNotExecuted();
ListenableFuture<ClientHttpResponse> result = executeInternal(this.headers);
this.executed = true;
return result;
}
/**
* Asserts that this request has not been {@linkplain #executeAsync() executed} yet.
* @throws IllegalStateException if this request has been executed
*/
protected void assertNotExecuted() {
Assert.state(!this.executed, "ClientHttpRequest already executed");
}
/**
* Abstract template method that returns the body.
* @param headers the HTTP headers
* @return the body output stream
*/
protected abstract OutputStream getBodyInternal(HttpHeaders headers) throws IOException;
/**
* Abstract template method that writes the given headers and content to the HTTP request.
* @param headers the HTTP headers
* @return the response object for the executed request
*/
protected abstract ListenableFuture<ClientHttpResponse> executeInternal(HttpHeaders headers)
throws IOException;
}
- 这个executeAsync的委托给子类的executeInternal实现
- 主要有SimpleStreamingAsyncClientHttpRequest、Netty4ClientHttpRequest两个实现
SimpleStreamingAsyncClientHttpRequest
spring-web-5.0.7.RELEASE-sources.jar!/org/springframework/http/client/SimpleStreamingAsyncClientHttpRequest.java
- 主要使用的是jdk的HttpURLConnection来实现
Netty4ClientHttpRequest
spring-web-5.0.7.RELEASE-sources.jar!/org/springframework/http/client/Netty4ClientHttpRequest.java
- 使用netty的bootstrap.connect进行请求
小结
AsyncLoadBalancerAutoConfiguration使用的AsyncClientHttpRequest及其实现类都被标记为废弃,spring 5之后推荐使用webClient。
doc
- 3.4 Spring WebClient as a Load Balancer Client
猜你喜欢
- 2024-09-20 Spring cloud Ribbon 客户端负载均衡详解(二)负载均衡器
- 2024-09-20 springcloud(十三):注册中心 Consul 使用详解
- 2024-09-20 SpringCloud系列——11Spring Cloud 源码分析之Gateway网关
- 2024-09-20 FeignClient注解配置url属性实现指定服务方
- 2024-09-20 SpringCloud升级之路2020.0.x版-34.验证重试配置正确性(2)
- 2024-09-20 我放弃了okhttp、httpClient,选了这个神仙工具
- 2024-09-20 还没有秃头吗?你真的需要大牛来教你如何深入解析Ribbon源码了
- 2024-09-20 Spring GateWay : 网关的转发细节
- 2024-09-20 深入理解SpringCloud之Gateway,小白都能看懂的保姆级教学
- 2024-09-20 微服务架构进阶:Hystrix 如何解决灾难性雪崩及隔离问题
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- powershellfor (55)
- messagesource (56)
- aspose.pdf破解版 (56)
- promise.race (63)
- 2019cad序列号和密钥激活码 (62)
- window.performance (66)
- qt删除文件夹 (72)
- mysqlcaching_sha2_password (64)
- ubuntu升级gcc (58)
- nacos启动失败 (64)
- ssh-add (70)
- jwt漏洞 (58)
- macos14下载 (58)
- yarnnode (62)
- abstractqueuedsynchronizer (64)
- source~/.bashrc没有那个文件或目录 (65)
- springboot整合activiti工作流 (70)
- jmeter插件下载 (61)
- 抓包分析 (60)
- idea创建mavenweb项目 (65)
- vue回到顶部 (57)
- qcombobox样式表 (68)
- vue数组concat (56)
- tomcatundertow (58)
- pastemac (61)
本文暂时没有评论,来添加一个吧(●'◡'●)