SpringCloud--负载平衡

打印 上一主题 下一主题

主题 1807|帖子 1807|积分 5421

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

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

x
目次
前言
一.负载平衡的引入
1.1问题引入 
1.2代码修改实现
二.负载平衡介绍
2.1实现负载平衡
2.2负载平衡计谋
2.3LoadBalancer 原理

   

  学习专栏:http://t.csdnimg.cn/tntwg
  
前言

        在前面的Eureka当中,我们固然实现了从注册中心中获取url,然后再与其他服务器进行交互!获取资源。
Eureka学习地址链接:http://t.csdnimg.cn/MPyJJ
一.负载平衡的引入

1.1问题引入 

        在SpringcloudEureka当中,我们学习到了怎样获取,但是叨教,如果有多台客户端同时哀求这个数据呢?那我们又应该怎样应对呢?
例子:我们可以进行多次访问TeacherService,全部访问同一个Teacher-service服务器,那么怎样减轻他的负担呢?,方法:


固然启动了多个实例,但是访问依然还是同一个呆板,没有分担负荷!因此我们需要修改之前的代码!
1.2代码修改实现

  1. @Service
  2. public class StudentService {
  3.     @Autowired
  4.     StudentMapper studentMapper;
  5.     @Autowired
  6.     RestTemplate restTemplate;
  7.     @Autowired
  8.     private DiscoveryClient discoveryClient;
  9.     // 计时器
  10.     private static AtomicInteger atomicInteger = new AtomicInteger(1);
  11.     private static List<ServiceInstance> instances;
  12.     @PostConstruct
  13.     public void init(){
  14.         //根据应⽤名称获取服务列表
  15.         instances = discoveryClient.getInstances("Teacher-service");
  16.     }
  17.     public StudentInfo getId(int id){
  18.         StudentInfo studentInfo = studentMapper.getId(id);
  19.         //每次都会自增!
  20.         int index = atomicInteger.getAndIncrement() % instances.size();
  21.         ServiceInstance instance = instances.get(index);
  22.         String url = instance.getUri().toString()+"/Teacher/"+studentInfo.getClassroom();
  23.         TeacherInfo teacherInfo = restTemplate.getForObject(url, TeacherInfo.class);
  24.         studentInfo.setTeacherInfo(teacherInfo);
  25.         return studentInfo;
  26.     }
  27. }
复制代码
本次使用了计数器,将每次服务列表,轮播的进行负担,修改了Student-service的代码,让其每次访问不同的实例!分担压力。
二.负载平衡介绍

        负载平衡,就是指在高并发时,也就是服务流量增大时,通常会使用增长呆板的方式进行扩容,而负载平衡,就是让多台呆板按照一定规则合理分配负载。
而实现负载平衡的有:SpringCloud LoadBalancer
2.1实现负载平衡

        我们使用@LoadBalanced注解,修改的代码有:BeanConfig类以及StudentService类
BeanConfig类: 
  1. @Configuration
  2. public class BeanConfig {
  3.     @Bean
  4.     @LoadBalanced
  5.     public RestTemplate restTemplate(){
  6.         return new RestTemplate();
  7.     }
  8. }
复制代码
StudentService类:
  1. @Service
  2. public class StudentService {
  3.     @Autowired
  4.     StudentMapper studentMapper;
  5.     @Autowired
  6.     RestTemplate restTemplate;
  7.     public StudentInfo getId(int id){
  8.         StudentInfo studentInfo = studentMapper.getId(id);
  9.                                 //一定和注册时的名字相同!
  10.         String url = "http://Teacher-service/Teacher/"+studentInfo.getClassroom();
  11.         TeacherInfo teacherInfo = restTemplate.getForObject(url, TeacherInfo.class);
  12.         studentInfo.setTeacherInfo(teacherInfo);
  13.         return studentInfo;
  14.     }
  15. }
复制代码
启动测试:

测试结果:




2.2负载平衡计谋

        负载平衡计谋是⼀种头脑, ⽆论是哪种负载平衡器, 它们的负载平衡计谋都是相似的. Spring Cloud LoadBalancer 仅支持两种负载平衡计谋: 轮询计谋 和 随机计谋

  • 轮询计谋:一种简朴的负载平衡算法,其焦点头脑是依次按顺序将哀求分配给每个服务实例,当全部实例都被轮询过一遍后,再次从第一个实例开始。
  • 随机计谋:将每个哀求随机分配给服务实例,每个实例被选中的概率是相称的。
轮询的缺点:如果服务实例的性能不平衡,轮询算法无法根据实际负载环境进行调整,可能导致某些实例负载过高。
随机的缺点:其随机性子,无法保证每个实例接收到的哀求数量是均匀的,可能导致一些实例负载较高或较低。
SpringCloud LoadBalancer默认使用 轮询计谋
随机计谋
如果想实现随机计谋,使用自定义计谋:创建一个新的Config层的LoadBalancerConfig类:
  1. import org.springframework.cloud.client.ServiceInstance;
  2. import org.springframework.cloud.loadbalancer.core.RandomLoadBalancer;
  3. import org.springframework.cloud.loadbalancer.core.ReactorLoadBalancer;
  4. import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
  5. import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
  6. import org.springframework.context.annotation.Bean;
  7. import org.springframework.core.env.Environment;
  8. public class CustomLoadBalancerConfiguration {
  9.     @Bean
  10.     ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment,
  11.                                                             LoadBalancerClientFactory loadBalancerClientFactory) {
  12.         String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
  13.         return new RandomLoadBalancer(loadBalancerClientFactory
  14.                 .getLazyProvider(name, ServiceInstanceListSupplier.class),
  15.                 name);
  16.     }
  17. }
复制代码
  该类需要满足:      不消   @Configuration   注释 ,在组件扫描范围内    修改BeanConfig类:
  1. @LoadBalancerClient(name = "Teacher-service", configuration = RandomLoadBalancer.class)@Configuration
  2. public class BeanConfig {
  3.     @Bean
  4.     @LoadBalanced
  5.     public RestTemplate restTemplate(){
  6.         return new RestTemplate();
  7.     }
  8. }
复制代码
  @LoadBalancerClient   注解:  

  • name: 负载平衡对哪个服务生效
  • configuration:使用哪个负载平衡器
注:如果没有为 product-service 指定自定义的负载平衡配置类 (LoadBalancerConfig.class),则 RestTemplate 默认会使用 Ribbon 提供的轮询(Round-Robin)计谋来进行服务实例的选择和哀求的负载平衡。
2.3LoadBalancer 原理

        或许有人问,为什么我加一个注解@LoadBalanced就可以实现负载平衡呢?
原因: 


  • Ribbon:Spring Cloud Ribbon 是一个基于 HTTP 和 TCP 客户端的负载平衡器。当你在 RestTemplate 上添加 @LoadBalanced 注解时,Spring Cloud Ribbon 会为 RestTemplate 创建一个动态代理,在发送哀求前拦截哀求,通过负载平衡算法选择合适的服务实例进行哀求发送。
  • @LoadBalanced 注解会为 RestTemplate 添加一个拦截器(interceptor),这个拦截器会在哀求发送前根据 Ribbon 的负载平衡计谋选择一个服务实例。Ribbon 默认的负载平衡计谋是轮询(Round-Robin),但你也可以通过配置修改为其他计谋,如随机、加权等。
   总结:对   RestTemplate   的哀求进行拦截, 然后从Eureka根据服务id获取服务列表,随后利⽤负载平衡算法得到真实的服务地址信息,更换服务id。   


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

使用道具 举报

0 个回复

倒序浏览

快速回复

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

本版积分规则

莫张周刘王

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表