SpringCloud: реализация собственной стратегии балансировки нагрузки Spring-cloud-loadbalancer
SpringCloud: реализация собственной стратегии балансировки нагрузки Spring-cloud-loadbalancer

Введение

Онлайн-видео и блоги в основном реализованы с использованием зависимости Spring-cloud-starter-netflix-ribbon, но Springcloud удалил netflix-ribbon после версии 2020.0.0. Используйте балансировщик нагрузки в eureka-client, используйте пользовательскую балансировку нагрузка не использует интерфейс IRule, поэтому возникло много проблем, но здесь мы также рассмотрим традиционную реализацию. О реализации нового метода мы поговорим позже. Конечно, вы также можете сразу перейти к 2. Реализуйте с помощью LoadBalancer Непосредственно прочтите использование новых методов.

1. Реализация с использованием интерфейса IRule.

1. Импортируйте зависимости Maven.
Язык кода:javascript
копировать
<dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-ribbon</artifactId>
     <version>1.4.6.RELEASE</version>
</dependency>
<dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-eureka</artifactId>
     <version>1.4.6.RELEASE</version>
</dependency>
2.yml конфигурация
Язык кода:javascript
копировать
server:
  port: 80

# EurekaКонфигурация
eureka:
  client:
    register-with-eureka: false #Не регистрироваться в эврике, по умолчанию true, false означает отсутствие регистрации (зарегистрировано провайдером)
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
    fetch-registry: true    #Указывает, начинать ли с Эврики Сервер получает зарегистрированную информацию Служить, по умолчанию — true, false означает не получать
3. Используйте алгоритм балансировки нагрузки, настроенный Springcloud.

Всего существует 7 конфигураций по умолчанию. Если мы не укажем это, по умолчанию используется алгоритм опроса, что означает, что поставщик запросов работает по очереди.

[Не удалось передать изображение по внешней ссылке. Исходный сайт может иметь механизм защиты от кражи. Рекомендуется сохранить изображение и загрузить его напрямую (img-U1PTQApm-1687860407286) (C:\Users\86186\AppData\Roaming\Typora\. typora-user-images\ image-20230509142142361.png)]

Например, мы можем напрямую ввести следующий код в любой класс конфигурации, чтобы заставить действовать поставщика требований произвольного доступа и стратегию балансировки:

Язык кода:javascript
копировать
@Bean
public IRule myRule(){
    return new RandomRule();
}

В настоящее время, когда вы посещаете http://localhost/consumer/list несколько раз, вы можете видеть, что данные, к которым осуществляется доступ каждый раз, появляются случайным образом, что указывает на то, что эта стратегия вступила в силу.

Что, если мы хотим настроить?

4. Индивидуальный алгоритм балансировки нагрузки.

На данный момент лучше всего написать соответствующий класс конфигурации отдельно, но следует отметить одну вещь: напрямую процитировать официальное предложение Springcloud:

Класс CustomConfiguration должен быть классом @Configuration, но учтите, что его нет в @ComponentScan для основного контекста приложения. В противном случае он используется всеми @RibbonClients. Если вы используете @ComponentScan (или @SpringBootApplication), вам необходимо принять меры, чтобы избежать его включения (например, вы можете поместить его в отдельный непересекающийся пакет или указать, что он должен быть включен в @ComponentScan).

Язык кода:javascript
копировать
Файл MengRandomRule.java:

import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;

import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

public class MengRandomRule extends AbstractLoadBalancerRule {
    public MengRandomRule() {
    }
    // 📢Обратите внимание, что две переменные здесь должны быть установлены как глобальные переменные.
    // Посетите каждую Служить 5 раз, а затем замените на следующую Служить (3 шт.)
    // total= 0, по умолчанию 0, если 5, заменяем на следующий Служить
    // индекс=0, по умолчанию 0, если итог=5, индекс+1
    private int total = 0;// сколько раз звонили
    private int currentIndex = 0; // Кто в настоящее время предоставляет Служить

