SpringCloud--负载均衡

目录

前言

一.负载均衡的引入

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代码修改实现

@Service
public class StudentService {
    @Autowired
    StudentMapper studentMapper;
    @Autowired
    RestTemplate restTemplate;
    @Autowired
    private DiscoveryClient discoveryClient;

    // 计时器
    private static AtomicInteger atomicInteger = new AtomicInteger(1);
    private static List<ServiceInstance> instances;

    @PostConstruct
    public void init(){
        //根据应⽤名称获取服务列表
        instances = discoveryClient.getInstances("Teacher-service");
    }
    public StudentInfo getId(int id){
        StudentInfo studentInfo = studentMapper.getId(id);
        //每次都会自增!
        int index = atomicInteger.getAndIncrement() % instances.size();
        ServiceInstance instance = instances.get(index);
        String url = instance.getUri().toString()+"/Teacher/"+studentInfo.getClassroom();
        TeacherInfo teacherInfo = restTemplate.getForObject(url, TeacherInfo.class);
        studentInfo.setTeacherInfo(teacherInfo);
        return studentInfo;
    }
}

本次使用了计数器,将每次服务列表,轮播的进行负担,修改了Student-service的代码,让其每次访问不同的实例!分担压力。

二.负载均衡介绍

        负载均衡,就是指在高并发时,也就是服务流量增大时,通常会使用增加机器的方式进行扩容,而负载均衡,就是让多台机器按照一定规则合理分配负载。

而实现负载均衡的有:SpringCloud LoadBalancer

2.1实现负载均衡

        我们使用@LoadBalanced注解,修改的代码有:BeanConfig类以及StudentService类

BeanConfig类: 

@Configuration
public class BeanConfig {
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

StudentService类:

@Service
public class StudentService {
    @Autowired
    StudentMapper studentMapper;
    @Autowired
    RestTemplate restTemplate;

    public StudentInfo getId(int id){
        StudentInfo studentInfo = studentMapper.getId(id);
                                //一定和注册时的名字相同!
        String url = "http://Teacher-service/Teacher/"+studentInfo.getClassroom();
        TeacherInfo teacherInfo = restTemplate.getForObject(url, TeacherInfo.class);
        studentInfo.setTeacherInfo(teacherInfo);
        return studentInfo;
    }
}

启动测试:

测试结果:

2.2负载均衡策略

        负载均衡策略是⼀种思想, ⽆论是哪种负载均衡器, 它们的负载均衡策略都是相似的. Spring Cloud LoadBalancer 仅支持两种负载均衡策略: 轮询策略随机策略

  1. 轮询策略:一种简单的负载均衡算法,其核心思想是依次按顺序将请求分配给每个服务实例,当所有实例都被轮询过一遍后,再次从第一个实例开始。
  2. 随机策略:将每个请求随机分配给服务实例,每个实例被选中的概率是相等的。

轮询的缺点:如果服务实例的性能不均衡,轮询算法无法根据实际负载情况进行调整,可能导致某些实例负载过高。

随机的缺点:其随机性质,无法保证每个实例接收到的请求数量是均匀的,可能导致一些实例负载较高或较低。

SpringCloud LoadBalancer默认使用 轮询策略

随机策略

如果想实现随机策略,使用自定义策略:创建一个新的Config层的LoadBalancerConfig类:

import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.loadbalancer.core.RandomLoadBalancer;
import org.springframework.cloud.loadbalancer.core.ReactorLoadBalancer;
import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.core.env.Environment;

public class CustomLoadBalancerConfiguration {
    @Bean
    ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment,
                                                            LoadBalancerClientFactory loadBalancerClientFactory) {
        String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
        return new RandomLoadBalancer(loadBalancerClientFactory
                .getLazyProvider(name, ServiceInstanceListSupplier.class),
                name);
    }
}
该类需要满足:   不用  @Configuration 注释 ,在组件扫描范围内
修改BeanConfig类:
@LoadBalancerClient(name = "Teacher-service", configuration = RandomLoadBalancer.class)
@Configuration
public class BeanConfig {
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}
@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。

相关推荐

  1. SpringCloud】Ribbon负载均衡

    2024-07-21 17:06:02       38 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-21 17:06:02       138 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-21 17:06:02       152 阅读
  3. 在Django里面运行非项目文件

    2024-07-21 17:06:02       128 阅读
  4. Python语言-面向对象

    2024-07-21 17:06:02       140 阅读

热门阅读

  1. 手写简易版Spring IOC容器04【学习】

    2024-07-21 17:06:02       30 阅读
  2. 网络文件传输

    2024-07-21 17:06:02       27 阅读
  3. vue2获取视频时长

    2024-07-21 17:06:02       29 阅读
  4. mybatis中的useGeneratedKeys和keyProperty

    2024-07-21 17:06:02       26 阅读
  5. AI Agent的创新之路:AutoGen与LangGraph的比较

    2024-07-21 17:06:02       22 阅读
  6. Android笔试面试题AI答之Activity(3)

    2024-07-21 17:06:02       22 阅读
  7. 关闭终端后继续执行celery任务

    2024-07-21 17:06:02       25 阅读
  8. 学习C语言之 深入了解数据存储

    2024-07-21 17:06:02       21 阅读
  9. WordPress杂技

    2024-07-21 17:06:02       27 阅读
  10. 赞扬的10条原则

    2024-07-21 17:06:02       28 阅读
  11. WHAT - 贪心场景和算法实现

    2024-07-21 17:06:02       29 阅读