05-LoadBalancer负载平衡

打印 上一主题 下一主题

主题 888|帖子 888|积分 2668

1.Ribbon目前也进入维护模式

1.1 Ribbon介绍

Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载平衡的工具。
简朴的说,Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载平衡算法和服务调用。Ribbon客户端组件提供一系列完善的配置项如连接超时,重试等。简朴的说,就是在配置文件中列出Load Balancer(简称LB)反面所有的机器,Ribbon会自动的帮助你基于某种规则(如简朴轮询,随机连接等)去连接这些机器。我们很轻易使用Ribbon实现自定义的负载平衡算法。
https://github.com/Netflix/ribbon
1.2 Ribbon替代方案


spring-cloud-loadbalancer
2.spring-cloud-loadbalancer概述

2.1 官网


2.2 是什么

LB负载平衡(Load Balance)是什么
简朴的说就是将用户的哀求平摊的分配到多个服务上,从而达到系统的HA(高可用),常见的负载平衡有软件Nginx,LVS,硬件F5等
spring-cloud-starter-loadbalancer组件是什么
Spring Cloud LoadBalancer是由SpringCloud官方提供的一个开源的、简朴易用的客户端负载平衡器,它包含在SpringCloud-commons中用它来替换了以前的Ribbon组件。相比较于Ribbon,SpringCloud LoadBalancer不仅能够支持RestTemplate,还支持WebClient(WeClient是Spring Web Flux中提供的功能,可以实现响应式异步哀求)。

https://docs.spring.io/spring-cloud-commons/reference/spring-cloud-commons/loadbalancer.html
2.3 面试题

loadbalancer本地负载平衡客户端 VS Nginx服务端负载平衡区别
Nginx是服务器负载平衡,客户端所有哀求都会交给nginx,然后由nginx实现转发哀求,即负载平衡是由服务端实现的。
loadbalancer本地负载平衡,在调用微服务接口时候,会在注册中心上获取注册信息服务列表之后缓存到JVM本地,从而在本地实现RPC长途服务调用技术。
个人明白,客户端负载平衡,是由客户端,选择向那台机器发起哀求,并得到响应。而服务端负载平衡,是由服务器端(nginx),决定某个哀求,由那台机器处理处罚,然后响应给客户端。
3.spring-cloud-loadbalancer负载平衡剖析

3.1 理论


LoadBalancer 在工作时分成两步:
第一步,先选择ConsulServer从服务端查询并拉取服务列表,知道了它有多个服务(上图3个服务),这3个实现是完全一样的,
默认轮询调用谁都可以正常执行。类似生存中求医挂号,某个科室今日出诊的全部医生,客户端你自己选一个。
第二步,按照指定的负载平衡策略从server取到的服务注册列表中由客户端自己选择一个地点,所以LoadBalancer是一个客户端的负载平衡器。
3.2 实操

3.2.1 官网参考如何正确使用

https://docs.spring.io/spring-cloud-commons/reference/spring-cloud-commons/loadbalancer.html


3.2.2 按照8001拷贝新建8002


3.2.3 启动Consul,然后启动8001和8002

启动Consul
  1. consul agent -dev
复制代码
获取在consul中配置的测试信息,通过8001或8002接口

bug
在consul中的配置重启后,消失了
3.2.4 Consul数据持久化配置并注册为Window服务

1.在consul.exe的同级目录下,新建mydata文件夹
2.新建consul_start.bat文件
  1. @echo.Consul Start......  
  2. @echo off  
  3. @sc create Consul binpath= "D:\Develop\consul\consul.exe agent -server -ui -bind=127.0.0.1 -client=0.0.0.0 -bootstrap-expect  1  -data-dir D:\Develop\consul\mydata   "
  4. @net start Consul
  5. @sc config Consul start= AUTO  
  6. @echo.Consul start is OK......success
  7. @pause
复制代码
3.管理员权限打开
4.启动结果

5.win后台
会多出consul服务
6.后续consul的配置数据会保存到mydata文件夹
3.2.5 修改Order模块

1.引入依靠
  1. <dependency>
  2.     <groupId>org.springframework.cloud</groupId>
  3.     <artifactId>spring-cloud-starter-loadbalancer</artifactId>
  4. </dependency>
复制代码
2.新增接口
  1. @GetMapping(value = "/consumer/pay/get/info")
  2. public  String getInfoByConsul() {
  3.     return restTemplate.getForObject(PAYMENT_SRV_URL + "/pay/get/info", String.class);
  4. }
复制代码
3.consul服务

4.测试
http://localhost:8080/consumer/pay/get/info
访问改接口,可见交替访问8001和8002
3.3 小总结