    public Server choose(ILoadBalancer lb, Object key) {
        if (lb == null) {
            return null;
        } else {
            Server server = null;
    
            while(server == null) {
                if (Thread.interrupted()) {
                    return null;
                }
    
                List<Server> upList = lb.getReachableServers();// Живи Служить
                List<Server> allList = lb.getAllServers();// Получить все
                int serverCount = allList.size();
                if (serverCount == 0) {
                    return null;
                }

//                int index = this.chooseRandomInt(serverCount);// Генерация интервальных случайных чисел
//                server = (Server)upList.get(index);// Получить случайное из живого Служить

                //========================================================
                //Часть, обернутая знаком равенства, является пользовательским правилом. Что касается другой части, то она фактически вычитается непосредственно из исходного кода. Просто измените эту часть, это очень просто!
                if(total<5){
                    server = upList.get(currentIndex);
                    total++;
                }else{
                    total=0;
                    currentIndex++;
                    if(currentIndex>=upList.size()){
                        currentIndex = 0;
                    }
                    server = upList.get(currentIndex);//Получить указанный Служить из живого Служить для работы
                }
    
                //========================================================
                if (server == null) {
                    Thread.yield();
                } else {
                    if (server.isAlive()) {
                        return server;
                    }
    
                    server = null;
                    Thread.yield();
                }
            }
    
            return server;
        }
    }
    
    protected int chooseRandomInt(int serverCount) {
        return ThreadLocalRandom.current().nextInt(serverCount);
    }
    
    public Server choose(Object key) {
        return this.choose(this.getLoadBalancer(), key);
    }
    
    public void initWithNiwsConfig(IClientConfig clientConfig) {
    }

}

Файл MengRule.java:

Язык кода:javascript
копировать
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MengRule {

    @Bean
    public IRule myRule(){
        return new MengRandomRule();// Изменение нашего пользовательского алгоритма: каждое Служить выполняется 5 раз.
    }

Файл основного класса запуска DeptConsumer_80.java:

import com.meng.myrule.MengRule;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.ribbon.RibbonClient;

@SpringBootApplication
@EnableEurekaClient
// Наш настроенный класс ленты можно загрузить при запуске микро-Служить.
@RibbonClient(name = "SPRINGCLOUD-PROVIDER-DEPT",configuration = MengRule.class)
public class DeptConsumer_80 {
    public static void main(String[] args) {
        SpringApplication.run(DeptConsumer_80.class,args);
    }
}

После настройки приведенного выше кода снова запустите службу 80. При посещении http://localhost/consumer/list вы можете обнаружить, что полученные данные меняются каждые 5 раз. На этом этапе происходит введение в настройку стратегии балансировки нагрузки с помощью. Интерфейс IRule готов!

Но следует отметить, что версии Springboot и соответствующего Springcloud не могут быть слишком высокими. Причины были указаны в начале, иначе возникнут ошибки типа Нет доступных экземпляров для ххх. Никак нельзя, можно только продолжать. узнавать новые вещи

2. Реализуйте с помощью LoadBalancer.

Балансировка нагрузки Spring Cloud LoadBalancer, последняя версия Springboot — 2.6.7, а соответствующая версия Springcloud — 2021.0.2. При настройке стратегии балансировки нагрузки таким способом проблем не возникнет. Если вы хотите узнать больше, вы можете . сравните два изменения исходного кода.

1. Импортируйте зависимости Maven.

Здесь вам нужно только импортировать зависимость Spring-cloud-starter-netflix-eureka-client, которая имеет встроенный пакет Ribbon:

Язык кода:javascript
копировать
<dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
     <version>3.1.2</version>
</dependency>
2.yml конфигурация

Конфигурационный файл здесь вообще не изменился

Язык кода:javascript
копировать
server:
  port: 80

# EurekaКонфигурация

eureka:
  client:
    register-with-eureka: false #Не регистрироваться в эврике, по умолчанию true, false означает отсутствие регистрации (зарегистрировано провайдером)
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
    fetch-registry: true    #Указывает, начинать ли с Эврики Сервер получает зарегистрированную информацию Служить, по умолчанию — true, false означает не получать
3. Используйте алгоритм балансировки нагрузки, настроенный Springcloud.

Нет необходимости избегать сканирования Springboot, как указано выше, просто настройте его непосредственно в пакете конфигурации!

[Не удалось передать изображение по внешней ссылке. Исходный сайт может иметь механизм защиты от кражи. Рекомендуется сохранить изображение и загрузить его напрямую (img-hRU42HiD-1687860407300) (C:\Users\86186\AppData\Roaming\Typora\. typora-user-images\ image-20230509142532151.png)]

Содержание конфигурации следующее:

Файл KonanRandomRule.java:

Язык кода:javascript
копировать
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.context.annotation.Configuration;
import org.springframework.core.env.Environment;

@Configuration
public class KonanRandomRule {

    @Bean
    ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment,
                                                            LoadBalancerClientFactory loadBalancerClientFactory) {
        String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
    
        //Вернемся к случайному опросу балансировки нагрузки Способ        return new RandomLoadBalancer(loadBalancerClientFactory.
                getLazyProvider(name, ServiceInstanceListSupplier.class),
                name);
    
          //Загрузка по опросу, это по умолчанию, вот демонстрация

//        return new RoundRobinLoadBalancer(loadBalancerClientFactory.getLazyProvider(name,
//                ServiceInstanceListSupplier.class),name);

    }

}

