Далее, давайте посмотрим, как получить экземпляр службы, какая обработка была проведена после получения и как выбрать экземпляр службы после обработки.
Разделите на три части:
Конфигурация
В разделе «Конфигурация» предыдущей статьи «Принципы пружинной облачной ленты» вы можете видеть, что балансировщик нагрузки по умолчанию является Zoneawareloadbalancer.
Посмотрите на класс конфигурации.
Расположение:
Spring-Cloud-netflix-core-13.5.release.jarorg.springframework.cloud.netflix.ribbonribbonclientConfiguration.class
@Suppresswarnings ("temercation")@configururation@enableconfigurationproperties // Порядок здесь важен, последний должен быть по умолчанию, сначала должно быть необязательным // См. https://github.com/spring-cloud/spring-cloud-netflix/issues/2086#issuecomment-316281653@import( <okhttpribbonconfiguration.class, restclascbonconfiguration.class, httpclientribgonfiguration. Опустить @bean @conditionalonmissingbean public iloadbalancer Ribbonloadbalancer (iClientConfig Config, Serverlist <serer> ServerList, ServerListFilter <server> ServerListFilter, Irule Rule, iping Ping, ServerListupdater. this.propertiesfactory.get (iloadbalancer.class, config, имя); } вернуть новый zoneawareloadbalancer <> (конфигурация, правило, ping, serverlist, serverlistfilter, serverlistupdater); } // опущено}Внедрено в экземпляре конфигурации, правила, ping, serverlist, serverlistfilter, serverlistupdater.
Конфигурация: Настройте экземпляр.
Правило: экземпляр политики балансировки нагрузки.
Пинг: экземпляр пинга.
Serverlist: получает и обновляет экземпляр службы.
ServerListfilter: экземпляр фильтрации службы.
ServerListupdater: экземпляр обновления информации о списке служб.
@Suppresswarnings ("temercation")@configururation@enableconfigurationproperties // Порядок здесь важен, последний должен быть по умолчанию, сначала должно быть необязательным // См. https://github.com/spring-cloud/spring-cloud-netflix/issues/2086#issuecomment-316281653@import( <okhttpribbonconfiguration.class, restclascbonconfiguration.class, httpclientribgonfiguration. Опустить @bean @conditionalonmissingbean public iclientconfig ribbonclientconfig () {defaultClientConfigimpl config = new DefaultClientConfigImpl (); config.loadproperties (this.name); вернуть конфигурацию; } @Bean @conditionalonmissingbean public ribbonrule (iclientconfig config) {if (this.propertiesfactory.isset (irule.class, name)) {return this.propertiesfactory.get (irule.class, config., name); } Zoneavoidancerule ruge = new Zoneavoidancerule (); rule.initwithniwsconfig (config); правило возврата; } @Bean @conditionalonmissingbean public iping ribbonping (iclientconfig config) {if (this.propertiesfactory.isset (iping.class, name)) {вернуть это. } вернуть новый Dummyping (); } @Bean @conditionalonmissingbean @suppresswarnings ("unchecked") public serverlist <serer> ribbonserverlist (iclientconfig config) {if (this.propertiesfactory.isset (serverlist.class, имя)) {return.propertiesfactory.slistry.class, confice, name); } ConfigurationBasedServerlist ServerList = новый конфигурация BasedServerList (); serverlist.initwithniwsconfig (config); вернуть серверный список; } @Bean @conditionalonmissingbean public serverlistupdater ribbonserverlistupdater (iclientconfig config) {return new pollingserverlistupdater (config); } @Bean @conditionalonmissingbean public iloadbalancer ribbonloadbalancer (iclientconfig config, serverlist <server> serverlistfilter <server> serverlistfilter, ruge rule, iping ping, serverlistupdater serverlidepdater) {if (this.propertiesfactory.isset (iloadlancer.class. this.propertiesfactory.get (iloadbalancer.class, config, имя); } вернуть новый zoneawareloadbalancer <> (конфигурация, правило, ping, serverlist, serverlistfilter, serverlistupdater); } @Bean @conditionalonmissingbean @suppresswarnings ("unchecked") public serverlistfilter <server> ribbonserverlistfilter (iclientConfig config) {if (this.propertiesfactory.isset (serverlistfilter.class, name)) {return.propertiesfactory.getSlater.class, name.colass. } ZonePreferenceserverListFilter Filter = new ZonePreferencesServerListFilter (); filter.initwithniwsconfig (config); вернуть фильтр; } @Bean @conditionalonmissingbean public Ribbonloadlancercontext лента Ribbonlocklancercontext (iloadbalancer LoadBalancer, конфигурация iClientConfig, retryHandler retryHandler) {return new RibbonlackBalancOntext (LoadBalancer, config, retryHandler); } // опущено}Настройка соответствующих примеров здесь
Конфигурация: DefaultClientConfigImpl.
Правило: Zoneavoidancerule.
Пинг: Dummyping.
ServerList: ConfigurationBasedServerlist, экземпляр списка сервисов на основе конфигурации.
ServerListfilter: ZonePreferenceserverListfilter.
ServerListupdater: OllingserverListupdater.
Следует отметить, что экземпляр ServerList здесь представляет собой конфигурацию, основанный на сериале, который является экземпляром, который получает информацию об обслуживании, когда Eureka не используется, и получается из файла конфигурации.
Таким образом, при использовании Eureka вам необходимо получить информацию о службе с сервера Eureka. Какой экземпляр следует использовать для этого?
При включении Eureka Service Discovery, класс конфигурации EurekaribbonClientConfiguration будет первым принят.
Расположение:
Spring-Cloud-netflix-eureka-client-1.3.5.release.jarorg.springframework.cloud.netflix.ribbon.eurekaeurekaribbonclientConfiguration.class
@Configuration @commonslogpublic class eurekaribbonclientconfiguration {// omit @bean @conditionalonmissingbean public iping ribbonping (iclientconfig config) {if (this.propertiesfactory.isset (iping.class, serviceId)) {return. } Niwsdiscoveryping ping = new niwsdiscoveryping (); ping.initwithniwsconfig (config); вернуть пинг; } @Bean @conditionalonmissingbean public serverlist <?> Ribbonserverlist (iclientconfig config, поставщик <eurekaclient> eurekaclientprovider) {if (this.propertiesfactory.isset (serverlist.class, serviceId)) {return.propertiesfactory.get (serverlist.class, serviceId)) {return. } DiscoveryEnabledNiwsserverlist DiscoveryServerList = new DiscoveryEnabledNiwsserverlist (config, eurekaclientprovider); Domainextractingserverlist serverlist = new DomainexTractingServerlist (DiscoveryServerList, config, this.ApproximatezoneFromHostName); вернуть серверный список; } // опущено}После первого использования конфигурации EurekaribbonclientConfiguration, экземпляры фактически становятся
Конфигурация: DefaultClientConfigImpl.
Правило: Zoneavoidancerule.
Ping: Niwsdiscoveryping.
ServerList: DomainexTractingServerlist, внутренняя DiscoveryEnabledniwsserverlist, фактически получение списка информации об обслуживании с помощью Service Discovery.
ServerListfilter: ZonePreferenceserverListfilter.
ServerListupdater: OllingserverListupdater.
Получить услуги
Прежде чем найти доступ к получению информации об обслуживании, сначала отредактируйте взаимосвязь наследования класса балансировщика нагрузки.
Родительский класс DynamicserverListloadlancer Construct вызывается в конструкции Zoneawareloadbalancer.
Расположение:
ленточный ладбалранц-2.2.2.jar
com.netflix.loadbalancer
Zoneawareloadbalancer.class
При построении DynamicserverListloadBalancer вызовут функция Restofinit.
ленточный ладбалранц-2.2.2.jar
com.netflix.loadbalancer
DynamicserverListloadBalancer.class
void restofinit (iClientConfig ClientConfig) {boolean primeConnection = this.IseSablePrimingConnections (); // выключить это, чтобы избежать дублированного асинхронного праймирования, выполненного в BaseloadBalancer.setserverlist () this.SetenablePrimingConnections (false); eNableAndinitlearnnewserversfeature (); UpdateListofServers (); if (primeConnection && this.getPrimeConnections ()! = null) {this.getPrimeConnections () .primeConnections (getReachableservers ()); } this.SetenablePrimingConnections (primeConnection); Logger.info ("DynamicServerListListloadBalancer для Client {} инициализировано: {}", clientConfig.getClientName (), this.ToString ()); }Во -первых, список сервисов регулярно обновляется, вызывая метод inableAndinitlearnnewserversfeature, а затем немедленно вызовите функцию UpdateListOfServers, чтобы немедленно получить информацию о списке услуг.
Давайте сначала посмотрим на метод EnableAndinitlearnnewserversfeature. Фактически, метод начала экземпляра обновления информации об обновлении информации о списке обслуживания вызывается для запуска функции времени обновления.
/ ** * Функция, которая позволяет нам добавлять новые экземпляры (от AMIS) в список * существующих серверов, которые LB будет использовать Call This Method, если вы хотите, чтобы эта функция включена */ public void enableAndinitlearnnewserversfeature () {logger.info ("с использованием serverlideupdater {}", serverlideupdater.getClass ().) ServerLideUpdater.start (UpdateAction); } Примером обновления информации о списке услуг здесь является экземпляр PollingserverListupdater, настроенный на этапе конфигурации. Взгляните на метод строительства и начала этого класса.
Public Class OplyingServerListupdater реализует ServerListupdater {// private static long listofservers_cache_update_delay = 1000; // msecs; private static int listofservers_cache_repeat_interval = 30 * 1000; // msecs; // Частный финальный атомарбуолейский isactive = new Atomicboolean (false); частное летучие длины Lostupdated = System.currentTimeMiMillis (); Частный финальный длинный initialdelayms; Частный финальный длинный обновление; // слегка публичный OfflingServerListupdater (iClientConfig ClientConfig) {this (listofservers_cache_update_delay, getrefreshintervalms (clientConfig)); } public ollingserverListupdater (Final Long InitialLayms, Final Long RefreshIntervalms) {this.InitialLayms = initialLayms; this.RefreshIntervalms = refreshIntervalms; } @Override public Synchronized void START (окончательный UpdateAction UpdateAction) {if (isActive.comPareAndset (false, true)) {final Runnable warpperrunnable = new Runnable () {@Override public void run () {if (! Isactive.get ()) {if (pressudfuture! } возвращаться; } try {updateAction.doupdate (); LASTUPDATED = SYSTEM.CurrentTimeMiLLIS (); } catch (Exception e) {logger.warn ("Не удалось одно цикл обновления", e); }}}}; presenuledFuture = getRefreshexeCutor (). PredicuLeWithFixedDelay (warperRunnable, initialLayms, rebreshIntervalms, timeUnit.milliseconds); } else {logger.info ("уже активный, no-op"); } } // пропускать}Из конструкции и постоянного определения выполнение откладывается на одну секунду, а обновление выполняется каждые 30 секунд по умолчанию. Вы можете изменить время обновления между конфигурацией.
Из метода запуска он должен открыть расписание, которое регулярно выполняется, и регулярно выполнять updateAction.doupdate ().
Вернитесь к методу начала Caller DynamicserverListlistloadlancer Class и посмотрите на определение экземпляра UpdateAction.
Защищенный Final ServerListupdater.updateAction updateAction = new ServerListupdater.updateAction () {@Override public void doupdate () {updateListofServers (); }};Фактически, используется метод UpdateListOfServers Class Class, который соответствует пути обновления списка информации о службе сразу после обновления времени запуска.
Продолжайте смотреть на метод UpdateListOfServers.
public void updateListofservers () {list <t> servers = new ArrayList <t> (); if (serverlistimpl! = null) {servers = serverlistimpl.getupdatedlistofservers (); Logger.debug ("Список серверов для {}, полученных из Discovery Client: {}", getIdentifier (), servers); if (filter! = null) {servers = filter.getFilteredListOfServers (Servers); Logger.debug ("фильтрованный список серверов для {}, полученного от Discovery Client: {}", getIdentifier (), servers); }} UpdateAllServerList (Servers); }1. Получите список информации о службе через экземпляр ServerList.
2. Отфильтруйте полученный список информации о службе через экземпляр ServerListfilter.
3. Сохраните список отфильтрованной информации о обслуживании в LoadBalancerStats в качестве состояния.
Давайте посмотрим на это отдельно.
1. Получите список информации о службе через экземпляр ServerList.
Экземпляр ServerList - это DomainExtractingServerList, сгенерированный на стадии конфигурации. Информация об обслуживании делегирована DiscoveryEnabledniwsserverlist.
Public Class DiscoveryEnabledNiwsServerlist Extrastends AbstractServerlist <singeryEnablibleServer> {// Опустить @Override Public List <cintyenabledServer> getInitialListofservers () {return optedServersViadScovery (); } @Override public list <cintyenabledserver> getUpdatedListofservers () {return optedServersViAdiscovery (); } частный список <congterseenabledServer> optedServersViAdiscovery () {list <SitectyEnabledServer> serverlist = new ArrayList <SiteckyEnabledServer> (); if (eurekaclientprovider == null || eurekaclientprovider.get () == null) {logger.warn ("eurekaclient еще не был инициализирован, возвращая пустой список"); вернуть новый ArrayList <SiturnableDServer> (); } Eurekaclient eurekaclient = eurekaclientprovider.get (); if (vipAddresses!=null){ for (String vipAddress: vipAddresses.split(",")) { // if targetRegion is null, it will be interpreted as the same region of client List<InstanceInfo> listOfInstanceInfo = eurekaClient.getInstancesByVipAddress(vipAddress, isSecure, targetRegion); for (exanceInfo II: listOfInStanceInfo) {if (ii.getStatus (). equals (andanceStatus.up)) {if (weadUseOverrideport) {if (logger.isdebugenabled ()) {logger.debug («переоценка порта на имя клиента:« + clientName + »to" overport); } // Копия необходима, так как застройщик exactionInfo просто использует исходную ссылку, //, и мы не хотим повредить глобальную копию Eureka объекта, которая может быть // используется другими клиентами в нашей системе ExtanceInfo Copy = new ExactionInfo (ii); if (issecure) {ii = new IncasonInfo.Builder (COPY) .SETSECUREPORT (OVIDEPORT) .BUILD (); } else {ii = new ExtanyInfo.builder (copy) .setport (overidport) .build (); }} DiscoveryEnabledServer des = new DiscoveryEnabledServer (ii, issecure, salyUseipaddr); des.setzone (discoveryclient.getzone (ii)); serverlist.add (des); }} if (serverlist.size ()> 0 && arpitizevizevipaddressbasedservers) {break; // Если у текущего vipaddress есть серверы, мы не используем последующие серверы на основе Vipaddress}}} return ServerList; } // опущено}Можно видеть, что на самом деле следует получить всю информацию о экземпляре службы от сервера Eureka через клиент Eureka и упаковывать онлайн -экземпляры DiscoveryEnabledServer, с информацией о зоне и помещайте их в список услуг.
2. Отфильтруйте полученный список информации о службе через экземпляр ServerListfilter.
Экземпляр ServerListFilte - это ZonePreferencesserverListFilter, генерируемый на этапе конфигурации, и фильтруется, вызывая метод getFilteredListofservers от экземпляра.
@Data@equalsandhashcode (callsuper = false) public class ZonePreferencesserverListfilter Extends ZoneaffinityServerlistfilter <serer> {Private String Zone; @Override public void initwithniwsconfig (iclientconfig niwsclientconfig) {super.initwithniwsconfig (niwsclientconfig); if (ConfigurationManager.getDeploymentContext ()! = null) {this.zone = configurationManager.getDeploymentContext (). getValue (contextKey.zone); }} @Override public list <sermer> getFilteredListofservers (list <serer> servers) {list <server> output = super.getFilteredListOfServers (Servers); if (this.zone! = null && output.size () == servers.size ()) {list <server> local = new ArrayList <serer> (); для (сервер (сервер: output) {if (this.zone.equalsignorecase (server.getzone ())) {local.add (server); }} if (! local.isempty ()) {return local; }} return output; }}В методе GetFilteredListofservers первое, что вы хотите, - это назвать то же имя родительского класса, чтобы первым фильтровать. Фактически, родительский класс также отфильтровывает услуги в той же области, что и потребительская сторона. Мало того, это добавляет некоторые интеллектуальные суждения, чтобы гарантировать, что фильтрация в той же области не выполняется, когда сбой/нагрузка высока или когда есть мало доступных случаев.
Однако в ZonePreferencesserverListfilter.getFilteredListofservers, даже если родительский класс не фильтровал, услуги той же зоны все еще необходимо отфильтровать и использовать. Кто сказал, что класс здесь является зоной?
Это довольно странная вещь, и кажется, что разумное суждение родительского класса не влияет.
Давайте посмотрим на тяжелую работу, выполненную ZoneaffinityServerlistfilter.getFilteredListofservers.
открытый класс ZoneaffinityServerlistfilter <t Extends Server> Extraves AbstractServerListFilter <t> реализует iClientConfigAware {// private boolean shopeablezoneaffinity (список <t> фильтрован) {if (! Zoneaffinity &&! } if (ZoneExclusize) {return true; } LoadBalancerStats Stats = GetLoadBalanCerStats (); if (stats == null) {return Zoneaffinity; } else {logger.debug («Определение аффинности зоны должна быть включена с данным списком сервера: {}», фильтровано); ZonesnapShot Snapshot = stats.getzonesnapshot (фильтрован); Double Loadperserver = snapshot.getLoadPerserver (); int instanceCount = snapshot.getInstanceCount (); int circuleTrakerTippultCount = snapshot.getCircuitTrippedCount (); if ((((Double) CircuitHreakertredCount) / InstanceCount> = BlackoutServerPercetHethReshold.get () || loadperServer> = ActiveRequustSperSerVerThroshold.get () || (instanceCount - CircustRepuppedCount) <viestableserSholdTHOLD.get ()) {logger.deBughind ("ZavestableserThrosThrold.get ()) {logger. BlackoutserVerperCentage: {}, ActiveRequustsperserver: {}, Viewableservers: {} », New Object [] {(Double) CircuitBreakerpuppuppedCount / instanceCount, LoadPerserver, InstanceCount - CircuitHreakEdCount}); return false;} else {return True;}}} @Averd @auld @averde @averde @averde @averdide @averdide @averdide @averdide @averdide @averdide @averdide @averdide GetFilteredListofServers (List <T> Servers) {if (Zone! = NULL && (ZONEAFFINITY || ZENEXCLUICE) && Servers! = null && servers.size ()> 0) {Listservers = lists.newarraylist (iterables.filter (servers, servers, servers, servers, servers, servers, this.zoneaffintepredicate.getserveronlypredicate ());Во -первых, услуги той же зоны, что и потребительская сторона, будут отфильтрованы, а затем услуги той же зоны будут определяться с помощью shopeNablezoneaffinity (фильтрованные серверы), чтобы определить, могут ли услуги одной и той же зоны быть приняты или все услуги могут быть приняты.
В методе ShopeNableZoneaffinity можно сделать снимок для служб той же зоны, и количество экземпляров, средней нагрузки и количество экземпляров этих услуг получается для расчета и суждения.
Вы можете взглянуть на значения ключевых индикаторов в методе initwithniwsconfig.
Условия решения:
Процент автоматических выключателей> = 0,8 (количество автоматических выключателей/Количество экземпляров обслуживания)
Средняя нагрузка> = 0,6
Количество доступных экземпляров <2 (количество экземпляров - количество сломанных экземпляров)
Если условия суждения будут выполнены, то все услуги будут использоваться для обеспечения доступности.
Однако, как упомянуто выше, поскольку сам ZonePreferenceserverListfilter всегда выбирает услуги, которые соответствуют потребительским зонам, интеллектуальные операции, выполненные в ZoneaffinityServerlistfilter.getFilteredListofservers, бесполезны.
Однако, конечно, вы можете использовать экземпляры ZoneaffinityServerListFilter через пользовательские конфигурации.
3. Сохраните список отфильтрованной информации о обслуживании в LoadBalancerStats в качестве состояния.
Последующий updateAllServerList(servers); И идите глубже шаг за шагом, вы обнаружите, что он фактически сохраняется в LoadBalancerStats , а услуги в настоящее время сохраняются в структуре HashMap<String, List<Server>> в соответствии с группировкой зоны, а ключ - зона.
Выберите службу
Балансировщик нагрузки, который реализует интерфейс iloadbalancer, используется для выбора сервисов путем реализации метода выбора, а выбранная служба используется в качестве целевой службы запроса.
Взгляните на метод zoneawareloadbalancer.chooseserver.
Общедоступный сервер public server (ключ объекта) {if (! Enabled.get () || getLoadBalancerStats (). GetaVailablezones (). Size () <= 1) {logger.debug («Логика осведомленности о зоне отключена или есть только одна зона»); вернуть Super.chooseServer (Key); } Server server = null; try {loadbalancerstats lbstats = getLoadBalancerStats (); Map <string, zonesnapshot> ZonesNapShot = Zoneavoidancerule.createsnapshot (lbstats); logger.debug ("Зона снимки: {}", Zonesnapshot); if (triggeringload == null) {triggeringload = dynamicPropertyFactory.getInstance (). getDoubleProperty ("Zoneawareniwsdiscoveryloadbalancer." + this.getName () + ".triggeringPerserVerThroshold", 0,2d); } if (triggeringBlackoutPercentage == null) { triggeringBlackoutPercentage = DynamicPropertyFactory.getInstance().getDoubleProperty( "ZoneAwareNIWSDiscoveryLoadBalancer." + this.getName() + ".avoidZoneWithBlackoutPercetage", 0.99999d); } Set <String> offecons = zoneavoidancerule.getavailablezones (ZonesNapShot, TriggeringLoad.get (), TriggeringBlackOutperCentage.get ()); logger.debug ("Доступные зоны: {}", доступные зоны); if (of aflyzones! = null && affectzones.size () <zonesnapshot.keyset (). size ()) {string Zone = zoneavoidancerule.randomChoosezone (zonesnapshot, доступные зоны); logger.debug ("Зона выбрана: {}", Zone); if (Zone! = null) {baseloadbalancer Zoneloadbalancer = GetLoadBalancer (Zone); server = Zoneloadbalancer.chooseServer (ключ); }}} catch (Exception e) {logger.Error ("Ошибка выбора сервера с использованием логики зоны для нагрузки Balancer = {}", name, e); } if (server! = null) {return server; } else {logger.debug ("Логика избегания зон не вызывается."); вернуть Super.chooseServer (Key); }}Обратите внимание, что здесь есть два использования:
1. Выключите балансировку нагрузки с платой зоны, настраивая Zoneawareniwsdiscoveryloadbalancer.enabled = false, или количество зон <= 1.
2. Используйте восприятие зоны, или количество зон составляет> 1.
Давайте посмотрим один за другим
1. Выключите балансировку нагрузки с платой зоны, настраивая Zoneawareniwsdiscoveryloadbalancer.enabled = false, или количество зон <= 1.
В этом случае вызывается метод родительского класса BaseLoadBalancer.ChooseServer.
Общедоступный сервер выбирает server (object key) {if (counter == null) {counter = createCounter (); } counter.increment (); if (rule == null) {return null; } else {try {return rule.choose (key); } catch (Exception e) {logger.warn ("loadbalancer [{}]: ошибка выбора сервера для ключа {}", имя, ключ, e); вернуть ноль; }}}Правило политики балансировки нагрузки, используемое здесь, на самом деле представляет собой экземпляр политики Zoneavoidancerule, генерируемый на этапе конфигурации, который был передан при построении Zoneawareloadbalancer.
public void setrule (urule rule) {if (rule! = null) {this.rule = rug; } else { / * Правило по умолчанию * / this.rule = new RoundRobinRule (); } if (this.rule.getloadbalancer ()! = this) {this.rule.setloadbalancer (this); }}Предположим, что если нет конфигурации, используется экземпляр политики по умолчанию по умолчанию.
2. Используйте восприятие зоны, или количество зон составляет> 1.
Общедоступный сервер выбирает server (ключ объекта) {if (! enabled.get () || getLoadBalancerStats (). getaVailablezones (). size () <= 1) {logger.debug ("Зона по сознанию отключена или есть только одна зона"); вернуть Super.chooseServer (Key); } Server server = null; try {loadbalancerstats lbstats = getLoadBalancerStats (); Map <string, zonesnapshot> ZonesNapShot = Zoneavoidancerule.createsnapshot (lbstats); logger.debug ("Зона снимки: {}", Zonesnapshot); if (triggeringload == null) {triggeringload = dynamicPropertyFactory.getInstance (). getDoubleProperty ("Zoneawareniwsdiscoveryloadbalancer." + this.getName () + ".triggeringPerserVerThroshold", 0,2d); } if (triggeringBlackoutPercentage == null) { triggeringBlackoutPercentage = DynamicPropertyFactory.getInstance().getDoubleProperty( "ZoneAwareNIWSDiscoveryLoadBalancer." + this.getName() + ".avoidZoneWithBlackoutPercetage", 0.99999d); } Set <String> offecons = zoneavoidancerule.getavailablezones (ZonesNapShot, TriggeringLoad.get (), TriggeringBlackOutperCentage.get ()); logger.debug ("Доступные зоны: {}", доступные зоны); if (of aflyzones! = null && affectzones.size () <zonesnapshot.keyset (). size ()) {string Zone = zoneavoidancerule.randomChoosezone (zonesnapshot, доступные зоны); logger.debug ("Зона выбрана: {}", Zone); if (Zone! = null) {baseloadbalancer Zoneloadbalancer = GetLoadBalancer (Zone); server = Zoneloadbalancer.chooseServer (ключ); }}} catch (Exception e) {logger.Error ("Ошибка выбора сервера с использованием логики зоны для нагрузки Balancer = {}", name, e); } if (server! = null) {return server; } else {logger.debug ("Логика избегания зон не вызывается."); вернуть Super.chooseServer (Key); }}В этом случае политика балансировки нагрузки Zoneavoidancerule используется по умолчанию.
Получите информацию о снимке зоны.
Получите доступную зону, наблюдая за определением zoneavoidancerule.getavailablezones, условие, которое не имеет доступной зоны:
После того, как все доступные зоны получаются, выберите одну случайно.
И в этой зоне выберите службу через родительский класс Baseloadbalancer of Zoneawareloadbalancer.chooseServer. Как составлено выше, если в BaseloadAlcer не проходит правило, то политика RoundRobinRule используется по умолчанию, чтобы найти услугу.
Фактически, это все еще является проблемой получения фильтра ZonePreferencesserverListfilter выше. Фактически, только одна услуга с той же зоной, что и потребительская сторона, отфильтрована. Следовательно, функция выбора услуг из доступных зон в части 2 не может быть достигнута. Чтобы добраться до него, фильтр должен быть заменен.
Суммировать:
Настройка балансировщика нагрузки запустит график для получения информации об обслуживании. При использовании клиента Eureka вся информация о экземпляре службы будет получена из службы Eureka, а услуги, которые могут быть использованы, будут отфильтрованы через фильтр. По умолчанию фильтр будет только отфильтровывать услуги, которые совпадают с потребительской стороной. Если вы хотите обеспечить высокую доступность, вы можете настроить фильтр ZoneaffinityServerListFilter, а список фильтрованных услуг выберет соответствующую службу, внедрив политику балансировки нагрузки интерфейса IRULE. Если вы используете политику с учетом зоны, вы можете выбрать соответствующий сервис из зоны с хорошими условиями нагрузки.