A continuación, echemos un vistazo a cómo obtener la instancia del servicio, qué procesamiento se ha realizado después de obtener y cómo seleccionar la instancia del servicio después del procesamiento.
Dividir en tres partes:
Configuración
En la sección de configuración del artículo anterior "Los principios de la cinta de nubes de resorte", puede ver que el equilibrador de carga predeterminado es Zoneawareloadbalancer.
Eche un vistazo a la clase de configuración.
Ubicación:
Spring-Cloud-Netflix-Core-1.3.5.Release.jarorg.springframework.cloud.netflix.ribbonribbonclientConfiguration.class
@Suppleswarnings ("deprecation")@configuration@enableConfigurationProperties // El pedido es importante aquí, el último debe ser el valor predeterminado, primero debería ser opcional // ver https://github.com/spring-cloud/spring-cloud-netflix/issues/2086#issuecomment-316281653@import({okhtttpibbonconfiguration.class, RestClientRibbonconfiguration.classs, httpclientRibonconfiguration.class}) omitir @Bean @conditionalonmissingBean public iLoadBalancer RibbonLoadBalancer (iclientConfig config, serverList <verver> ServerList, ServerListFilter <verver> ServerListFilter, Irule Rule, iPing Ping, ServerListupDater ServerListUpDater) {if esta.propertiesfactory.isset (OlilOaDAscer. {return this.propertiesfactory.get (iloadbalancer.class, config, nombre); } return New ZoneaAwareloadBalancer <> (config, regla, ping, serverlist, serverlistfilter, serverlistupdater); } // omitido}Inyectado en la instancia de config, regla, ping, serverlist, serverlistfilter, serverlistupdater.
config: configure la instancia.
Regla: instancia de política de equilibrio de carga.
Ping: instancia de ping.
ServerList: obtiene y actualiza una instancia del servicio.
ServerListFilter: instancia de filtrado de servicio.
ServerListUpdater: instancia de actualización de información de la lista de servicios.
@Suppleswarnings ("deprecation")@configuration@enableConfigurationProperties // El pedido es importante aquí, el último debe ser el valor predeterminado, primero debería ser opcional // ver https://github.com/spring-cloud/spring-cloud-netflix/issues/2086#issuecomment-316281653@import({okhtttpibbonconfiguration.class, RestClientRibbonconfiguration.classs, httpclientRibonconfiguration.class}) omitir @Bean @conditionAlonMissingBean public iClientConfig RibbonClientConfig () {defaultClientConfigImpl config = new DefaultClientConfigImpl (); config.loadProperties (this.name); return config; } @Bean @conditionAlonMissingBean Public irule Ribbonrule (iclientConfig config) {if (this.propertiesfactory.isset (irule.class, name)) {return this.propertiesfactory.get (irule.class, config, name); } Regla de zoneavaidancerule = nueva zoneAvaidanCerule (); reglas.initWithNiWSconfig (config); regla de retorno; } @Bean @conditionAlonMissingBean Public Iping Ribbonping (iclientConfig config) {if (this.propertiesfactory.isset (iping.class, name)) {return this.propertiesfactory.get (iping.class, config, name); } return new DumMyping (); } @Bean @ConditionAlonMissingBean @SupessWarnings ("sin verificar") Public ServerList <Server> RibBonSerVerList (iclientConfig config) {if (this.propertiesfactory.isset (serverlist.class, name)) {return this.propertiesfactory.class.class, configuración, configuración, nombre); } ConfigurationBasedServerList ServerList = new ConfigurationBasedServerList (); servidorList.initWithNiWSconfig (config); return ServerList; } @Bean @conditionAlonMissingBean Public ServerListUpdater RibBonServerListUpdater (iclientConfig config) {return New PollingServerListUpdater (config); } @Bean @conditionAlonMissingBean Public ILOAdBalancer RibbonLoadBalancer (iclientConfig config, serverList <verver> ServerListFilter <verver> ServerListFilter, Irule Rule, Iping Ping, ServerListupDupdAnserListUpdator this.propertiesfactory.get (iloadbalancer.class, config, nombre); } return New ZoneaAwareloadBalancer <> (config, regla, ping, serverlist, serverlistfilter, serverlistupdater); } @Bean @conditionAlonMissingBean @SupessWarnings ("no verchado") público ServerListFilter <Server> RibBonServerListFilter (iClientConfig config) {if (this.propertiesFactory.isset (serverListFilter.Class, nombre) {return this.propertiesfactory.get (servidor, filter. nombre); } ZonePreferenceserListFilter Filter = new ZonePreferenceserverListFilter (); filtro.initWithNiWSconfig (config); Filtro de retorno; } @Bean @conditionAlonMissingBean RibbonLoadBalancercontext RibbonLoadBalancercontext (iloadBalancer LoadBalancer, IClientConfig config, RetryHandler RetryHandler) {return New RibbonLoadBalancercontext (LoadBalancer, config, retrynhandler); } // omitido}Configurar ejemplos relevantes aquí
config: defaultClientConfigImpl.
Regla: ZoneAvaidancerule.
Ping: Dummyping.
ServerList: ConfigurationBasedServerList, instancia de lista de servicios basada en la configuración.
ServerListFilter: ZonePreferenceserverListFilter.
ServerListUpdater: PollingServerListUpdater.
Cabe señalar que la instancia de ServerList aquí es ConfigurationBasedServerList, que es una instancia que obtiene información de servicio cuando Eureka no se usa, y se obtiene del archivo de configuración.
Entonces, al usar Eureka, debe obtener información de servicio de Eureka Server. ¿Qué instancia debe usarse para hacer esto?
Al habilitar el descubrimiento de servicios de Eureka, la clase de configuración EurekaribbonClientConfiguration se adoptará primero.
Ubicación:
Spring-Cloud-Netflix-eureka-Client-1.3.5.Release.jarorg.springframework.cloud.netflix.ribbon.eurekaeurekaribbonclientconfiguration.class
@Configuración @commonslogpublic clase eurekaribbonClientConfiguration {// omite @Bean @ConditionAlonMissingBean Public Iping Ribbonping (iclientConfig config) {if (this.propertiesfactory.isset (iPing.class, servicioD)) {return this.propertiesfactory.get (iPing.class, configuración, configuración, configuración, configuración, configuración); } Niwsdiscoveryping ping = new niwsDiscoveryPing (); ping.initwithniwsconfig (config); devolver ping; } @Bean @conditionAlonMissingBean Public ServerList <?> RibBonserverList (ICLIENTCONFIG CONFIG, Provider <eurekaclient> eurekaclientProvider) {if (this.propertiesfactory.isset (serverList.class, servicioid)) {devuelve thant.propertiesfactory.get (serverlist.class, classet, Servicio, Servicio; } DiscoveryEnnableNIWSServerList DiscoveryServerList = new DiscoveryEnableNIWSServerList (config, eurekaclientProvider); DomaineExtractingServerList serverList = new DomainExtractingServerList (DiscoverServerList, config, this.ApproximeZoneFromHostName); return ServerList; } // omitido}Después de usar primero la configuración de EurekaribbonClientConfiguration, las instancias se convierten en
config: defaultClientConfigImpl.
Regla: ZoneAvaidancerule.
Ping: NiwsDiscOverying.
ServerList: DomainExtractingServerList, DiscoveryEnsableNedNiWSServerList, en realidad, obteniendo una lista de información de servicio a través del descubrimiento de servicios.
ServerListFilter: ZonePreferenceserverListFilter.
ServerListUpdater: PollingServerListUpdater.
Obtener servicios
Antes de encontrar el acceso para obtener información del servicio, primero edite la relación de herencia de clase del equilibrador de carga.
La construcción principal de la clase DynamicServerListloadBalancer se llama en la construcción de Zoneawareloadbalancer.
Ubicación:
Ribbon-LoadBalancer-2.2.2.Jar
com.netflix.loadBalancer
Zoneawareloadbalancer.class
En la construcción de DynamicserverListloadBalancer, se llama la función RETOFINIT.
Ribbon-LoadBalancer-2.2.2.Jar
com.netflix.loadBalancer
DynamicServerListloadBalancer.class
Void RAYFINIT (ICLIENTCONFIG CLIENTCONFIG) {boolean primeconnection = this.IsenablePrimingConnections (); // Apague esto para evitar el cebado asincrónico duplicado realizado en Baseloadbalancer.setServerList () this.SetenablePrimingConnections (FALSE); EnlElEndInitLearnNeWServersFeature (); updateListofServers (); if (primeConnection && this.getPrimeConnections ()! = NULL) {this.getPrimeConnections () .PrimeConnections (getReachableServers ()); } this.SetenablePrimingConnections (Primeconnection); Logger.info ("DynamicServerListloadBalancer para cliente {} inicializado: {}", clientCig.getClientName (), this.ToString ()); }Primero, la lista de servicios se actualiza regularmente llamando al método EnableAndinitLearnNewserversFeatureFeature, y luego llame inmediatamente a la función UpdateListOfServers para obtener y actualizar la información de la lista de servicios de inmediato.
Primero veamos el método habilitativo de ewsewserversfeatureFeature. De hecho, se llama al método de inicio de la instancia de actualización de información de la lista de servicios para iniciar la función de actualización cronometrada.
/ ** * característica que nos permite agregar nuevas instancias (de AMIS) a la lista de * servidores existentes que el LB usará Llamar a este método si desea esta característica habilitada */ public void enBeaBeAndInitLearnNewsNewsFeatueFeate () {logger.info ("Uso de servidorListupDater {}", serverListupDater.getClass (). ServerListUpdater.Start (UpdateAction); } El ejemplo de la actualización de la información de la lista de servicios aquí es la instancia PollingServerListUpdater configurada en la etapa de configuración. Eche un vistazo al método de construcción e inicio de esta clase.
Public Class PollingServerListupdater implementa ServerListupdater {// Private static longOfServers_cache_update_delay = 1000; // msecs; privado static int listOfServers_cache_repeat_interval = 30 * 1000; // msecs; // ISACTIVE ATOMICBOOLEA FINAL PRIVADO = new AtomicBoolean (falso); Volátil privado durante mucho tiempo se dastupdated = System.CurrentTimemillis (); Private final Long InitialDelayms; Privado final de actualización larga final; // PollingServerListUpdater ligeramente público (iClientConfig ClientConfig) {this (listOfServers_cache_update_delay, getRefreshIntervalms (ClientConfig)); } Public PollingServerListUpdater (final Long InitialDelayms, Final Long Refreshintervalms) {this.initialDelayms = initialDelayms; this.RefreshIntervalms = RefreshIntervalms; } @Override public sincronized void start (final de actualización de actualización) {if (isActive.CompareAndSet (false, true)) {final runnable wrapPRUrRunnable = new runnable () {@Override public Void void () {if (! Isactive.get ()) {if programado! } devolver; } try {updateAction.DoupDate (); LastUpdated = System.CurrentTimemillis (); } capt (excepción e) {logger.warn ("falló un ciclo de actualización", e); }}}}; ProchuledFuture = getRefreshExecutor (). SchedulewithFixedDelay (WRAPPERRUNABLE, INITIALDELAYMS, RefreshIntervalms, TimeUnit.MilliseConds); } else {logger.info ("ya activo, no-op"); }} // omit}De la construcción y la definición constante, la ejecución se retrasa en un segundo y la actualización se realiza cada 30 segundos de forma predeterminada. Puede modificar el tiempo de actualización entre la configuración.
Desde el método de inicio, es abrir un cronograma que se ejecute regularmente y ejecutar UpdateAction.DoupDate () regularmente.
Vuelva a la clase de Start Method Caller DynamicServerListloadBalancer y eche un vistazo a la definición de la instancia de UpdateAction.
Serverlistupdater final protegido. }};
De hecho, se llama a la clase UpdateListOfServers de la clase DynamicServerListloadBalancer, que es consistente con la ruta para actualizar la lista de información del servicio inmediatamente después de la actualización del tiempo de inicio.
Continúe mirando el método UpdateListOfServers.
public void UpdateListOfServers () {list <t> servidores = new ArrayList <T> (); if (serverListImpl! = NULL) {SERVERS = ServerListImpl.getUpdatedListOfServers (); Logger.debug ("Lista de servidores para {} obtenidos de Discovery Client: {}", getIdentifier (), servidores); if (filtre! = null) {servidores = filtro.getFilteredListOfServers (servidores); Logger.debug ("Lista filtrada de servidores para {} obtenido de Discovery Client: {}", getIdentifier (), servidores); }} updateAllServerList (servidores); }1. Obtenga la lista de información del servicio a través de la instancia de ServerList.
2. Filtre la lista de información de servicio obtenida a través de la instancia de ServerListFilter.
3. Guarde la lista de información del servicio filtrado en LoadBalancerStats como Hold State.
Echemos un vistazo a él por separado a continuación.
1. Obtenga la lista de información del servicio a través de la instancia de ServerList.
La instancia de ServerList es el DomainExtractingServerList generado en la etapa de configuración. La información del servicio se delega a DiscoveryEnableNiwsServerList.
Public Class DiscoveryEnnabledNIWSServerList extiende AbstractServerList <DiscoveryEnseDServer> {// omitir @Override Public List <ScubedyEnsegeServer> getInitialListofServers () {return obtenedServersViAdiscovery (); } @Override Public List <ScubedInEndServer> getUpdatedListofServers () {return obtenedServersViAdScovery (); } Lista privada <ScubedInEndServer> ObtenerServersViAdiscovery () {List <ScubedInEndServer> ServerList = New ArrayList <ScubedInEndServer> (); if (eurekaclientProvider == null || eurekaclientProvider.get () == null) {logger.warn ("eurekaclient aún no se ha inicializado, devolviendo una lista vacía"); devolver nuevo ArrayList <ScubedInEndServer> (); } Eurekaclient eurekaclient = eurekaclientProvider.get (); if (vipAddresses! = null) {for (string vipAddress: vipAddresses.split (",")) {// Si la región de Target es nulo, se interpretará como la misma región de la lista de clientes <Sistenfo> LiToFinStanceInfo = eureKaclient.getinstancesbyvipaddress (Vipaddress, issecure, IdInstance, INSTACE,); for (instanceInfo II: listOfInStanceInfo) {if (ii.getStatus (). Equals (instancEsTatus.up)) {if (debería sereverrideport) {if (logger.isdebugeNabled ()) {logger.debug ("anular el puerto en el nombre del cliente:" + clientName + "a" + overideport); } // La copia es necesaria ya que el generador de InstanceInfo solo usa la referencia original, // y no queremos corromper la copia global eureka del objeto que puede ser // utilizada por otros clientes en nuestro sistema InstanceInfo Copy = new instanceInfo (ii); if (issecure) {ii = new InstanceInfo.Builder (Copy) .SetSeSecurePort (overRidEport) .Build (); } else {ii = new InstanceInfo.Builder (copy) .SetPort (overRideport) .Build (); }} DiscoveryEnabledServer des = new DiscoveryEnableServer (II, issecure, deberá UuseipAddr); des.setzone (DiscoveryClient.getzone (ii)); ServerList.Add (DES); }} if (serverList.size ()> 0 && prioritizeVipAddressBasedServers) {break; // Si el vipaddress actual tiene servidores, no utilizamos servidores basados en vipaddress posteriores}}} return ServerList; } // omitido}Se puede ver que en realidad es para obtener toda la información de instancia de servicio del servidor Eureka a través del cliente Eureka y empaquetar los en línea en las instancias DiscoveryEnseBiledServer, con información de zona, y ponerlos en la lista de servicios.
2. Filtre la lista de información de servicio obtenida a través de la instancia de ServerListFilter.
La instancia de ServerListFilte es la zonaPreferenceServerListFilter generada en la etapa de configuración, y se filtra llamando al método getFilteredListOfServers de la instancia.
@Data@EqualsAndHashCode (llamadouper = false) Public Class ZonePreferenceServerListFilter extiende ZoneAffinityServerListFilter <Server> {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 <Server> getFilteredListOfServers (List <Server> servidores) {List <Server> output = Super.getFilteredListOfServers (servidores); if (this.zone! = null && output.size () == SERVERS.SIZE ()) {LIST <SERVER> local = new ArrayList <Server> (); for (servidor servidor: output) {if (this.zone.equalSignorecase (server.getzone ())) {local.add (servidor); }} if (! local.isEmpty ()) {return local; }} salida de retorno; }}En el método GetFilteredListOfServers, lo primero que desea es llamar al mismo nombre de la clase principal para filtrar primero. De hecho, la clase principal también filtra los servicios en la misma área que el lado del consumidor. No solo eso, agrega algunos juicios inteligentes para garantizar que el filtrado en la misma área no se realice cuando la falla/carga es alta o cuando hay pocas instancias disponibles.
Sin embargo, en ZonePreferenceserverListFilter.getFilteredListOfServers, incluso si la clase principal no se ha filtrado, los servicios de la misma zona aún deben filtrarse y usarse. ¿Quién dijo que la clase aquí es ZonePreference?
Esto es algo bastante extraño, y se siente que el juicio inteligente de la clase principal no tiene ningún efecto.
Echemos un vistazo al arduo trabajo realizado por ZoneffinityServerListFilter.getFilteredListOfServers.
clase pública ZoneAffinityServerListFilter <t extiende el servidor> extiende AbstractServerListFilter <T> implementa ICLIENTCONFIGAWAWAWE {// Private Boolean ShouldenableZonEafinity (List <T> Filtered) {if (! Zoneaffinity &&! ZoneExCluse) {return False; } if (ZoneExClusive) {return true; } LoadBalancerStats stats = GetLoadBalancerStats (); if (stats == null) {return zoneAffinity; } else {logger.debug ("determinar si la afinidad de la zona debe habilitarse con la lista de servidores dada: {}", filtrado); ZonesnapShot Snapshot = stats.getZonesNapShot (filtrado); Double LoadPerServer = Snapshot.getLoadPerServer (); int instancecount = snapshot.getInstanCount (); int CircuitBreakerTrippedCount = Snapshot.getCircuittripedCount (); if ((((((doble) CircuitBreakerTrippedCount) / InstancECount> = BlackoutServerCentCentAgethReshold.get () || LoadPerServer> = ActivereqeustSperserverververthreshold.get () || (InstanceCount - Circuit BreakerTrippedCount) <AsonseDonververSvershReshold.get () {logger.DebUg ("ZonEAffinity es ovelablefain. BlackoutServerPermentage: {}, activeqeustSperserver: {}, Disponibleervers: {} ", nuevo objeto [] {(double) CircuitBreakerTrippedCount / InstancECount, LoadPerServer, InstanceCount - CircuitBreakerTrippedCount}; getFilteredListofServers (List <T> Servers) {if (Zone! = Null && (ZoneAffinity || ZoneExClusive) && Servers! = Null && Servers.Size ()> 0) {List <T> FilteredServers = lists.newarrayList (iterable.filter (Servers (Servers,,,, Servers,,,,, Servers,,,,, Servers,,,, Servers,,,, Servers,,, Servers,,,, Servers,,,, Servers,,,, Servers,,, Servers,,,, Servers,,, Servers,,, Servers,,, Servers,,, Servers,,, Servers,, Servers,,, Servers,,, Servers,. this.zoneAffinityPredicate.getServerUnlyPredicate ());Primero, los servicios de la misma zona que el lado del consumidor se filtrarán, y luego los servicios de la misma zona estarán determinados por ShouldAnableZonEafinity (FilteredServers) para determinar si se pueden adoptar los servicios de la misma zona o todos los servicios se pueden adoptar.
En el método SupenableZonEaffinity, se realiza una instantánea para los servicios de la misma zona, y el número de instancias, la carga promedio y el número de instancias de estos servicios se obtienen para el cálculo y el juicio.
Puede echar un vistazo a los valores de los indicadores clave en el método initWithNiWSconFig.
Condiciones de decisión:
Porcentaje de interruptores de circuitos> = 0.8 (número de interruptores de circuitos/número de instancias de servicio)
Carga promedio> = 0.6
Número de instancias disponibles <2 (número de instancias - número de instancias que están rotas)
Si se cumplen las condiciones del juicio, se utilizarán todos los servicios para garantizar la disponibilidad.
Sin embargo, como se mencionó anteriormente, debido a que ZonePreferenceserverListFilter siempre elige los servicios que son consistentes con las zonas de consumo, las operaciones inteligentes realizadas en ZonEaffinityServerListFilter.getFilteredListOfServers no sirven de nada.
Sin embargo, por supuesto, puede usar las instancias de ZoneFinityServerListFilter a través de configuraciones personalizadas.
3. Guarde la lista de información del servicio filtrado en LoadBalancerStats como Hold State.
Seguimiento updateAllServerList(servers); Y profundice paso a paso, descubrirá que en realidad se guarda en LoadBalancerStats , y los servicios en este momento se guardan en HashMap<String, List<Server>> de acuerdo con la agrupación de la zona, y la clave es la zona.
Seleccione un servicio
El equilibrador de carga que implementa la interfaz iloadbalancer se utiliza para seleccionar los servicios implementando el método Choiceserver, y el servicio seleccionado se utiliza como el servicio de solicitud de destino.
Eche un vistazo al ZoneaAwareloadbalancer.
@Override Public Server eligeServer (Key de objeto) {if (! Endabled.get () || getLoadBalancerStats (). GetAVailableZones (). Size () <= 1) {logger.debug ("Zone Aking Logic Disable o solo hay una zona"); return super.Choosserver (clave); } Server Server = null; intente {LoadBalancerStats lbstats = GetLoadBalancerStats (); Map <string, zonesnapshot> zonesnapshot = zoneAvaidancerule.createSnapshot (lbstats); logger.debug ("Snapshots de zona: {}", zonesnapshot); if (TriggeringLoad == NULL) {TriggeringLoad = DynamicPropertyFactory.getInstance (). } if (TriggeringBlackOutPentMentage == NULL) {TriggeringBlackOutPentEcentage = DynamicPropertyFactory.getInstance (). } Set <String> DisponibleZones = ZoneAvaidanCerule.getAVailableZones (ZonesNapShot, TriggeringLoad.get (), TriggeringBlackOutPentMentage.get ()); logger.debug ("Zonas disponibles: {}", DisponibleZones); if (disponibleZones! = NULL && DisponlyZones.Size () <zonesnapshot.keySet (). size ()) {string zone = zoneAvaidanCerule.randomchoosezone (Zonesnapshot, disponible Zonas); logger.debug ("Zona elegida: {}", zona); if (zona! = null) {Baseloadbalancer zoneloadbalancer = getLoadBalancer (zona); servidor = ZoneloadBalancer.ChoosServer (clave); }}} Catch (Exception e) {logger.error ("Error al elegir el servidor usando la lógica de la zona consciente para la carga equilibradora = {}", nombre, e); } if (servidor! = null) {devuelve servidor; } else {logger.debug ("La lógica de evitación de zona no está invocada"); return super.Choosserver (clave); }}Tenga en cuenta que hay dos usos aquí:
1. Apague el equilibrio de carga de la zona al configurar zoneawareniwsdiscoveryloadBalancer.enabled = false, o el número de zonas <= 1.
2. Use la percepción de la zona, o el número de zonas es> 1.
Echemos un vistazo uno por uno
1. Apague el equilibrio de carga de la zona al configurar zoneawareniwsdiscoveryloadBalancer.enabled = false, o el número de zonas <= 1.
En este caso, se llama a la clase principal Baseloadbalancer. Se llama al método de opuesto.
Public Server eligeServer (clave de objeto) {if (contador == null) {contador = createCounter (); } contador.increment (); if (regla == null) {return null; } else {try {return regla.Choose (clave); } Catch (Exception e) {logger.warn ("LoadBalancer [{}]: Error al elegir servidor para la clave {}", nombre, clave, e); regresar nulo; }}}La regla de la política de equilibrio de carga utilizada aquí es en realidad la instancia de la política de ZoneAvaidancerule generada durante la fase de configuración que se transmitió cuando se construye el ZoneaAwareloadbalancer.
public void setRule (regla irule) {if (regla! = null) {this.rule = regla; } else { / * regla predeterminada * / this.rule = new RoundRobinRule (); } if (this.rule.getLoadBalancer ()! = this) {this.rule.setloadBalancer (this); }}Suponga que si no hay configuración, se utiliza la instancia de política RoundRobinRule predeterminada.
2. Use la percepción de la zona, o el número de zonas es> 1.
Public Server eligeServer (Key de objeto) {if (! Enabled.get () || getLoadBalancerStats (). GetAVailableZones (). Size () <= 1) {logger.debug ("Zone Aking Logic deshabilitado o solo hay una zona"); return super.Choosserver (clave); } Server Server = null; intente {LoadBalancerStats lbstats = GetLoadBalancerStats (); Map <string, zonesnapshot> zonesnapshot = zoneAvaidancerule.createSnapshot (lbstats); logger.debug ("Snapshots de zona: {}", zonesnapshot); if (TriggeringLoad == NULL) {TriggeringLoad = DynamicPropertyFactory.getInstance (). } if (TriggeringBlackOutPentMentage == NULL) {TriggeringBlackOutPentEcentage = DynamicPropertyFactory.getInstance (). } Set <String> DisponibleZones = ZoneAvaidanCerule.getAVailableZones (ZonesNapShot, TriggeringLoad.get (), TriggeringBlackOutPentMentage.get ()); logger.debug ("Zonas disponibles: {}", DisponibleZones); if (disponibleZones! = NULL && DisponlyZones.Size () <zonesnapshot.keySet (). size ()) {string zone = zoneAvaidanCerule.randomchoosezone (Zonesnapshot, disponible Zonas); logger.debug ("Zona elegida: {}", zona); if (zona! = null) {Baseloadbalancer zoneloadbalancer = getLoadBalancer (zona); servidor = ZoneloadBalancer.ChoosServer (clave); }}} Catch (Exception e) {logger.error ("Error al elegir el servidor usando la lógica de la zona consciente para la carga equilibradora = {}", nombre, e); } if (servidor! = null) {devuelve servidor; } else {logger.debug ("La lógica de evitación de zona no está invocada"); return super.Choosserver (clave); }}En este caso, la política de equilibrio de carga ZoneAvaidanCerule se usa de forma predeterminada.
Obtenga la información de la zona de la zona.
Obtenga la zona disponible, observando la definición de ZoneAvaidanCerule.getAVailableZones, la condición de que no la zona disponible es:
Después de obtener todas las zonas disponibles, elija una al azar.
Y desde esta zona, seleccione el servicio a través de la clase matriz Baseloadbalancer de Zoneawareloadbalancer.Choosserver. Como se compiló anteriormente, si no se pasa ninguna regla en Baseloadbalancer, entonces la política RoundRobinRule se utiliza de forma predeterminada para encontrar un servicio.
De hecho, sigue siendo el problema de obtener el filtro ZonePreferenceserverListFilter anterior. De hecho, solo se filtra un servicio con la misma zona que el lado del consumidor. Por lo tanto, no se puede lograr la función de seleccionar servicios de las zonas disponibles en la Parte 2. Para alcanzarlo, el filtro debe ser reemplazado.
Resumir:
El equilibrador de carga configurado comenzará el horario para obtener información del servicio. Al usar el cliente Eureka, toda la información de instancia de servicio se obtendrá del servicio Eureka, y los servicios que se pueden usar se filtrarán a través del filtro. Por defecto, el filtro solo filtrará los servicios que son los mismos que el lado del consumidor. Si desea garantizar una alta disponibilidad, puede configurar el filtro ZoneAffinityServerListFilter, y la lista de servicios filtrados seleccionará el servicio correspondiente implementando la política de equilibrio de carga de la interfaz IRULE. Si utiliza la política de Award Zone, puede seleccionar el servicio apropiado de la zona con buenas condiciones de carga.