Вставьте приведенную выше конфигурацию в файл KonanRule.java контейнера Spring:

Язык кода:javascript
копировать
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.cloud.loadbalancer.core.ReactorServiceInstanceLoadBalancer;
import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

//Внедряем пользовательскую балансировку правила нагрузки
@Configuration
public class konanRule {

    // параметр serviceInstanceListSupplierProvider будет автоматически введено
    @Bean
    public ReactorServiceInstanceLoadBalancer customLoadBalancer(ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider) {
        return new KonanRandomRule(serviceInstanceListSupplierProvider);
    }

}

Конфигурация основного стартового класса DeptConsumer_80.java:

Язык кода:javascript
копировать
import com.konan.springcloud.myrule.konanRule;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
//import org.springframework.cloud.netflix.ribbon.RibbonClient;

@SpringBootApplication
@EnableEurekaClient
//@RibbonClient(name = "SPRINGCLOUD-PROVIDER-DEPT",configuration = KonanRule.class) //Больше не используется
@LoadBalancerClient(name = "SPRINGCLOUD-PROVIDER-DEPT",configuration = konanRule.class)
public class DeptConsumer_80 {
    public static void main(String[] args) {
        SpringApplication.run(DeptConsumer_80.class,args);
    }
}

Запустите текущую службу еще раз и посетите http://localhost/consumer/list. Вы можете видеть, что данные, к которым осуществляется доступ каждый раз, представляют собой API различных поставщиков запросов, вызываемых случайным образом, что указывает на то, что эта стратегия также вступила в силу.

Что, если его настроить? Аналогично, мы также пишем класс конфигурации для реализации?

4. Индивидуальный алгоритм балансировки нагрузки.

На рисунке выше вы можете видеть еще один файл: MyLoadBalancerRule.java. Содержимое этого файла — это наша настроенная стратегия. Аналогичным образом мы сначала модифицируем файл konanRule.java и передаем его службу регистрации MyLoadBalancerRule.java для регистрации. эту конфигурацию в контейнере Spring вам нужно изменить только одно место:

Язык кода:javascript
копировать
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.cloud.loadbalancer.core.ReactorServiceInstanceLoadBalancer;
import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

//Внедряем пользовательскую балансировку правила нагрузки
@Configuration
public class konanRule {

    // параметр serviceInstanceListSupplierProvider будет автоматически введено
    @Bean
    public ReactorServiceInstanceLoadBalancer customLoadBalancer(ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider) {
        //Измените это, чтобы указать на настроенный файл конфигурации
        return new KonanRandomRule(serviceInstanceListSupplierProvider);
    }

}

Вот пример конфигурации MyLoadBalancerRule.java, которая также позволяет заменять наш сервис каждые 5 раз (закомментированный — стратегия случайного алгоритма):

