Чем больше вы говорите, чем больше делаете, тем практичнее вы будете.
1. Базовые знания2. Основные компоненты ленты Netflix2.1 Список сервисов ServerList2.2 Фильтрация службы ServerListFilter2.3 Обновление списка сервисов ServerListUpdater2.4 Проверка работоспособности службы IPing2.5 IRule выбирает сервис по алгоритму2.6 ILoadBalancer: координатор, генеральный менеджер2.7 Настроить состав компонентов3. Основные компоненты SC-ленты (от Eureka)3.1 (Конфигурация) Конфигурация по умолчанию RibbonClientConfiguration3.2 (Конфигурация) Пользовательская конфигурация3.2.1 Аннотированный класс конфигурации3.2.1 Конфигурация в конфигурационном файле:3.3 (использование) SpringClientFactory3.4 (использование) LoadBalancerClient3. Что происходит, когда SC-Ribbon используется с eureka4. Как Resttemplate имеет возможности балансировки нагрузки5. Резюме
1. Базовые знания
Прежде всего, нам нужно понять базовые знания:
Netflix открыл исходный код для ряда компонентов микросервисов. адрес проектаgithub.com/Netflix. иметь внутри
eureka
,Ribbon
и т.дSpringCloud интегрирует несколько наборов пакетов с открытым исходным кодом Netfix, а также формирует проект, адрес проектаGitHub.com/spring - уродливо.... Мы знакомы с эврикой, лента здесь.
Ribbon — это проект с открытым исходным кодом, выпущенный Netflix, его основная функция — предоставление алгоритма балансировки нагрузки программного обеспечения на стороне клиента.
Модуль Spring Cloud Ribbon — это
封装
Проект Ribbon, разработанный Netflix.
то есть
- Spring Cloud Ribbon — это набор инструментов для балансировки клиентской нагрузки, основанный на ленте Netflix.
- Основная функциональность находится в проекте Netflix Ribbon.
Эта статья основана на версии Brixton, исходный код которой просматривается непосредственно в среде Springboot.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Brixton.SR4</version>
<type>pom</type>
<scope>import</scope>
</dependency>ml
2. Основные компоненты ленты Netflix
начать сNetflix Ribbon
точка зрения проекта
2.1 Список сервисов ServerList
Список сервисов хранения, то есть объектов для балансировки нагрузки
主要实现
- ConfigurationBasedServerList: Статический список сервисов, который мы обычно называем мертвой записью, настраивается до запуска проекта.
-
DiscoveryEnabledNIWSServerList: список динамических сервисов, начиная с
Eureka Client
для списка услуг.
2.2 Фильтрация службы ServerListFilter
Отфильтруйте список служб по определенным условиям и выполните вторичную фильтрацию в списке серверов ServerList.
主要实现
:
-
AbstractServerListFilter
Класс, отвечающий за фильтрацию списка доступных в данный момент серверов из балансировщика нагрузки. - ZoneAffinityServerListFilter: Отфильтровать все службы, которые не находятся в той же зоне, что и клиент (примечание: если той же зоны, что и клиент, не существует, не фильтровать службы в разных зонах).
- ZonePreferenceServerListFilter:
- ServerListSubsetFilter
2.3 Обновление списка сервисов ServerListUpdater
Определите действие обновления, выполните операцию обновления в соответствии с политикой, обновите список ServerList, обычно используемый для динамического списка серверов.
主要实现
:
PollingServerListUpdater
Стратегия реализации по умолчанию. Этот объект запускает синхронизированный пул потоков и регулярно выполняет стратегию обновления.EurekaNotificationServerListUpdater
Список служб обновляется при получении уведомления об обновлении кэша.
2.4 Проверка работоспособности службы IPing
проверить, жив ли сервис,
主要实现
:
- DummyPing: всегда думай живо
- NoOpPing:ничего не делать
- PingConstant: Укажите статус выживания сервера, установив параметр конфигурации
- NIWSDiscoveryPing: возвращает true, если экземпляр службы существует в локальном кэше Eureka (конфигурация по умолчанию). Когда класс, предоставленный в пакете ленты-eureka, используется в сочетании с eureka, если клиент обнаружения находится в сети, считается, что обнаружение пульса прошло успешно.
- PingUrl: Используйте HttpClient для вызова URL-адреса службы. Если вызов успешен, пульс считается успешным, что указывает на то, что служба активна.
IPing проверяет работоспособность службы.
IPingStrategy
: интерфейс политики проверки списка сервисов,
Единственная реализация:SerialPingStrategy
: Используя стратегию линейного обхода, IPing используется для проверки живучести каждого сервиса.
2.5 IRule выбирает сервис по алгоритму
Выберите услугу для доступа из списка услуг в соответствии с алгоритмом
主要实现
:
- RandomRule: случайный алгоритм
- RoundRobinRule: стратегия ротации (`политика по умолчанию`)
- RetryRule: Опрос + повтор, основанный на RoundRobinRule, добавлена функция повтора.
-
WeightedResponseTimeRule: (
非常好
) при запуске статистика недостаточна, первое использованиеRoundRobinRule
Стратегия. имеетDynamicServerWeightTask
Запланированные задачи, время ответа каждого экземпляра службы по умолчанию рассчитывается каждые 30 секунд, и когда статистики будет достаточно, переключитесь наWeightedResponseTimeRule
. - BestAvailableRule: сначала отфильтруйте службы с включенным автоматическим выключателем, а затем выберите экземпляр службы с наименьшим одновременным запросом для использования. При запуске, если статистики недостаточно, используется стратегия RoundRobinRule, а когда статистики будет достаточно, переключится на BestAvailableRule.
- PredicateBasedRule: фильтр + поворот
- AvailabilityFilteringRule: (1) Автоматический выключатель сработал из-за множественных сбоев доступа (2) Количество одновременных подключений превышает пороговое значение (3) Оставшийся список услуг опрашивается
Резюме: мы видим, что вышеуказанный компонент является ссылкой на список сервисов (
待负载对象
)из定义
,и操作
. Но пусть работают вместе. Для этого требуется ILoadBalancer
2.6 ILoadBalancer: координатор, генеральный менеджер
Балансировщик нагрузки отвечает за управление планированием балансировки нагрузки на уровне менеджера.
调度其他组件,完成从服务列表里获取一个服务的目标
Предоставьте внешний метод для выбора сервера.
public Server chooseServer(Object key);
Абстрактный класс: AbstractLoadBalancer main定义了服务的分组
主要实现
:
1.BaseLoadBalancer: Базовая реализация балансировщика нагрузки. Обслуживание
(1) Вести список всех сервисов + список текущих выживших сервисов
(2) По умолчанию для выбора сервиса используется ротация.
(3) Определите таймер и регулярно проверяйте активность в соответствии с политикой SerialPingStrategy.
2.DynamicServerListLoadBalancerДинамическая версия обновления
(1) DomainExtractingServerList динамически получает список служб статуса UP от EurekaClient.
(2) ZoneAffinityServerListFilter фильтрует список
(3) PollingServerListUpdater регулярно обновляет службу
3.ZoneAwareLoadBalancer: Добавлена политика зоны на основе DynamicServerListLoadBalancer.
(1) Этот класс использует ZoneStats для хранения статуса и среднего количества запросов каждой зоны. Региональные показатели как факторы, влияющие на выбор услуг
2.7 Настроить состав компонентов
С компонентами, какой метод комбинирования используется? Лента обеспечивает возможность настройки для пользователей.
Настройте различные эффекты балансировки нагрузки с помощью различных комбинаций компонентов.
Какие есть способы настройки:
- Интерфейс IClientConfig: реализация по умолчанию
DefaultClientConfigImpl
. Если вы не настроите никаких свойств, определенные здесь компоненты будут использоваться по умолчанию. Конечно, здесь есть и другие конфигурации различных свойств.
默认配置的组件有:
- Конфигурация файла: когда мы заменяем конфигурацию по умолчанию, мы можем настроить различные свойства в файле конфигурации.
Конфигурация формата атрибута выглядит следующим образом
<clientName>.<nameSpace>.<propertyName>=<value>
api-user.ribbon.listOfServers=localhost:8099
Таким образом: приблизительные компоненты Netfix-Ribbon и принцип работы понятны с первого взгляда.
адрес проектаGitHub.com/Netflix/Япония…
3. Основные компоненты SC-ленты (от Eureka)
SpringCloud-Ribbon объединяетNetflix Ribbon
, чтобы интегрировать его в систему springcloud.
Основные функцииNetflix Ribbon
Проект находится в разработке. Пакет SC-лентыNetflix Ribbon
, в основном для выполнения некоторой работы по интеграции.
С этой целью, какие компоненты SpringCloud-Ribbon добавлены и что они сделали?
思考
: Поскольку основная функцияNetflix Ribbon
Проект находится в разработке. То, что делает этот проект, - это не что иное, как начало со следующих аспектов
- уровень конфигурации: В соответствии с привычками конфигурации системы Spring.
- уровень использования: Как использовать балансировщик нагрузки ленты
!!!!!注意注意: 此处说的是脱离Eureka使用SpringCloud-Ribbon
Рассмотрим проделанную для этого работу:
Работа на уровне конфигурации:
3.1 (Конфигурация) Конфигурация по умолчанию RibbonClientConfiguration
Этот класс конфигурации также существует как класс конфигурации по умолчанию, то есть когда вы ничего не настраиваете.SpringCloud-Ribbon
Комбинация основных компонентов, загружаемых по умолчанию,
по сравнению сNetflix Ribbon
проектDefaultClientConfigImpl
Предусмотренные компоненты по умолчанию:
3.2 (Конфигурация) Пользовательская конфигурация
На основе принципа расширяемости: SpringCloudRibbon также предоставляет персонализированные функции настройки.
3.2.1 Аннотированный класс конфигурации
Здесь задействованы две аннотации:@RibbonClient
и@RibbonClients
(обратите внимание, что естьs
)
- Функция этих двух классов аннотаций заключается в том, что классы, аннотируемые ими, будут передавать некоторый механизм
RibbonClientConfiguration
заменить конфигурацию по умолчанию - Разница между этими двумя аннотациями заключается в следующем: одна охватывает компонент одной службы, а другая нацелена на несколько служб.
Используется следующим образом: я ставлюuser
балансировка сервисной нагрузкиIPing
компоненты заменены на моиMyPingUrl
.
Configuration
@RibbonClient(name = "user", configuration = UserConfiguration.class)
public class UserRibbonConfiguration {
}
@Configuration
protected static class UserConfiguration{
@Bean
public IPing ribbonPing() {
return new MyPingUrl();
}
}
Обратите внимание на добавление конфигурации в UserConfiguration. UserConfiguration должен быть объявлен с помощью @Configuration и не может быть размещен в месте, которое может быть просканировано с помощью @ComponentScan или @SpringBootApplication основного контекста приложения, что предотвращает совместное использование конфигурации всеми @RibbonClients.
Если вы хотите сбалансировать нагрузку на все сервисыIPing
компоненты заменены на моиMyPingUrl
@RibbonClient(defaultConfiguration = UserConfiguration.class)
public class UserRibbonConfiguration {
}
Принцип работы:
Принцип работы этих двух аннотаций таков: вводяRibbonClientConfigurationRegistrar
Регистратор, который регистрирует класс конфигурации какRibbonClientSpecification
@Configuration
@Import(RibbonClientConfigurationRegistrar.class)//这里
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RibbonClient {
}
//注册器
public class RibbonClientConfigurationRegistrar implements ImportBeanDefinitionRegistrar {
private void registerClientConfiguration(BeanDefinitionRegistry registry,
Object name, Object configuration) {
//注册为一个RibbonClientSpecification
BeanDefinitionBuilder builder = BeanDefinitionBuilder
.genericBeanDefinition(RibbonClientSpecification.class);
builder.addConstructorArgValue(name);
builder.addConstructorArgValue(configuration);
registry.registerBeanDefinition(name + ".RibbonClientSpecification",
builder.getBeanDefinition());
}
}
RibbonClientSpecification
: Буквально переведено в спецификацию клиента, да, ваша персонализированная конфигурация анализируется в спецификации клиента.
Пример:
- Служба A и служба B используют одну и ту же персонализированную конфигурацию, службы A и B имеют одну
RibbonClientSpecification
Спецификация - Служба C использует персонализированную конфигурацию, а служба C имеет
RibbonClientSpecification
Спецификация
Как работает эта спецификация? увидеть ниже
3.2.1 Конфигурация в конфигурационном файле:
Другой - настроить его непосредственно в файле конфигурации в системе Spring.application.yml
api-user:
ribbon:
NIWSServerListClassName: com.netflix.loadbalancer.ConfigurationBasedServerList
Классы, определенные в этих свойствах, имеют приоритет над bean-компонентами, определенными с помощью @RibbonClient(configuration=MyRibbonConfig.class) и значениями по умолчанию, предоставляемыми Spring Cloud Netflix.
说了配置,在讲讲使用层面的工作
Используйте работу на уровне:
Использование функции балансировки нагрузки фактически вILoadBalancer
на этом координирующем компоненте. Так называемое использование, собственно, и заключается в этом.ILoadBalancer
начальство.
3.3 (использование) SpringClientFactory
SpringClientFactory использует фабричный режим для предоставления внешних сервисов: согласно serviceId, он получает сервисы таких объектов, как IClient, ILoadBalance и ILoadBalanceContext.
Здесь мы сосредоточимся только на
ILoadBalance
приобретение.
SpringClientFactory создает отдельный контекст для каждой службы и загружает в него соответствующую конфигурацию и классы реализации интерфейса Ribbon core. создать логику в своем родительском классеNamedContextFactory
public abstract class NamedContextFactory{
private Map<String, C> configurations = new ConcurrentHashMap<>();
private Class<?> defaultConfigType;
//创建上下文
protected AnnotationConfigApplicationContext createContext(String name) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
if (this.configurations.containsKey(name)) {
for (Class<?> configuration : this.configurations.get(name)
.getConfiguration()) {
context.register(configuration);
}
}
for (Map.Entry<String, C> entry : this.configurations.entrySet()) {
if (entry.getKey().startsWith("default.")) {
for (Class<?> configuration : entry.getValue().getConfiguration()) {
context.register(configuration);
}
}
}
context.register(PropertyPlaceholderAutoConfiguration.class,
this.defaultConfigType);
context.getEnvironment().getPropertySources().addFirst(new MapPropertySource(
this.propertySourceName,
Collections.<String, Object> singletonMap(this.propertyName, name)));
if (this.parent != null) {
// Uses Environment from parent as well as beans
context.setParent(this.parent);
}
context.refresh();
return context;
}
}
Здесь есть два момента:
По входящей службе
serverId
СоздаватьAnnotationConfigApplicationContext
, загрузите свой собственный пакет балансировки нагрузки. Разные сервисы имеют разные контексты, в которых хранится комбинация принадлежащих ему комплектов балансировки нагрузки.Способ составления набора услуг балансировки нагрузки. Это определяется двумя упомянутыми выше способами настройки. это
configurations
иdefaultConfigType
Спецификация, представленная двумя свойствами.
private Map<String, C> configurations = new ConcurrentHashMap<>();
private Class<?> defaultConfigType;//代表默认的组件组合
- конфигурации : представляет спецификацию комплекта для персонализированных конфигураций. упомянутый выше
RibbonClientSpecification
- defaultConfigType : представляет класс конфигурации по умолчанию для sc-ленты.
RibbonClientConfiguration
когда мы звонимSpringClientFactory.getLoadBalancer
Когда метод получает экземпляр балансировщика нагрузки, суть сводится к получению принадлежащего ему сервиса в контексте, соответствующем сервису.ILoadBalancer
выполнить.
public <T> T getInstance(String name, Class<T> type) {
AnnotationConfigApplicationContext context = getContext(name);
if (BeanFactoryUtils.beanNamesForTypeIncludingAncestors(context,
type).length > 0) {
return context.getBean(type);返回bean
}
return null;
}
получитьILoadBalancer
реализации, мы можем назвать егоchooseServer
Получите экземпляр службы и сделайте запрос.
ILoadBalancer userLoadBalancer = clientFactory.getLoadBalancer("user");
Server server = userLoadBalancer.chooseServer("default")
3.4 (использование) LoadBalancerClient
LoadBalancerClient инкапсулирует SpringClientFactory и широко используется в качестве клиента балансировщика нагрузки. Этот класс является входом в настоящий клиент балансировки нагрузки SC-Ribbon.
Предусмотрено три метода:
- Выберите метод экземпляра службы;
- выполнить метод запроса
- Рефакторинг метода uri.
Каждый метод связан с балансировкой нагрузки
ServiceInstance choose(String serviceId);
<T> T execute(String serviceId, LoadBalancerRequest<T> request) throws IOException;
URI reconstructURI(ServiceInstance instance, URI original);
LoadBalancerClient действует как клиент балансировки нагрузки. Его способность полностью основана на совместных усилиях всех вышеперечисленных компонентов.
public class MyClass {
@Autowired
private LoadBalancerClient loadBalancer;
public void doStuff() {
ServiceInstance instance = loadBalancer.choose("stores");
URI storesUri = URI.create(String.format("http://%s:%s", instance.getHost(), instance.getPort()));
// ... do something with the URI
}
}
3. Что происходит, когда SC-Ribbon используется с eureka
1. Уровень конфигурации:
когдаSpringCloudRibbon
иEureka
При совместном использовании будет использоваться@RibbonClients
Замена некоторых компонентов по умолчанию для балансировки нагрузки всех сервисов (замена составных пакетов)
@Configuration
@EnableConfigurationProperties
@ConditionalOnClass(DiscoveryEnabledNIWSServerList.class)
@ConditionalOnBean(SpringClientFactory.class)
@ConditionalOnProperty(value = "ribbon.eureka.enabled", matchIfMissing = true)
@AutoConfigureAfter(RibbonAutoConfiguration.class)
@RibbonClients(defaultConfiguration = EurekaRibbonClientConfiguration.class)
public class RibbonEurekaAutoConfiguration {
}
----------------------------
@Configuration
@CommonsLog
public class EurekaRibbonClientConfiguration {
@Bean
@ConditionalOnMissingBean
public IPing ribbonPing(IClientConfig config) {
NIWSDiscoveryPing ping = new NIWSDiscoveryPing();//
ping.initWithNiwsConfig(config);
return ping;
}
@Bean
@ConditionalOnMissingBean
public ServerList<?> ribbonServerList(IClientConfig config) {
DiscoveryEnabledNIWSServerList discoveryServerList = new DiscoveryEnabledNIWSServerList(
config);
DomainExtractingServerList serverList = new DomainExtractingServerList(
discoveryServerList, config, this.approximateZoneFromHostname);
return serverList;
}
}
- IP-адрес: реализован с использованием NIWSDiscoveryPing.
- Список серверов: используется
DomainExtractingServerList
.DomainExtractingServerList
проксиDiscoveryEnabledNIWSServerList
.DiscoveryEnabledNIWSServerList
Список хранимых сервисов все изEurekaClient
из локального кеша. (Операция выборкиPollingServerListUpdater
, исполнение по времени)
public class DiscoveryEnabledNIWSServerList extends AbstractServerList<DiscoveryEnabledServer>{
private List<DiscoveryEnabledServer> obtainServersViaDiscovery() {
EurekaClient eurekaClient = eurekaClientProvider.get();
List<InstanceInfo> listOfInstanceInfo = eurekaClient.getInstancesByVipAddress(vipAddress, isSecure, targetRegion);
....
}
}
2. Используйте уровень:
Ничего не меняется, просто используйтеLoadBalancerClient
Чтобы использовать балансировку нагрузки для получения сервера.
4. Как Resttemplate имеет возможности балансировки нагрузки
Resttemplate имеет возможности балансировки нагрузки, и его суть заключается в использованииLoadBalancerClient
реализовать.
Как этого достичь?
Это включает в себя два пункта знаний:
-
Resttemplate
Связанные системы: -
@LoadBalanced
аннотация.
Resttemplate
Есть понятие перехватчика. Другими словами, до того, как будет сделан фактический запрос, некоторые перехватчики будут взяты. Это выбирает балансировщик нагрузкиServer
предоставил возможность.
@LoadBalanced
Аннотация, чтобы изменить егоResttemplate
Примеры инъекцийLoadBalancerInterceptor
Перехватчик. Этот перехватчик переданLoadBalancerClient
для достижения балансировки нагрузки
public class LoadBalancerInterceptor implements ClientHttpRequestInterceptor {
private LoadBalancerClient loadBalancer;
...
}
Подробности читайте в других моих статьях
Отправка http-запросов (1): несколько способов отправки http-запросов.
Отправить http-запрос (2): RestTemplate отправляет http-запрос
RestTemplate с аннотацией @LoadBalanced имеет возможности балансировки нагрузки.
5. Резюме
Текст начинается с введения нескольких компонентов балансировки нагрузки и начинается с нижнего уровня.Resttemplate
принцип. открылResttemplate
Черный ящик, который инициирует запросы балансировки нагрузки. Вдоль этой линии просто внимательно изучите очки знаний каждого раздела.
Вы будете поражены тем, сколько работы по разработке было сэкономлено благодаря построению здания фреймворков с открытым исходным кодом.
Мы не должны останавливаться на этапе использования, но также должны глубоко понимать принципы лежащего в основе фреймворка, чтобы вы были на один уровень выше здания.
Ссылка на ссылку:
https://www.jianshu.com/p/73c117fbfe10
https://blog.csdn.net/hry2015/article/details/78357990
Если в этой статье есть какие-либо ошибки, пожалуйста, критикуйте и советуйте, это очень ценится!
Если вы ничего не понимаете в статье, вы можете связаться со мной, чтобы обменяться знаниями!
Публичный аккаунт WeChat:Исходное действие
Наслаждайтесь изучением исходного кода, действуйте, действуйте с исходным кодом