3.3.1 使用DiscoveryClient动态获取上线的服务列表


3.3.2 订单模块新增代码
  1. @Resource
  2. private DiscoveryClient discoveryClient;
  3. @GetMapping("/discovery")
  4. public String discovery() {
  5.     //获取所有的consul中的服务名
  6.     List<String> services = discoveryClient.getServices();
  7.     for (String element : services) {
  8.         System.out.println(element);
  9.     }
  10.     System.out.println("===================================");
  11.         //获取key服务的所有服务实例
  12.     List<ServiceInstance> instances = discoveryClient.getInstances("cloud-payment-service");
  13.     for (ServiceInstance element : instances) {
  14.         //服务实例名 + 服务主机名 + 服务端口号 + 服务url
  15.         System.out.println(element.getServiceId() + "\t" + element.getHost() + "\t" + element.getPort() + "\t" + element.getUri());
  16.     }
  17.     return instances.get(0).getServiceId() + ":" + instances.get(0).getPort();
  18. }
复制代码
输出信息
  1. cloud-consumer-order
  2. cloud-payment-service
  3. consul
  4. ===================================
  5. cloud-payment-service        x        8001        http://x:8001 x是主机名
  6. cloud-payment-service        x        8002         http://x:8002
复制代码
3.3.3 负载平衡原理小总结
负载平衡算法:rest接口第频频哀求数 % 服务器集群总数目 = 实际调用服务器位置下标 ,每次服务重启动后rest接口计数从1开始。
  1. List<ServiceInstance> instances = discoveryClient.getInstances("cloud-payment-service");
  2. //如
  3. List [0] instances = 127.0.0.1:8002
  4. List [1] instances = 127.0.0.1:8001
复制代码
8001+ 8002 组合成为集群,它们共计2台机器,集群总数为2, 按照轮询算法原理:
当总哀求数为1时: 1 % 2 =1 对应下标位置为1 ,则得到服务地点为127.0.0.1:8001
当总哀求数位2时: 2 % 2 =0 对应下标位置为0 ,则得到服务地点为127.0.0.1:8002
当总哀求数位3时: 3 % 2 =1 对应下标位置为1 ,则得到服务地点为127.0.0.1:8001
当总哀求数位4时: 4 % 2 =0 对应下标位置为0 ,则得到服务地点为127.0.0.1:8002
如此类推......
4.负载平衡算法原理

4.1 默认算法,有几种

4.1.1 官网

https://docs.spring.io/spring-cloud-commons/reference/spring-cloud-commons/loadbalancer.html#switching-between-the-load-balancing-algorithms
4.1.2 默认两种


轮询
  1. public class RoundRobinLoadBalancer implements ReactorServiceInstanceLoadBalancer
复制代码
随机
  1. public class RoundRobinLoadBalancer implements ReactorServiceInstanceLoadBalancer
复制代码
源码
略,见org.springframework.cloud.client.loadbalancer.reactive.ReactiveLoadBalancer接口
4.2 算法切换
  1. @LoadBalancerClient(value = "cloud-payment-service",configuration = RestTemplateConfig.class)
  2. public class RestTemplateConfig {
  3.     @Bean
  4.     @LoadBalanced
  5.     public RestTemplate restTemplate(){
  6.         return new RestTemplate();
  7.     }
  8.     @Bean
  9.     ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment,
  10.                                                             LoadBalancerClientFactory loadBalancerClientFactory) {
  11.         String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
  12.         return new RandomLoadBalancer(loadBalancerClientFactory
  13.                 .getLazyProvider(name, ServiceInstanceListSupplier.class),
  14.                 name);
  15.     }
  16. }
复制代码
The classes you pass as @LoadBalancerClient or @LoadBalancerClients configuration arguments should either not be annotated with @Configuration or be outside component scan scope.
在RestTemplateConfig的类上,有@LoadBalancerClient或者@LoadBalancerClients,就不该在使用@Configuration注解了,包含了。
  1. Configuration(proxyBeanMethods = false)
  2. @Import(LoadBalancerClientConfigurationRegistrar.class)
  3. @Target(ElementType.TYPE)
  4. @Retention(RetentionPolicy.RUNTIME)
  5. @Documented
  6. public @interface LoadBalancerClient
复制代码
  1. @Configuration(proxyBeanMethods = false)
  2. @Retention(RetentionPolicy.RUNTIME)
  3. @Target({ ElementType.TYPE })
  4. @Documented
  5. @Import(LoadBalancerClientConfigurationRegistrar.class)
  6. public @interface LoadBalancerClients
复制代码
只是为了记录自己的学习历程,且本人水平有限,不对之处,请指正。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

刘俊凯

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表