Язык кода:javascript
копировать
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.DefaultResponse;
import org.springframework.cloud.client.loadbalancer.EmptyResponse;
import org.springframework.cloud.client.loadbalancer.Request;
import org.springframework.cloud.client.loadbalancer.Response;
import org.springframework.cloud.loadbalancer.core.ReactorServiceInstanceLoadBalancer;
import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
import reactor.core.publisher.Mono;

import java.util.List;

public class MyLoadBalancerRule implements ReactorServiceInstanceLoadBalancer {
    private int total=0;    // сколько раз звонили
    private int index=0;    // Кто в настоящее время предоставляет Служить

    // Служитьсписок    private ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider;
    
    public MyLoadBalancerRule(ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider) {
        this.serviceInstanceListSupplierProvider = serviceInstanceListSupplierProvider;
    }
    
    @Override
    public Mono<Response<ServiceInstance>> choose(Request request) {
        ServiceInstanceListSupplier supplier = serviceInstanceListSupplierProvider.getIfAvailable();
        return supplier.get().next().map(this::getInstanceResponse);
    }
    
    //Используйте случайные числа, чтобы получить Служить

//    private Response<ServiceInstance> getInstanceResponse(
//            List<ServiceInstance> 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);
//    }

    //Каждый Служить посещается 5 раз, а затем заменяется следующим Служить
    private Response<ServiceInstance> getInstanceResponse(List<ServiceInstance> instances) {
        System.out.println("Введите пользовательскую балансировку нагрузки");
        if (instances.isEmpty()) {
            return new EmptyResponse();
        }
    
        System.out.println("Опрос после каждого Служить доступ 5 раз");
        int size = instances.size();
    
        ServiceInstance serviceInstance=null;
        while (serviceInstance == null) {
            System.out.println("===");
            if (total < 5) {
                serviceInstance = instances.get(index);
                total++;
            } else {
                total=0;
                index++;
                if (index>=size) {
                    index=0;
                }
                serviceInstance=instances.get(index);
            }
        }
    
        return new DefaultResponse(serviceInstance);
    
    }

}

Запустите службу Springcloud-consumer-dept-80 и зайдите на http://localhost/consumer/lis. Данные меняются каждые пять раз, а консоль также выводит соответствующую информацию, указывающую на то, что настройка пользовательской политики загрузки прошла успешно!

3. Настройка стратегии мультизагрузки через RestTemplate.

Если мы используем restTemplate для выполнения запросов к интерфейсу службы, нам нужно использовать аннотацию @LoadBalancerClients или аннотацию @LoadBalancerClient, чтобы настроить, куда мы вводим restTemplate.

Язык кода:javascript
копировать
package com.peach.springcloud.config;

import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
//Здесь Конфигурация нашей пользовательской стратегии LoadBalancer. Если кто-то захочет расширить алгоритм самостоятельно Необходимо реализовать интерфейс ReactorServiceInstanceLoadBalancer.
//@LoadBalancerClients(defaultConfiguration = {name = "CLOUD-PAYMENT-SERVICE", configuration = CustomLoadBalancerConfiguration.class})
//Обратите внимание на атрибут имени здесь Должно соответствовать имени провайдера Служить на странице эврики. В настоящее время страница отображается в верхнем регистре
@LoadBalancerClient(name = "CLOUD-PAYMENT-SERVICE",configuration = CustomLoadBalancerConfiguration.class)
public class ApplicationContextConfig {

    //Помещаем этот объект в контейнер ioc
    @Bean
    @LoadBalanced  //Используйте эту аннотацию, чтобы назначить балансировку restTemplate способности нагрузки
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
}

4. Конфигурация стратегии мультизагрузки

Его можно настроить с помощью аннотации @LoadBalancerClients или @LoadBalancerClient.

Язык кода:javascript
копировать
@LoadBalancerClients({
        @LoadBalancerClient(value = "eureka-client-1", configuration = ClietConfig.EurekaClient1Config.class)
        , @LoadBalancerClient(value = "eureka-client-2", configuration = ClietConfig.EurekaClient2Config.class)
})
public class ClietConfig {
    
    static class EurekaClient1Config {
        
        // ...
        
    }

    static class EurekaClient2Config {

