本文主要研究一下spring cloud的LoadBalancerAutoConfiguration

RibbonAutoConfiguration

spring-cloud-netflix-ribbon-2.0.0.RC2-sources.jar!/org/springframework/cloud/netflix/ribbon/RibbonAutoConfiguration.java

@Configuration
@ConditionalOnClass(RestTemplate.class)
@ConditionalOnBean(LoadBalancerClient.class)
@EnableConfigurationProperties(LoadBalancerRetryProperties.class)
public class LoadBalancerAutoConfiguration {@LoadBalanced@Autowired(required = false)private List<RestTemplate> restTemplates = Collections.emptyList();@Beanpublic SmartInitializingSingleton loadBalancedRestTemplateInitializerDeprecated(final ObjectProvider<List<RestTemplateCustomizer>> restTemplateCustomizers) {return () -> restTemplateCustomizers.ifAvailable(customizers -> {for (RestTemplate restTemplate : LoadBalancerAutoConfiguration.this.restTemplates) {for (RestTemplateCustomizer customizer : customizers) {customizer.customize(restTemplate);}}});}@Autowired(required = false)private List<LoadBalancerRequestTransformer> transformers = Collections.emptyList();@Bean@ConditionalOnMissingBeanpublic LoadBalancerRequestFactory loadBalancerRequestFactory(LoadBalancerClient loadBalancerClient) {return new LoadBalancerRequestFactory(loadBalancerClient, transformers);}@Configuration@ConditionalOnMissingClass("org.springframework.retry.support.RetryTemplate")static class LoadBalancerInterceptorConfig {@Beanpublic LoadBalancerInterceptor ribbonInterceptor(LoadBalancerClient loadBalancerClient,LoadBalancerRequestFactory requestFactory) {return new LoadBalancerInterceptor(loadBalancerClient, requestFactory);}@Bean@ConditionalOnMissingBeanpublic RestTemplateCustomizer restTemplateCustomizer(final LoadBalancerInterceptor loadBalancerInterceptor) {return restTemplate -> {List<ClientHttpRequestInterceptor> list = new ArrayList<>(restTemplate.getInterceptors());list.add(loadBalancerInterceptor);restTemplate.setInterceptors(list);};}}@Configuration@ConditionalOnClass(RetryTemplate.class)public static class RetryAutoConfiguration {@Bean@ConditionalOnMissingBeanpublic LoadBalancedRetryFactory loadBalancedRetryFactory() {return new LoadBalancedRetryFactory() {};}}@Configuration@ConditionalOnClass(RetryTemplate.class)public static class RetryInterceptorAutoConfiguration {@Bean@ConditionalOnMissingBeanpublic RetryLoadBalancerInterceptor ribbonInterceptor(LoadBalancerClient loadBalancerClient, LoadBalancerRetryProperties properties,LoadBalancerRequestFactory requestFactory,LoadBalancedRetryFactory loadBalancedRetryFactory) {return new RetryLoadBalancerInterceptor(loadBalancerClient, properties,requestFactory, loadBalancedRetryFactory);}@Bean@ConditionalOnMissingBeanpublic RestTemplateCustomizer restTemplateCustomizer(final RetryLoadBalancerInterceptor loadBalancerInterceptor) {return restTemplate -> {List<ClientHttpRequestInterceptor> list = new ArrayList<>(restTemplate.getInterceptors());list.add(loadBalancerInterceptor);restTemplate.setInterceptors(list);};}}
}
复制代码
  • 定义了LoadBalancerRequestFactory以及LoadBalancerInterceptorConfig、RetryAutoConfiguration、RetryInterceptorAutoConfiguration

LoadBalancerRetryProperties

spring-cloud-commons-2.0.0.RC2-sources.jar!/org/springframework/cloud/client/loadbalancer/LoadBalancerRetryProperties.java

/*** Configuration properties for the {@link LoadBalancerClient}.* @author Ryan Baxter*/
@ConfigurationProperties("spring.cloud.loadbalancer.retry")
public class LoadBalancerRetryProperties {private boolean enabled = true;/*** Returns true if the load balancer should retry failed requests.* @return true if the load balancer should retry failed request, false otherwise.*/public boolean isEnabled() {return enabled;}/*** Sets whether the load balancer should retry failed request.* @param enabled whether the load balancer should retry failed requests*/public void setEnabled(boolean enabled) {this.enabled = enabled;}
}
复制代码
  • 这个配置是否开启loadbalancer的retry

