Em seguida, vamos dar uma olhada em como obter a instância de serviço, que processamento foi feito após a obtenção e como selecionar a instância do serviço após o processamento.
Divida em três partes:
Configuração
Na seção de configuração do artigo anterior "Os princípios da fita da nuvem da primavera", você pode ver que o balanceador de carga padrão é zoneawareloadbalancer.
Dê uma olhada na classe de configuração.
Localização:
Spring-Cloud-Netflix-core-1.3.5.release.jarorg.springframework.cloud.netflix.ribbonRibBonClientConfiguration.class
@Suppresswarnings ("deprecação")@configuration@EnableConfigurationProperties // O pedido é importante aqui, o último deve ser o padrão, primeiro deve ser opcional // consulte Https://github.com/spring-cloud/spring-cloud-netflix/issues/2086#issuecomment-316281653@import( {khttprpritbonConfiguration.clls, restclientRibbonfiguration.cl), httttpclientRabbonfllass, restclientRibbonfiguration.cliSl) omit @Bean @conditionalonMissingBean ILOADBALLANCER RIPBONLOADBALANCER (ICLIENTCONFIG Config, ServerList <Verver> ServerList, ServerListFilter <Verver> serverListFilter, regra Irule, iping ping, serverlistUmerListupDater) {return this.propertiesfactory.get (iloadBalancer.class, config, nome); } Retornar novo ZoneawareloadBalancer <> (config, regra, ping, serverlist, serverlistfilter, serverlistupdater); } // omitido}Injetado no caso de Config, Regra, Ping, Serverlist, ServerListFilter, ServerListUpDater.
Config: configure a instância.
Regra: instância da política de equilíbrio de carga.
Ping: instância de ping.
Serverlist: recebe e atualiza uma instância do serviço.
ServerListFilter: Instância de filtragem de serviço.
ServerListupDater: Instância de atualização de informações da lista de serviços.
@Suppresswarnings ("deprecação")@configuration@EnableConfigurationProperties // O pedido é importante aqui, o último deve ser o padrão, primeiro deve ser opcional // consulte Https://github.com/spring-cloud/spring-cloud-netflix/issues/2086#issuecomment-316281653@import( {khttprpritbonConfiguration.clls, restclientRibbonfiguration.cl), httttpclientRabbonfllass, restclientRibbonfiguration.cliSl) omit @bean @conditionalonMissingBean Public ICLIENTCONFIG RibBonClientConfig () {defaultClientConfigImpl config = new DefaultClientConfigImpl (); config.loadproperties (this.name); return config; } @Bean @conditionalonMissingBean Irule ribbonRule (iClientConfig config) {if (this.propertiesFactory.isset (irule.class, nome)) {return this.propertiesFactory.get (irule.class, config, nome); } ZoneAvoidaCerule regra = new ZoneAVoDancerure (); regra.initwithniwsconfig (config); regra de retorno; } @Bean @ConditionalonMissingBean Public Iping Ribbonping (iClientConfig config) {if (this.propertiesFactory.isset (iping.class, nome)) {return this.propertiesFactory.get (iping.class, config, nome); } retornar novo dummyping (); } @Bean @ConditionalonMissingBean @SUPletSwarnings ("desmarcados") public ServerList <Verver> ribbonserverlist (iClientConfig config) {if (this.PropertiesFactory.isset (serverList.class, nome)) {return this.propertiesfactory.isset (serverlist.class, nome)) {return this.ProtiesFactory.get.get.get.getList.gnist.cllass, names) {retorn.propertiesfactory.get.get.getList.class, names); } ConfigurationBasedServerlist ServerList = new ConfigurationBasedServerList (); serverlist.initwithniwsconfig (config); retornar serverlist; } @Bean @ConditionalonMissingBean ServerListUpdater RibbonserverlistUpDater (iClientConfig config) {Return PollingServerlistUsTer (config); } @Bean @conditionalonMissingBean ILOADBALLANCER RIFBONLOADBALANCER (ICLIENTCONFIG Config, ServerList <Verver> serverListFilter <verver> serverlistfilter, regra irule, iping ping, serverlistupDaterListupDater) {se this.PropertiesFactory.get (iloadBalancer.class, config, nome); } Retornar novo ZoneawareloadBalancer <> (config, regra, ping, serverlist, serverlistfilter, serverlistupdater); } @Bean @ConditionalonMissingBean @SUPletSwarnings ("desmarcados") Public ServerListFilter <Verver> ribbonserverlistfilter (iClientConfig config) {if (this.PropertiesFactory.isset (serverListfilter.class, nome) { nome); } ZonePreferenceserverListFilter filter = new ZonePreferencesServerListFilter (); filtro.initwithniwsconfig (config); retorno filtro; } @Bean @ConditionalonMissingBean RibbonloadBonLoadBalancerContext RibBonLoadBalancerContext (ILOADBALANCER LOADBALANCER, ICLIENTCONFIG Config, RETRYHANDLER RETRYHANDLER) {Return RibBonLoadBalancerContext (LoadBalancer, Config, RetherHandman); } // omitido}Configure exemplos relevantes aqui
Config: DefaultClientConfigimpl.
Regra: Zoneavoidancerule.
Ping: Dummyping.
ServerList: ConfigurationBasedServerlist, Instância da lista de serviços baseada em configuração.
ServerListFilter: ZonePreferencesServerlistFilter.
ServerListUpDater: PollingServerListUpDater.
Deve -se notar que a instância do ServerList aqui é o ConfigurationBasedServerlist, que é uma instância que obtém informações de serviço quando o eureka não é usado e é obtido no arquivo de configuração.
Portanto, ao usar o Eureka, você precisa obter informações de serviço do Eureka Server. Qual instância deve ser usada para fazer isso?
Ao ativar a descoberta de serviços Eureka, a classe EurekaribBonClientConfiguration será adotada pela primeira vez.
Localização:
Spring-Cloud-Netflix-eureka-client-1.3.5.release.jarorg.springframework.cloud.netflix.ribbon.eurekaerekaribbonlientConfiguration.class
@Configuration @CommonsLogPublic Classe EurekaribBonClientConfiguration {// omit @Bean @conditionalonMissingBean Public Ipping Ribbonping (iClientConfig config) {if (this sPIRPERTIES.PropertiesFactory.isset (iping.class, serviceId) {ReturnFelfForties th ThisPerties. } NIWSDesCoveryPing ping = novo niwsDiscoveryPing (); ping.initwithniwsconfig (config); retornar ping; } @Bean @ConditionalonMissingBean ServerList public <?> Ribbonserverlist (iClientConfig Config, Provider <EureKaclient> EurekaclientProvider) {if (this.PropertiesFactory.issetList.class, serviceId) {ReturnThEstFactor.PropertiesfFactory.issetList.GerlAsS,) {iSt.PropertiesFactorsFactory.issetList.Gerl), } Descoberta eNabledNiWSServerlist DiscoveryServerlist = new DiscoveryEnabledNiWSServerlist (config, EurekaclientProvider); DomainextractingServerList ServerList = new DomAinextractingServerlist (DiscoveryServerlist, config, this.ApproximateZoneFromHostName); retornar serverlist; } // omitido}Depois de usar primeiro a configuração EurekaribBoLcientConfiguration, as instâncias realmente se tornam
Config: DefaultClientConfigimpl.
Regra: Zoneavoidancerule.
Ping: NIWSDescoveryping.
ServerList: DomAinextractingServerlist, Internamente DiscoveryEnabledNiWSServerlist, obtendo uma lista de informações de serviço através da descoberta de serviços.
ServerListFilter: ZonePreferencesServerlistFilter.
ServerListUpDater: PollingServerListUpDater.
Obtenha serviços
Antes de encontrar o acesso para obter informações sobre o serviço, primeiro edite a relação de herança da classe do balanceador de carga.
O construto DynamicSerVerListLancer da classe dos pais é chamado no construto do ZoneaWareloadBalancer.
Localização:
Ribbon-LargoBalancer-2.2.2.jar
com.netflix.loadBalancer
Zoneawareloadbalancer.class
Na construção do DynamicServerlistLoadBalancer, a função Restofinit é chamada.
Ribbon-LargoBalancer-2.2.2.jar
com.netflix.loadBalancer
DynamicServerListListBalancer.class
Void Restofinit (ICLIENTCONFIG CLIENTCONFIG) {boolean primeConnection = this.isenablePrimingConnections (); // Desligue isso para evitar o priming assíncrono duplicado realizado em baseloadbalancer.setServerlist () this.setEnablePrimingConnections (false); enableandinitlearnnewserversfeature (); updateListOfServers (); if (primeConnection && this.getPrimeconnections ()! = null) {this.getPriMeconnections () .PriMeconnections (getReachableservers ()); } this.setEnablePrimingConnections (primeConnection); Logger.Info ("DynamicServerListlloadBalancer para o cliente {} inicializado: {}", clientconfig.getClientName (), this.toString ()); }Primeiro, a lista de serviços é atualizada regularmente, chamando o método EnableandInitlearnNewServersFeature e, em seguida, chama imediatamente a função UpdateListOfServers para obter e atualizar as informações da lista de serviços imediatamente.
Vamos primeiro olhar para o método EnableandinitlearnNewServersFeature. De fato, o método inicial da instância de atualização de informações da lista de serviços é chamado para iniciar a função de atualização cronometrada.
/ ** * Recurso que nos permite adicionar novas instâncias (do AMIS) à lista de * servidores existentes que o LB usará chamando esse método se desejar esse * recurso ativado */ public void enableandNitlearnNewServersFeature () {Logger.info ("Usando serverlistUmater {}",, serverlistMer {server.info ("Usando serverlistUmater {}",, servidor () {Logger.info (" ServerListupDater.Start (UpdateAction); } O exemplo de atualização de informações da lista de serviços aqui está a instância PollingServerListUpDater configurada no estágio de configuração. Dê uma olhada no método de construção e início desta classe.
classe pública POLLINGSERVERLISTUPDATER implementa o serverListupDater {// private static listofservers_cache_update_delay = 1000; // msecs; private static int listofservers_cache_repeat_interval = 30 * 1000; // msecs; // private final atomicBoolean ISactive = new AtomicBoolean (false); Private Volátil Private LastUpdated = System.CurrentTimEmillis (); Private Final Long InitialDelayms; Private Final Long RefreshIntervalms; // ligeiramente public PollingServerListUpDater (ICLIENTCONFIG CLIENTCONFIG) {this (listOfServers_Cache_Update_Delay, getRefreshIntervalms (clientConfig)); } public PollingServerListUpDater (Long Long InitialDelayms, Final Longo RefReshIntervalms) {this.initialDelayms = InitialDelayms; this.RefReshInterValms = refShIntervalms; } @Override Public Syncronized void Iniciar (atualização final da atualização) {if (isactive.compareandSet (false, true)) {final runnable wrapderrunnable = new runnable () {@Override public void run () {if (! } retornar; } tente {updateAction.doupDate (); lastUpdated = System.CurrentTimemillis (); } catch (Exceção e) {Logger.warn ("Falha um ciclo de atualização", e); }}}}; scheduledfuture = getRefreshExecutor (). schedulewithfixedDelay (wrapperrunnable, inicialDelayms, refreshIntervalms, timeUnit.millisEconds); } else {logger.info ("já ativo, não-op"); }} // omita}A partir da construção e definição constante, a execução é adiada em um segundo e a atualização é realizada a cada 30 segundos por padrão. Você pode modificar o tempo de atualização entre a configuração.
A partir do método inicial, é abrir um cronograma que executa regularmente e execute a atualização.DoupDate () regularmente.
Volte para o método de início DynamicServerListLancer Class e dê uma olhada na definição da instância de atualização.
Final serverListUpdater.UpDateAction protegido atualização = new ServerListUpDater.UpDateAction () {@Override public void DoupDate () {updatelistofServers (); }};De fato, é chamado o método da DynamicServerlistLancer da UpdateListOfServers, que é consistente com o caminho para atualizar a lista de informações de serviço imediatamente após a atualização do tempo de inicialização.
Continue analisando o método UpdateListOfServers.
public void updateListOfServers () {list <t> servers = new ArrayList <T> (); if (serverListImpl! = null) {servers = serverlistimpl.getUpDatedListOfServers (); Logger.debug ("Lista de servidores para {} obtida do Discovery Client: {}", getIdentifier (), servidores); if (filtro! = null) {servers = filter.getFilteredListOfServers (servidores); Logger.debug ("Lista filtrada de servidores para {} obtida do Discovery Client: {}", getIdentifier (), servidores); }} updateAllServerlist (servidores); }1. Obtenha a lista de informações de serviço através da instância do ServerList.
2. Filtre a lista de informações de serviço obtida através da instância do ServerListFilter.
3. Salve a lista de informações de serviço filtrada no LoadBalancerStats como Hold State Hold.
Vamos dar uma olhada nele separadamente a seguir.
1. Obtenha a lista de informações de serviço através da instância do ServerList.
A instância do ServerList é o domainextractingServerlist gerado no estágio de configuração. As informações de serviço são delegadas ao DiscoveryEnabledNiWSServerlist.
public Class DiscoveryEnabledNiWSServerlist estende abstractServerlist <CiscoveryEnabledServer> {// omit @Override Public List <CiscoveryEnabledServer> getInitialListOfServers () {Return obtenServersViaDiscovery (); } @Override Public List <CiscoveryEnabledServer> getUpDatedListOfServers () {return obttenServersviadiscovery (); } Lista privada <CiscoveryEnabledServer> obtenServersViadiscovery () {list <CiscoveryEnabledServer> serverList = new ArrayList <CiscoveryEnabledServer> (); if (eurekaclientprovider == null || eurekaclientprovider.get () == null) {logger.warn ("Eurekaclient ainda não foi inicializado, retornando uma lista vazia"); retornar novo ArrayList <CiscoveryEnabledServer> (); } Eurekaclient eurekaclient = eurekaclientprovider.get (); if (vipaddresses! = null) {for (string vipaddress: vipaddresses.split (",")) {// se o TargetRegion for nulo, será interpretado como a mesma região da lista de clientes <temlowInfo> listOfinStanceInfo = EuRekaclient.getInSressbyVentsbeddress (vipddress> para (InstanceInfo II: listOfInstanceInfo) {if (ii.getStatus (). Equals (Instancestatus.up)) {if (deveuseoverrideport) {if (Logger.isdebugenabled ()) {Logger.debug ("substituindo o nome do cliente:" + clientname + "para" " } // A cópia é necessária, pois o Builder InstanceInfo apenas usa a referência original, // e não queremos corromper a cópia global eureka do objeto que pode ser usada por outros clientes em nosso sistema InstanceInfo cópia = new InstanceInfo (ii); if (isSCURE) {ii = new InstanceInfo.builder (cópia) .setSecureport (substituto) .build (); } else {ii = new InstanceInfo.builder (cópia) .setport (substituto) .build (); }} DiscoveryEnabledServer DES = new DiscoveryEnabledServer (II, emissor, deveuseipaddr); des.setzone (Discoveryclient.getzone (ii)); serverlist.add (DES); }} if (serverList.size ()> 0 && priorizevipaddressbasedservers) {break; // Se o VIPAddress atual tiver servidores, não usaremos servidores subsequentes baseados em Vipaddress}}} retornar serverlist; } // omitido}Pode -se observar que é realmente obter todas as informações da instância de serviço do servidor Eureka através do cliente Eureka e empacotar as instâncias on -line em DiscoveryEnabledServer, com informações da zona e colocá -las na lista de serviços.
2. Filtre a lista de informações de serviço obtida através da instância do ServerListFilter.
A instância do ServerListFilte é o ZonePreferenceserverListFilter gerado no estágio de configuração e é filtrado chamando o método getFilteredListOfServers do método da instância.
@Data@EqualSandHashCode (Callsuper = false) public class ZonePreferencesServerListFilter estende o ZoneaffinityServerListFilter <Verver> {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 <Verver> getFilteredListOfServers (List <Verver> servidores) {list <vider> output = super.getFilteredListOfServers (servidores); if (this.Zone! = null && output.size () == servers.size ()) {list <verver> local = new ArrayList <Verver> (); para (servidor servidor: output) {if (this.zone.equalsignorecase (server.getzone ())) {local.add (server); }} if (! local.isempty ()) {return local; }} retornar saída; }}No método GetFilteredListOfServers, a primeira coisa que você deseja é chamar o mesmo nome da classe pai para filtrar primeiro. De fato, a classe pai também filtra os serviços na mesma área que o lado do consumidor. Além disso, ele adiciona alguns julgamentos inteligentes para garantir que a filtragem na mesma área não seja realizada quando a falha/carga é alta ou quando há poucas instâncias disponíveis.
No entanto, no ZonePreferencesServerlistFilter.getFilteredListOfServers, mesmo que a classe pai não tenha filtrado, os serviços da mesma zona ainda precisam ser filtrados e usados. Quem disse que a aula aqui é o ZonePreference?
Isso é uma coisa estranha, e sente que o julgamento inteligente da classe pai não tem efeito.
Vamos dar uma olhada no trabalho árduo realizado pelo ZoneffinityServerlistFilter.getFilteredListOfServers.
Classe public zoneaffinityServerlistFilter <t estende o servidor> estende o abstrateServerlistFilter <t> implementa o iclientConfigaware {// Private boolean devenableZoneAffinity (list <t> filtrado) {if (! ZoneAffinity &&! } if (zoneexclusive) {return true; } LoadBalancerStats Stats = getLoadBalancerStats (); if (stats == null) {return zoneffinity; } else {Logger.debug ("Determinando se a afinidade da zona deve ser ativada na determinada lista do servidor: {}", filtrada); Zonesnapshot instantâneo = stats.getZonesNAPShot (filtrado); Double loadPerServer = snapshot.getLoadPerServer (); int instancecount = snapshot.getInstanceCount (); int circuitbreakertripdcount = snapshot.getCircuitTripedCount (); if ((((() CircuitbreakertripdCount) / InstanceCount> = BlackoutServerPorcentAgethreshold.get () || loadPerServer> = ActiveReqeustsPerServerthreshold.get () || (InstanCount - CircuitbreakertripdCount) <bodableServersthHold.get () () {Log.gger. BlackoutServerPerPentage: {}, ActiveReqeustsPerServer: {}, untilableServers: {} ", new Object [] {(Double) CircuitbreakertripedCount / InstanceCount, LouadPerServer, Return, Return, Return; getFilteredListOfServers (List <T> servidores) {if (zone! thesPrimeiro, os serviços da mesma zona que o lado do consumidor serão filtrados e, em seguida, os serviços da mesma zona serão determinados pela DevanableZoneAffinity (servidores filtrados) para determinar se os serviços da mesma zona podem ser adotados ou todos os serviços podem ser adotados.
No método devenableZoneffinity, um instantâneo é feito para serviços da mesma zona e o número de instâncias, carga média e número de instâncias desses serviços são obtidas para cálculo e julgamento.
Você pode dar uma olhada nos valores dos principais indicadores no método initwithniwsconfig.
Condições de decisão:
Porcentagem de disjuntores> = 0,8 (número de disjuntores/número de instâncias de serviço)
Carga média> = 0,6
Número de instâncias disponíveis <2 (número de instâncias - número de instâncias quebradas)
Se as condições de julgamento forem atendidas, todos os serviços serão usados para garantir a disponibilidade.
No entanto, como mencionado acima, como o próprio ZonePreferenceserVerListFilter sempre escolhe serviços que são consistentes com as zonas do consumidor, as operações inteligentes realizadas em zoneffinityServerlistFilter.getFilteredListOfServers não são inúteis.
No entanto, é claro, você pode usar instâncias ZoneffinityServerlistFilter através de configurações personalizadas.
3. Salve a lista de informações de serviço filtrada no LoadBalancerStats como Hold State Hold.
Acompanhar updateAllServerList(servers); E se aprofundará passo a passo, você descobrirá que ele é realmente salvo em LoadBalancerStats , e os serviços neste momento são salvos HashMap<String, List<Server>> estrutura de acordo com o agrupamento de zona, e a chave é a zona.
Selecione um serviço
O balanceador de carga que implementa a interface iloadBalancer é usado para selecionar serviços implementando o método ChoiceServer, e o serviço selecionado é usado como serviço de solicitação de destino.
Dê uma olhada no ZoneaWareloadBalancer.Chooseserver Method.
@Override Public Server ChooseServer (chave do objeto) {if (! Habiled.get () || getLoadBalancerStats (). GetAvailableZones (). Size () <= 1) {Logger.debug ("Zone Awardy Logic desativado ou existe apenas uma zona"); retornar super.Chooseserver (chave); } Servidor server = null; tente {loadBalancerStats lbstats = getLoadBalancerStats (); Mapa <string, zonesnapshot> zonesnapshot = zoneAvoidanceRule.createsnapshot (lbstats); Logger.debug ("Snapshots de zona: {}", zonesnapshot); if (triggeringLoad == null) {triggeringLoad = dynamicPropertyFactory.getInstance (). getDoubleProperty ("zoneawareniwsdiscoveryloadbalancer." + this.getName () + ".TriggeringLoadPerServerthShsHold", 0.2d); } if (triggeringblackoutPercentage == null) {triggeringBlackoutPercentage = DynamicPropertyFactory.getInstance (). } SET <String> disponívelZones = zonevoidancerule.getAvailableZones (zonesnapshot, triggeringload.get (), triggeringBlackoutPorcentage.get ()); Logger.debug ("Zonas disponíveis: {}", disponível em zones); if (disponível em zones! = null && disponível zones.size () <zonesnapshot.keyset (). size ()) {string zone = zoneAvoidancerule.randomChooseZona (zonesnapshot, zones disponíveis); Logger.debug ("Zona escolhida: {}", zone); if (zone! = null) {BaseloadBalancer zoLoadBalancer = getLoadBalancer (zone); Server = zoLoadBalancer.chooseserver (chave); }}} Catch (Exceção e) {Logger.error ("Erro Escolha do servidor usando a lógica da zona para o balanceador de carga = {}", nome, e); } if (server! = null) {return server; } else {Logger.debug ("A lógica de prevenção de zona não é invocada."); retornar super.Chooseserver (chave); }}Observe que existem dois usos aqui:
1. Desligue o balanceamento de carga com reconhecimento de zona, configurando o zoneawareniwsdiscoveryloadbalancer.enabled = false, ou o número de zonas <= 1.
2. Use a percepção da zona, ou o número de zonas é> 1.
Vamos dar uma olhada um por um
1. Desligue o balanceamento de carga com reconhecimento de zona, configurando o zoneawareniwsdiscoveryloadbalancer.enabled = false, ou o número de zonas <= 1.
Nesse caso, o método da classe dos pais é chamado.
servidor público escolheServer (chave do objeto) {if (contador == null) {contador = createCounter (); } contador.increment (); if (regra == null) {return null; } else {try {return regra.choose (key); } catch (Exceção e) {Logger.warn ("LoadBalancer [{}]: Erro escolha servidor para chave {}", nome, chave, e); retornar nulo; }}}A regra de política de balanceamento de carga usada aqui é na verdade a instância da política do ZoneAVoDancerule gerada durante a fase de configuração que foi transmitida ao construir o zoneawareloadbalancer.
public void setRule (regra irule) {if (regra! = null) {this.rule = regra; } else { / * regra padrão * / this.rule = new RoundRobinRule (); } if (this.rule.getLoadBalancer ()! = this) {this.rule.setloadBalancer (this); }}Suponha que, se não houver configuração, a instância de política do RoundRobinRule padrão será usada.
2. Use a percepção da zona, ou o número de zonas é> 1.
servidor público escolheerver (chave do objeto) {if (! Habiled.get () || getLoadBalancerStats (). getAvailableZones (). size () <= 1) {Logger.debug ("Lógica atky da zona desativada ou existe apenas uma zona"); retornar super.Chooseserver (chave); } Servidor server = null; tente {loadBalancerStats lbstats = getLoadBalancerStats (); Mapa <string, zonesnapshot> zonesnapshot = zoneAvoidanceRule.createsnapshot (lbstats); Logger.debug ("Snapshots de zona: {}", zonesnapshot); if (triggeringLoad == null) {triggeringLoad = dynamicPropertyFactory.getInstance (). getDoubleProperty ("zoneawareniwsdiscoveryloadbalancer." + this.getName () + ".TriggeringLoadPerServerthShsHold", 0.2d); } if (triggeringblackoutPercentage == null) {triggeringBlackoutPercentage = DynamicPropertyFactory.getInstance (). } SET <String> disponívelZones = zonevoidancerule.getAvailableZones (zonesnapshot, triggeringload.get (), triggeringBlackoutPorcentage.get ()); Logger.debug ("Zonas disponíveis: {}", disponível em zones); if (disponível em zones! = null && disponível zones.size () <zonesnapshot.keyset (). size ()) {string zone = zoneAvoidancerule.randomChooseZona (zonesnapshot, zones disponíveis); Logger.debug ("Zona escolhida: {}", zone); if (zone! = null) {BaseloadBalancer zoLoadBalancer = getLoadBalancer (zone); Server = zoLoadBalancer.chooseserver (chave); }}} Catch (Exceção e) {Logger.error ("Erro Escolha do servidor usando a lógica da zona para o balanceador de carga = {}", nome, e); } if (server! = null) {return server; } else {Logger.debug ("A lógica de prevenção de zona não é invocada."); retornar super.Chooseserver (chave); }}Nesse caso, a política de balanceamento de carga do ZoneAvoidaCerule é usada por padrão.
Obtenha as informações instantâneas da zona.
Obtenha a zona disponível, observando a definição de zonevoidancerule.getAvailableZones, a condição de que não a zona disponível é:
Depois que todas as zonas disponíveis são obtidas, escolha uma aleatoriamente.
E a partir desta zona, selecione o serviço através da classe pai BaseLoadBalancer do ZoneawareloadBalancer.Chooseserver. Como compilado acima, se nenhuma regra for aprovada no BaseloadBalancer, a política RoundRobinRule será usada por padrão para encontrar um serviço.
De fato, ainda é o problema de obter o filtro ZonePreferencesServerListFilter acima. De fato, apenas um serviço com a mesma zona que o lado do consumidor é filtrado. Portanto, a função de selecionar serviços das zonas disponíveis na Parte 2 não pode ser alcançada. Para alcançá -lo, o filtro deve ser substituído.
Resumir:
O balanceador de carga configurado iniciará o cronograma para obter informações de serviço. Ao usar o cliente Eureka, todas as informações da instância do serviço serão obtidas no serviço Eureka e os serviços que podem ser usados serão filtrados através do filtro. Por padrão, o filtro filtra apenas os serviços que são os mesmos do lado do consumidor. Se você deseja garantir alta disponibilidade, pode configurar o filtro ZoneffinityServerlistFilter, e a lista de serviços filtrados selecionará o serviço correspondente implementando a política de balanceamento de carga da interface Irule. Se você usar a política com reconhecimento de zona, poderá selecionar o serviço apropriado da zona com boas condições de carga.