        // ...

    }
}

другой

Ссылка: https://blog.csdn.net/m0_57538148/article/details/124771818.

https://blog.csdn.net/qq_35799668/article/details/114534023

https://blog.csdn.net/zuodingquan666/article/details/119207926

https://blog.csdn.net/weixin_42189048/article/details/117843278

boy illustration
Неразрушающее увеличение изображений одним щелчком мыши, чтобы сделать их более четкими артефактами искусственного интеллекта, включая руководства по установке и использованию.
boy illustration
Копикодер: этот инструмент отлично работает с Cursor, Bolt и V0! Предоставьте более качественные подсказки для разработки интерфейса (создание навигационного веб-сайта с использованием искусственного интеллекта).
boy illustration
Новый бесплатный RooCline превосходит Cline v3.1? ! Быстрее, умнее и лучше вилка Cline! (Независимое программирование AI, порог 0)
boy illustration
Разработав более 10 проектов с помощью Cursor, я собрал 10 примеров и 60 подсказок.
boy illustration
Я потратил 72 часа на изучение курсорных агентов, и вот неоспоримые факты, которыми я должен поделиться!
boy illustration
Идеальная интеграция Cursor и DeepSeek API
boy illustration
DeepSeek V3 снижает затраты на обучение больших моделей
boy illustration
Артефакт, увеличивающий количество очков: на основе улучшения характеристик препятствия малым целям Yolov8 (SEAM, MultiSEAM).
boy illustration
DeepSeek V3 раскручивался уже три дня. Сегодня я попробовал самопровозглашенную модель «ChatGPT».
boy illustration
Open Devin — инженер-программист искусственного интеллекта с открытым исходным кодом, который меньше программирует и больше создает.
boy illustration
Эксклюзивное оригинальное улучшение YOLOv8: собственная разработка SPPF | SPPF сочетается с воспринимаемой большой сверткой ядра UniRepLK, а свертка с большим ядром + без расширения улучшает восприимчивое поле
boy illustration
Популярное и подробное объяснение DeepSeek-V3: от его появления до преимуществ и сравнения с GPT-4o.
boy illustration
9 основных словесных инструкций по доработке академических работ с помощью ChatGPT, эффективных и практичных, которые стоит собрать
boy illustration
Вызовите deepseek в vscode для реализации программирования с помощью искусственного интеллекта.
boy illustration
Познакомьтесь с принципами сверточных нейронных сетей (CNN) в одной статье (суперподробно)
boy illustration
50,3 тыс. звезд! Immich: автономное решение для резервного копирования фотографий и видео, которое экономит деньги и избавляет от беспокойства.
boy illustration
Cloud Native|Практика: установка Dashbaord для K8s, графика неплохая
boy illustration
Краткий обзор статьи — использование синтетических данных при обучении больших моделей и оптимизации производительности
boy illustration
MiniPerplx: новая поисковая система искусственного интеллекта с открытым исходным кодом, спонсируемая xAI и Vercel.
boy illustration
Конструкция сервиса Synology Drive сочетает проникновение в интрасеть и синхронизацию папок заметок Obsidian в облаке.
boy illustration
Центр конфигурации————Накос
boy illustration
Начинаем с нуля при разработке в облаке Copilot: начать разработку с минимальным использованием кода стало проще
boy illustration
[Серия Docker] Docker создает мультиплатформенные образы: практика архитектуры Arm64
boy illustration
Обновление новых возможностей coze | Я использовал coze для создания апплета помощника по исправлению домашних заданий по математике
boy illustration
Советы по развертыванию Nginx: практическое создание статических веб-сайтов на облачных серверах
boy illustration
Feiniu fnos использует Docker для развертывания личного блокнота Notepad
boy illustration
Сверточная нейронная сеть VGG реализует классификацию изображений Cifar10 — практический опыт Pytorch
boy illustration
Начало работы с EdgeonePages — новым недорогим решением для хостинга веб-сайтов
boy illustration
[Зона легкого облачного игрового сервера] Управление игровыми архивами
boy illustration
Развертывание SpringCloud-проекта на базе Docker и Docker-Compose