RetryLoadBalancerInterceptor

spring-cloud-commons-2.0.0.RC2-sources.jar!/org/springframework/cloud/client/loadbalancer/RetryLoadBalancerInterceptor.java

public class RetryLoadBalancerInterceptor implements ClientHttpRequestInterceptor {private LoadBalancerClient loadBalancer;private LoadBalancerRetryProperties lbProperties;private LoadBalancerRequestFactory requestFactory;private LoadBalancedRetryFactory lbRetryFactory;public RetryLoadBalancerInterceptor(LoadBalancerClient loadBalancer,LoadBalancerRetryProperties lbProperties,LoadBalancerRequestFactory requestFactory,LoadBalancedRetryFactory lbRetryFactory) {this.loadBalancer = loadBalancer;this.lbProperties = lbProperties;this.requestFactory = requestFactory;this.lbRetryFactory = lbRetryFactory;}@Overridepublic ClientHttpResponse intercept(final HttpRequest request, final byte[] body,final ClientHttpRequestExecution execution) throws IOException {final URI originalUri = request.getURI();final String serviceName = originalUri.getHost();Assert.state(serviceName != null, "Request URI does not contain a valid hostname: " + originalUri);final LoadBalancedRetryPolicy retryPolicy = lbRetryFactory.createRetryPolicy(serviceName,loadBalancer);RetryTemplate template = createRetryTemplate(serviceName, request, retryPolicy);return template.execute(context -> {ServiceInstance serviceInstance = null;if (context instanceof LoadBalancedRetryContext) {LoadBalancedRetryContext lbContext = (LoadBalancedRetryContext) context;serviceInstance = lbContext.getServiceInstance();}if (serviceInstance == null) {serviceInstance = loadBalancer.choose(serviceName);}ClientHttpResponse response = RetryLoadBalancerInterceptor.this.loadBalancer.execute(serviceName, serviceInstance,requestFactory.createRequest(request, body, execution));int statusCode = response.getRawStatusCode();if (retryPolicy != null && retryPolicy.retryableStatusCode(statusCode)) {byte[] bodyCopy = StreamUtils.copyToByteArray(response.getBody());response.close();throw new ClientHttpResponseStatusCodeException(serviceName, response, bodyCopy);}return response;}, new LoadBalancedRecoveryCallback<ClientHttpResponse, ClientHttpResponse>() {//This is a special case, where both parameters to LoadBalancedRecoveryCallback are//the same.  In most cases they would be different.@Overrideprotected ClientHttpResponse createResponse(ClientHttpResponse response, URI uri) {return response;}});}private RetryTemplate createRetryTemplate(String serviceName, HttpRequest request, LoadBalancedRetryPolicy retryPolicy) {RetryTemplate template = new RetryTemplate();BackOffPolicy backOffPolicy = lbRetryFactory.createBackOffPolicy(serviceName);template.setBackOffPolicy(backOffPolicy == null ? new NoBackOffPolicy() : backOffPolicy);template.setThrowLastExceptionOnExhausted(true);RetryListener[] retryListeners = lbRetryFactory.createRetryListeners(serviceName);if (retryListeners != null && retryListeners.length != 0) {template.setListeners(retryListeners);}template.setRetryPolicy(!lbProperties.isEnabled() || retryPolicy == null ? new NeverRetryPolicy(): new InterceptorRetryPolicy(request, retryPolicy, loadBalancer,serviceName));return template;}
}
复制代码
  • 实现了ClientHttpRequestInterceptor接口
  • 通过lbRetryFactory.createRetryPolicy(serviceName,loadBalancer)创建重试策略,然后创建RetryTemplate

小结

LoadBalancerAutoConfiguration这个类定义了LoadBalancerRequestFactory以及LoadBalancerInterceptor,另外主要配置的是loadBalancer的重试。重试功能主要通过spring retry组件的RetryTemplate来实现。

doc

  • Spring Cloud Finchley.RELEASE Documentation

聊聊spring cloud的LoadBalancerAutoConfiguration相关推荐

  1. 聊聊spring cloud gateway的GlobalFilter

    序 本文主要研究一下spring cloud gateway的GlobalFilter GatewayAutoConfiguration spring-cloud-gateway-core-2.0.0 ...

  2. 从架构演进的角度聊聊Spring Cloud都做了些什么?

    Spring Cloud作为一套微服务治理的框架,几乎考虑到了微服务治理的方方面面,之前也写过一些关于Spring Cloud文章,主要偏重各组件的使用,本次分享主要解答这两个问题:Spring Cl ...

  3. 聊聊Spring Cloud版本的那些事儿

    继续昨天说的计划,解惑一下收到比较多的问题. 有朋友问"为什么在很多文章中,大家引用的Spring版本名字都不一样呢?比如:Angel.SR6,Brixton.SR5等等,它们都有什么区别呢 ...

  4. 聊聊spring cloud gateway的PreserveHostHeaderGatewayFilter

    序 本文主要研究下spring cloud gateway的PreserveHostHeaderGatewayFilter GatewayAutoConfiguration spring-cloud- ...

  5. 聊聊spring cloud的DefaultEurekaServerContext

    序 本文主要研究一下spring cloud的DefaultEurekaServerContext EurekaServerAutoConfiguration @Configuration @Impo ...

  6. 聊聊 Spring Cloud Config

    一般服务器的应用都有以下几种类型, 其中当属业务部分最多也最繁杂. 当应用越来越庞大和复杂时,单机就肯定不能满足需求了,然后就要考虑分布式了,接下可能会应用不同的语言来开发应用. 比如 nginx 毫 ...

  7. 聊聊spring cloud gateway的SecureHeadersGatewayFilter

    序 本文主要研究下spring cloud gateway的SecureHeadersGatewayFilter GatewayAutoConfiguration @Configuration @Co ...

  8. 聊聊spring cloud gateway的XForwardedHeadersFilter

    序 本文主要研究spring cloud gateway的XForwardedHeadersFilter GatewayAutoConfiguration spring-cloud-gateway-c ...

  9. 聊聊spring cloud gateway的SetStatusGatewayFilter

    序 本文主要研究下spring cloud gateway的SetStatusGatewayFilter GatewayAutoConfiguration spring-cloud-gateway-c ...

最新文章

  1. 计算机产业深度报告:云计算与人工智能开启新一轮技术变革周期
  2. babel import语法 js_搭建开发JS库的运行环境
  3. 【caffe】OpenCV Load caffe model
  4. Java串口包Javax.comm的安装
  5. linux编程课后作业,Unix/Linux 编程实践教程第三章习题
  6. 认证令牌_Java应用程序的令牌认证
  7. 阿里云获全球第一张云安全国际认证金牌
  8. spring datasource oracle,spring中2种oracle数据源的配置
  9. iOS-单例设计模式
  10. 机器人能力再进化,组装宜家椅子只需20分钟! | Science Robotics论文
  11. mysqlbinlog抽取某个表的信息
  12. 手机html5编辑器哪个好,3款容易上手的HTML5编辑工具推荐~
  13. erroe C1083:无法打开包括文件(源文件)
  14. 算法:(BFS)迷宫寻路算法
  15. 在页面引入项目路径 ${webRoot}
  16. 四分位数计算方法总结
  17. hdu2177——威佐夫博弈变形
  18. 轻松搞定分组报表中的各种排序
  19. 破解这「七宗罪」,你才能晋升高级运营
  20. 【云原生 · Kubernetes】Kubernetes基础概念

热门文章

  1. 8个开发必备的PHP功能
  2. 解决jQuery和其它库的冲突
  3. (转)使.Net程序在未安装framework的电脑上运行(公布方法、源代码)
  4. 在Ubuntu上安装Odoo 11(企业版)
  5. mysql-mmm故障解决一例
  6. Android内存管理-OnTrimMemory
  7. Android MarsDaemon实现进程及Service常驻
  8. 这些技术人棒棒哒!BingoDay2017获奖名单新鲜出炉~~~
  9. HTML5地理定位用法
  10. httpClient多线程请求