小工具知识网

当前位置: 首页 > 行业知识 > SpringCloud:spring-cloud-loadbalancer原理分析及实现自定义负载均衡策略

行业知识

SpringCloud:spring-cloud-loadbalancer原理分析及实现自定义负载均衡策略

2026-11-09 04:04:26 来源:互联网转载

文章目录

    • @[toc]
    • 一、Spring Cloud LoadBalancer原理
    • 二、LoadBalancer自定义负载均衡器
    • 其他

一、Spring Cloud LoadBalancer原理

LoadBalancerClient作为负载均衡客户端,用于进行负载均衡逻辑,从服务列表中选择出一个服务地址进行调用,其内部方法为下图显示:

在LoadBalancerClient种存在两个execute()方法,均是用来执行请求的,reconstructURI()是用来重构URL。对于LoadBalancerClient在Spring Cloud LoadBalancer中实现类则是BlockingLoadBalancerClient。BlockingLoadBalancerClient存在两个choose()方法,其实现的是图1-1中的ServiceInstanceChooser接口种的两个choose()方法(图1-2):

在上述图片中通过通过工厂类LoadBalancerClientFactory获取具体的负载均衡器实例,后面的loadBalancer.choose(request)调用(图1-3)接口choose()方法实现根据负载均衡算法选择下一个服务器完成负载均衡。

图1-3可以看出ReactorLoadBalancer接口继承ReactiveLoadBalancer接口,ReactorLoadBalancer接口后续又被ReactorServiceInstanceLoadBalancer继承且其实现了两个方法,分别是:RandomLoadBalancer(随机负载均衡器)和RoundRobinLoadBalancer(轮询负载均衡器)。

二、LoadBalancer自定义负载均衡器

根据图1-4类图显示,我们只需要在自定义配置轮询方法时重定义ReactorServiceInstanceLoadBalancer接口即可,如下例子:

@Configurationpublic class MyLoadBalancerConfig {    @Bean    public ReactorServiceInstanceLoadBalancer reactorServiceInstanceLoadBalancer(Environment environment, LoadBalancerClientFactory loadBalancerClientFactory) {        String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);        //返回随机轮询负载均衡方式        return new RandomLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);    }}

但是如果我们要自定义轮询算法该如何做呢?根据上面可以知道LoadBalancerClientFactory是创建客户机、负载均衡器和客户机配置实例的工厂。它根据客户端名称创建一个Spring ApplicationContext,并从中提取所需的bean(官方解释)。因此我们进入到LoadBalancerClientFactory类中:

我们需要去实现它的子接口ReactorServiceInstanceLoadBalancer,因为去获取负载均衡器实例的时候,是通过去容器中查找ReactorServiceInstanceLoadBalancer类型的bean来实现的,参照RandomLoadBalancer我们进行仿写

public class CustomRandomLoadBalancerClient implements ReactorServiceInstanceLoadBalancer {     // 服务列表    private ObjectProvider serviceInstanceListSupplierProvider;     public CustomRandomLoadBalancerClient(ObjectProvider serviceInstanceListSupplierProvider) {        this.serviceInstanceListSupplierProvider = serviceInstanceListSupplierProvider;    }     @Override    public Mono choose(Request request) {        ServiceInstanceListSupplier supplier = serviceInstanceListSupplierProvider.getIfAvailable();        return supplier.get().next().map(this::getInstanceResponse);    }     /**     * 使用随机数获取服务     * @param instances     * @return     */    private Response getInstanceResponse(            List instances) {        System.out.println("进来了");        if (instances.isEmpty()) {            return new EmptyResponse();        }         System.out.println("进行随机选取服务");        // 随机算法        int size = instances.size();        Random random = new Random();        ServiceInstance instance = instances.get(random.nextInt(size));         return new DefaultResponse(instance);    }}

自定义配置类:

@Configurationpublic class MyLoadBalancerConfig {     // 参数 serviceInstanceListSupplierProvider 会自动注入    @Bean    public ReactorServiceInstanceLoadBalancer customLoadBalancer(ObjectProvider serviceInstanceListSupplierProvider) {        return new CustomRandomLoadBalancerClient(serviceInstanceListSupplierProvider);    }}

在项目启动类上添加@LoadBalancerClient注解:name值一定要使用服务端配置的服务名(spring.application.name),通过configuration指定自定义的配置

@SpringBootApplication@LoadBalancerClient(name = "myServer", configuration = MyLoadBalancerConfig.class)public class BlockClientApplication {     public static void main(String[] args) {        SpringApplication.run(BlockClientApplication.class, args);    }}

其他

参考:https://www.cnblogs.com/linchenguang/p/15656603.html

https://blog.csdn.net/weixin_50518271/article/details/111449560

https://blog.csdn.net/qq_31142237/article/details/90486836

上一篇:轻松下载应用助手,一站式教程详解!

下一篇:百度地图怎么制作?