Ribbon使用

ribbon在使用上非常简单,仅仅只sql教程需要在配置类上加入配置即可

    @Bean@LoadBalancedpublic RestTemplate restTemplate(){return new RestTemplate();}

调用时,直接使用在eureka中注册的服务java基础教程名进行调用,就可以由ribbon来进行负载均衡了

    @GetMapping("/checkAndBegin/{userId}")public Integer findResumeOpenStateEureka(@PathVariable Long userId) {
//        List<ServiceInstance> list = discoveryClient.getInstances("lagou-service-resume");
//        ServiceInstance serviceInstance = list.get(0);
//        String host = serviceInstance.getHost();
//        int port = serviceInstance.getPort();String url = "http://zhao-service-resume/resume/openstate/"+userId;System.out.println("从eureka中获取了请求地址"+url);Integer forObject =restTemplate.getForObject(url, Integer.class);return forObject;}

根据要求,zhao-service-resume项目开启多个,并打印请python基础教程求信息,即可发现负载均衡已经实现
另外目前Ribbon的内置负载均衡策略

目前默认使用的是随机负载均衡RandomRule,默认全局生效,但是可以针对不同c#教程的调用服务设置不同的负载均衡策略

zhao-service-resume:ribbon:NFLoadBalancerRuleClassName:
com.netflix.loadbalancer.RandomRule #负载策略调整

同时,可以自定负载均衡策略vb.net教程并配置

Ribbon源码分析

一般而言,自动装配类就是加载配置的入口。

@Configuration
@Conditional(RibbonAutoConfiguration.RibbonClassesConditions.class)
@RibbonClients
@AutoConfigureAfter(name = "org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration")
@AutoConfigureBefore({LoadBalancerAutoConfiguration.class, AsyncLoadBalancerAutoConfiguration.class})
@EnableConfigurationProperties({RibbonEagerLoadProperties.class, ServerIntrospectorProperties.class})
public class RibbonAutoConfiguration {
}

通过上述配置,我们可以先看看LoadBalancerAutoConfiguration的具体内容

 @LoadBalanced@Autowired(required = false)private List<RestTemplate> restTemplates = Collections.emptyList();

此处将自动注入添加了@LoadBalanced注解的RestTemplate对象
同时还注入了一个RestTemplate的定制器RestTemplateCustomizer

 @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);}}});}

继续进入RestTemplateCustomizer的定制器代码,我们发现在定制器中加入了一个拦截器

@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);};}}

ClientHttpRequestInterceptor的拦截具体内容为,根据获取到的请求路径和请求地址进行负载均衡

 @Overridepublic ClientHttpResponse intercept(final HttpRequest request, final byte[] body,final ClientHttpRequestExecution execution) throws IOException {final URI originalUri = request.getURI();String serviceName = originalUri.getHost();Assert.state(serviceName != null, "Request URI does not contain a valid hostname: " + originalUri);return this.loadBalancer.execute(serviceName, requestFactory.createRequest(request, body, execution));}

执行负载均衡的代码

 public <T> T execute(String serviceId, LoadBalancerRequest<T> request, Object hint) throws IOException {ILoadBalancer loadBalancer = getLoadBalancer(serviceId);Server server = getServer(loadBalancer, hint);if (server == null) {throw new IllegalStateException("No instances available for " + serviceId);}RibbonServer ribbonServer = new RibbonServer(serviceId, server, isSecure(server,serviceId), serverIntrospector(serviceId).getMetadata(server));return execute(serviceId, ribbonServer, request);}

从这段代码可以看出,第一行根据配置,选出相应的负载均衡策略。第二行就是根据相应的负载均衡策略选择一个服务端进行服务请求,达到负载均衡的目的
最后在BaseLoadBalancer中执行了根据不同的策略选择服务的操作

    public Server chooseServer(Object key) {if (counter == null) {counter = createCounter();}counter.increment();if (rule == null) {return null;} else {try {return rule.choose(key);} catch (Exception e) {logger.warn("LoadBalancer [{}]:  Error choosing server for key {}", name, key, e);return null;}}}

考虑完了上面的主逻辑之后,还有一个问题,就是服务列表是什么时候获取到的。
在RibbonAutoConfigration中注入了SpringClientFactory,而SpringClientFactory又注入了RibbonClientConfiguration

 public SpringClientFactory() {super(RibbonClientConfiguration.class, NAMESPACE, "ribbon.client.name");}

RibbonClientConfiguration中进行了注入客户端操作的相关操作,包括负载均衡策略,客户端配置,服务列表等,其中最重要的就是如何获取和更新服务列表

 @ConditionalOnMissingBean@SuppressWarnings("unchecked")public ServerList<Server> ribbonServerList(IClientConfig config) {if (this.propertiesFactory.isSet(ServerList.class, name)) {return this.propertiesFactory.get(ServerList.class, config, name);}ConfigurationBasedServerList serverList = new ConfigurationBasedServerList();serverList.initWithNiwsConfig(config);return serverList;}@Bean@ConditionalOnMissingBeanpublic ServerListUpdater ribbonServerListUpdater(IClientConfig config) {return new PollingServerListUpdater(config);}@Bean@ConditionalOnMissingBeanpublic ILoadBalancer ribbonLoadBalancer(IClientConfig config,ServerList<Server> serverList, ServerListFilter<Server> serverListFilter,IRule rule, IPing ping, ServerListUpdater serverListUpdater) {if (this.propertiesFactory.isSet(ILoadBalancer.class, name)) {return this.propertiesFactory.get(ILoadBalancer.class, config, name);}return new ZoneAwareLoadBalancer<>(config, rule, ping, serverList,serverListFilter, serverListUpdater);}

在ribbonList方法中并未有获取serverList的操作,在ribbonLoadBalancer中进行了使用,那么究竟怎么一回事呢?实际上是在ZoneAwareLoadBalancer的父类DynamicServerListLoadBalancer中进行了重新的赋值并且执行了定时任务进行更新。

    void restOfInit(IClientConfig clientConfig) {boolean primeConnection = this.isEnablePrimingConnections();// turn this off to avoid duplicated asynchronous priming done in BaseLoadBalancer.setServerList()this.setEnablePrimingConnections(false);enableAndInitLearnNewServersFeature();updateListOfServers();if (primeConnection && this.getPrimeConnections() != null) {this.getPrimeConnections().primeConnections(getReachableServers());}this.setEnablePrimingConnections(primeConnection);LOGGER.info("DynamicServerListLoadBalancer for client {} initialized: {}", clientConfig.getClientName(), this.toString());}

首先通过updateAction.doUpdate();更新,然后通过getRefreshExecutor()进行获取

 @Overridepublic synchronized void start(final UpdateAction updateAction) {if (isActive.compareAndSet(false, true)) {final Runnable wrapperRunnable = new Runnable() {@Overridepublic void run() {if (!isActive.get()) {if (scheduledFuture != null) {scheduledFuture.cancel(true);}return;}try {updateAction.doUpdate();lastUpdated = System.currentTimeMillis();} catch (Exception e) {logger.warn("Failed one update cycle", e);}}};scheduledFuture = getRefreshExecutor().scheduleWithFixedDelay(wrapperRunnable,initialDelayMs,refreshIntervalMs,TimeUnit.MILLISECONDS);} else {logger.info("Already active, no-op");}}

欢迎搜索关注本人与朋友共同开发的微信面经小程序【大厂面试助手】和公众号【微瞰技术】,以及总结的分类面试题https://github.com/zhendiao/JavaInterview

Ribbon负载均衡分析相关推荐

  1. SpringCloud源码:Ribbon负载均衡分析

    本文主要分析 SpringCloud 中 Ribbon 负载均衡流程和原理. SpringCloud版本为:Edgware.RELEASE. 一.时序图 和以前一样,先把图贴出来,直观一点: 二.源码 ...

  2. JavaEE进阶知识学习-----SpringCloud(六)Ribbon负载均衡

    Ribbon负载均衡 Ribbon概述 Spring Cloude Ribbon是基于Netfilx Ribbon实现的一套客户端 负载均衡的工具,简单说,Ribbon是Netfilix发布的开源项目 ...

  3. SpringCloud[04]Ribbon负载均衡服务调用

    文章目录 Ribbon负载均衡服务调用 1. 概述 1. Ribbon是什么 2. Ribbon能做什么 2. Ribbon负载均衡演示 1. 架构说明 2. Ribbon的POM依赖 3. Rest ...

  4. spring cloud中通过配置文件自定义Ribbon负载均衡策略

    2019独角兽企业重金招聘Python工程师标准>>> spring cloud中通过配置文件自定义Ribbon负载均衡策略 博客分类: 微服务 一.Ribbon中的负载均衡策略 1 ...

  5. SpringCloud:Ribbon负载均衡(基本使用、 负载均衡、自定义配置、禁用 Eureka 实现 Ribbon 调用)

    现在所有的服务已经通过了 Eureka 进行了注册,那么使用 Eureka 注册的目的是希望所有的服务都统一归属到 Eureka 之中进 行处理,但是现在的问题,所有的微服务汇集到了 Eureka 之 ...

  6. 详解Eureka服务注册与发现和Ribbon负载均衡【纯理论实战】

    Eureka服务注册与发现 Eureka简介 在介绍Eureka前,先说一下CAP原则 CAP原则又称CAP定理,指的是在一个分布式系统中,Consistency(一致性). Availability ...

  7. 最新版Spring Cloud Alibaba微服务架构-Ribbon负载均衡篇

    文章目录 前言 一.Ribbon核心概念 二.服务器端负载均衡和Riboon客户端负载均衡 1.服务器端负载均衡: 2.Riboon客户端负载均衡: 三.Ribbon策略 四.Ribbon配置使用 五 ...

  8. Ribbon负载均衡原理,Feign是如何整合Ribbon的?

    文章目录 1. 什么是负载均衡? 2. Ribbon的使用 ①:自定义负载均衡策略 ②:Ribbon的饥饿加载 3. Ribbon的负载均衡原理 ①:收集带有@LoadBalanced注解的RestT ...

  9. SpringCloud的Ribbon负载均衡

    Spring Cloud Ribbon相关学习: 简介 Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具. 简单的说,Ribbon是Netflix ...

  10. SpringCloud系列五:Ribbon 负载均衡(Ribbon 基本使用、Ribbon 负载均衡、自定义 Ribbon 配置、禁用 Eureka 实现 Ribbon 调用)...

    声明:本文来源于MLDN培训视频的课堂笔记,写在这里只是为了方便查阅. 1.概念:Ribbon 负载均衡 2.具体内容 现在所有的服务已经通过了 Eureka 进行了注册,那么使用 Eureka 注册 ...

最新文章

  1. tf.keras.activations.softmax 激活函数 示例
  2. SpringBoot下的模板技术Thymeleaf详解
  3. cocos2d-x for android配置 运行 Sample on Linux OS
  4. TCP第四次挥手为什么要等待2MSL
  5. C# 中 NPOI 库读写 Excel 文件的方法【摘】
  6. 协鑫集成携中国成套工程在核灾区建立1GW光伏电站
  7. 数学建模 聚类模型
  8. 智能一代云平台(三十三):log4j日志研究
  9. 自动化CodeReview - ASP.NET Core请求参数验证
  10. [转载]幂等和高并发在电商系统中的使用
  11. apache 支持.htaccess 解决Internal Server Error The server 错误
  12. 挑战程序设计竞赛(第一章)
  13. LCD1602A模块的应用
  14. 一个粗糙的js分页判断
  15. SQL Server 监视(Monitoring)体系架构
  16. Spring Cloud实战(二)-Spring Cloud Eureka
  17. 前端——面试(苏小妍)
  18. 【量化交易】 量化因子 情绪类因子计算
  19. ipad服务器的显示器,Air Display怎么用 iPad怎么分屏显示 值得收藏
  20. 企业怎样顺利实施ERP管理系统?

热门文章

  1. 简单echars Demo
  2. 网站卡死服务器2008,winserver2008r2频繁卡死?
  3. 交换友情链接要怎么做才能完美
  4. 输出1234无重复三位数
  5. Guava基本工具包Base:Null和字符串分割(Splitter)、拼接(Joiner)处理
  6. openpyxl创建excel工作表
  7. ES文件浏览器ftp文件共享,通过电脑访问手机文件夹传输文件
  8. Rust 编译模型之殇
  9. DCM protocol Diagnostic session
  10. Windows 7远程桌面 重启 关机 任务管理器 命令