Ensuite, examinons comment obtenir l'instance de service, ce que le traitement a été effectué après avoir obtenu et comment sélectionner l'instance de service après traitement.
Divisez en trois parties:
Configuration
Dans la section de configuration de l'article précédent "Les principes du ruban de nuage de printemps", vous pouvez voir que l'équilibreur de charge par défaut est ZoneAwareLoadbalancer.
Jetez un œil à la classe de configuration.
Emplacement:
Spring-Cloud-netflix-core-1.3.5
@SuppressWarnings ("Deprécation") @ configuration @ perteConfigurationProperties // L'ordre est important ici, le dernier devrait être la valeur par défaut, d'abord devrait être facultatif // voir https://github.com/spring-cloud/spring-cloud-netflix/issues/2086#issuecomment-316281653@import({okhttpribbonconfiguration.class, restclientribbonconfiguration.class, httpclientconconfiguration.class}) {// omettre @Bean @conditionalonMissingBean public Iloadbalancer RibbonloadBalancer (IclientConfig Config, serverlist <Server> ServerList, serverlistFilter <Spirt> ServerListFilter, Irule Rule, iping Ping. return this.propertiesfactory.get (iloadbalancer.class, config, nom); } return new ZoneAwareLoadBalancer <> (config, règle, ping, serverlist, serverlistFilter, serverListUpDater); } // omis}Injecté dans l'instance de config, règle, ping, serverList, serverlistFilter, serverListUpDater.
Config: configurez l'instance.
Règle: Instance de stratégie d'équilibrage de chargement.
Ping: instance de ping.
ServerList: obtient et met à jour une instance du service.
ServerListFilter: instance de filtrage de service.
ServerListUpDater: instance de mise à jour des informations sur la liste des services.
@SuppressWarnings ("Deprécation") @ configuration @ perteConfigurationProperties // L'ordre est important ici, le dernier devrait être la valeur par défaut, d'abord devrait être facultatif // voir https://github.com/spring-cloud/spring-cloud-netflix/issues/2086#issuecomment-316281653@import({okhttpribbonconfiguration.class, restclientribbonconfiguration.class, httclientconconfiguration.class}) // omettre @bean @conditionalonMissingBean public IclientConfig rubbonClientConfig () {defaultClientConfigImpl config = new defaultClientConfigImpl (); config.loadProperties (this.name); return config; } @Bean @conditionalonMissingBean public Irule rubbonrule (iClientConfig config) {if (this.propertiesfactory.isset (irule.class, nom)) {return this.propertiesfactory.get (iule.class, config, nom); } Zoneavoidancerrule Rule = New ZoneAVoidancerUle (); Rule.InitWithniwsConfig (config); Règle de retour; } @Bean @conditionalonMissingBean public iping rubbonping (iclientconfig config) {if (this.propertiesfactory.isset (iping.class, name)) {return this.propertiesfactory.get (iping.class, config, name); } return new Dummyping (); } @Bean @conditionalonMissingBean @SuppressWarnings ("Unchecked") public ServerList <Sternver> ribBonServerList (iClientConfig Config) {if (this.propertiesfactory.get (serverlist.class, nom)) {renvoie this.propertiesfactory.get (serverlist.class, config, name); } ConfigurationBasedServerList ServerList = new ConfigurationBasedServerList (); serverlist.initwithniwsconfig (config); return serverList; } @Bean @conditionalonMissingBean public ServerListDater RibbonServerListUpDater (IclientConfig Config) {return new PollingServerListUpDater (config); } @Bean @conditionalonMissingBean public iloadbalancer rubbonloadBalancer (IclientConfig Config, serverlist <server> serverListFilter <Server> ServerListFilter, IRULE Rule, iping ping, serverLispupDater ServerListDater) {if (this.propertiesfactory.sset (iloadballaner.class, {retour this.propertiesfactory.get (iloadbalancer.class, config, nom); } return new ZoneAwareLoadBalancer <> (config, règle, ping, serverlist, serverlistFilter, serverListUpDater); } @Bean @conditionalonMissingBean @SuppressWarnings ("Unchecked") public ServerListFilter <Server> RibBonServerListFilter (iClientConfig Config) {if (this.propertiesfactory.isset (serverlistFilter.class, nom)) {return this.propertiesfactory.get (serverlistFilter } ZonePreferencesServerListFilter Filter = new ZonePreferencesServerListFilter (); filter.initwithniwsconfig (config); filtre de retour; } @Bean @conditionalonMissingBean public rubbonloadBalerContext rubbonloadBalancerConText (iloadbalancer loadbalancer, iClientConfig config, reryhandler retryHandler) {return new RibbonBerConText (loadBalancer, config, retryHandler); } // omis}Configurer des exemples pertinents ici
config: defaultClientConfigImpl.
Règle: ZoneavoidancerUle.
Ping: Dummyping.
ServerList: ConfigurationBasedServerList, instance de liste de services basée sur la configuration.
ServerListFilter: ZonePreferencesServerListFilter.
ServerListUpDater: PollserververListUpDater.
Il convient de noter que l'instance de ServerList ici est ConfigurationBasedServerList, qui est une instance qui obtient des informations de service lorsque Eureka n'est pas utilisé, et est obtenu à partir du fichier de configuration.
Ainsi, lorsque vous utilisez Eureka, vous devez obtenir des informations de service à partir du serveur Eureka. Quelle instance doit être utilisée pour ce faire?
Lors de l'activation de la découverte de service Eureka, la classe de configuration EurekaribBonClientConfiguration sera d'abord adoptée.
Emplacement:
Spring-Cloud-Netflix-eureka-Client-1.3.5
@ Configuration @ commonslogpublic classe eurekaribbonClientConfiguration {// omettre @bean @conditionalonMissingBean public iping Ribbonping (iClientConfig config) {if (this.propertiesfactory.isset (iping.class, serviceId)) {return this.propertiesfactory.get (iping.class, config, serviceid); } Niwsdiscoveryping ping = new niwsdiscoveryping (); ping.initwithniwsconfig (config); retour ping; } @Bean @conditionalonMissingBean public ServerList <?> RibBonServerList (ICLIENTCONFIG Config, fournisseur <Eurekaclient> eurekaclientProvider) {if (this.propertiesfactory.isset (serverlist.class, serviceId)) {return this.propertiesfactory.get (serverlist.class.class, config, serviceid); } DiscoveryEnabledNiWSServerList DiscoveryServerList = new DiscoveryEnabledNiwSserverList (config, eurekaclientProvider); DomaineExtractingServerList ServerList = new DomaineExtractingServerList (DiscoveryServerList, config, this.approximatezoneFromHostName); return serverList; } // omis}Après avoir utilisé pour la première fois la configuration EurekaribbonClientConfiguration, les instances deviennent réellement
config: defaultClientConfigImpl.
Règle: ZoneavoidancerUle.
Ping: niwsdiscoveryping.
ServerList: DomaineExtractingServerList, DiscoveryEnabledNiWSServerList, obtenant en fait une liste d'informations de service via la découverte de service.
ServerListFilter: ZonePreferencesServerListFilter.
ServerListUpDater: PollserververListUpDater.
Obtenir des services
Avant de trouver l'accès pour obtenir des informations de service, modifiez d'abord la relation de succession de la classe de l'équilibreur de charge.
La construction de la Classe Parent DynamicServerListBalancer est appelée dans la construction de ZoneAwareLoadbalancer.
Emplacement:
Ribbon-wadbalancer-2.2.2.jar
com.netflix.loadbalancer
ZoneAwareloadbalancer.class
Dans la construction de DynamicServerListLoadBalancer, la fonction Restofinit est appelée.
Ribbon-wadbalancer-2.2.2.jar
com.netflix.loadbalancer
DynamicServerListloadBalancer.class
void restofinit (iClientConfig clientConfig) {boolean primeConnection = this.iseablePrimingConnections (); // désactiver cela pour éviter l'amorçage asynchrone dupliqué effectué dans BasEloadBalancer.SetServerList () this.seTenablePrimingConnections (false); perdableAndInitLearnNewSerVersFeAture (); UpdateListOfServers (); if (PrimeConnection && this.getprimeconnections ()! = null) {this.getprimeconnections () .primeConnections (getReachableServers ()); } this.setEnablePrimingConnections (PrimeConnection); Logger.info ("DynamicServerListLoadBalancer pour client {} initialisé: {}", clientConfig.getClientName (), this.toString ()); }Tout d'abord, la liste des services est mise à jour régulièrement en appelant la méthode de perdableAndInitLearNnewServersFeat, puis d'appeler immédiatement la fonction UpdateListOfServers pour obtenir et mettre à jour les informations de la liste des services immédiatement.
Examinons d'abord la méthode perdableAndinitLearnNewServersFeature. En fait, la méthode de démarrage de l'instance de mise à jour des informations sur la liste des services est appelée pour démarrer la fonction de mise à jour chronométrée.
/ ** * fonctionnalité qui nous permet d'ajouter de nouvelles instances (à partir d'AMIS) à la liste des * serveurs existants que le LB utilisera cette méthode si vous souhaitez que cette fonctionnalité * activée * / public void enableAndInitLearNNewServersfeat () {Logger.info ("" Utilisation de serverListUpDater {} ", serverLupDater.getClass (). serverListUpDater.Start (UpdateAction); } L'exemple de mise à jour des informations sur la liste des services ici est l'instance PollserverListUpDater configurée à l'étape de configuration. Jetez un œil à la méthode de construction et de démarrage de cette classe.
classe publique PollingServerListUpDater implémente ServerListUpDater {// LISTE STATIQUE PRIVATE LISTOFSERVERS_CACHE_UPDATE_DELAY = 1000; // MSECS; Int statique privé ListoFservers_Cache_repeat_Interval = 30 * 1000; // MSECS; // final privé atomicboolean isactive = new atomicboolien (false); Private Volatile Long Lastupdated = System.CurrentTimeMillis (); Final privé long InitialDelayms; finale privée longue rafraîchissement des intervalles; // légèrement publique PollingServerListUpDater (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 synchronisé void start (final updateAction updateAction) {if (isactive.compareAndset (false, true)) {final runnable arseperrunnable = new Runnable () {@Override public void run () {if (! Isactice.get ()) {if (scheduledfuture! = Null) {scheduledfuture.cance (scheduledfuture! = Null) {scheduledfuture.CANCEL (true); } retour; } essayez {updateAction.DoupDate (); LastUpdated = System.CurrentTimeMillis (); } catch (exception e) {logger.warn ("échoué un cycle de mise à jour", e); }}}}; ScheduledFuture = getRefreshexecutor (). schedulewithfixeddelay (wrapperUnnable, initialDelayms, RefreshIntervalms, timeunit.milliseconds); } else {logger.info ("déjà actif, no-op"); }} // omettre}De la construction et de la définition constante, l'exécution est retardée d'une seconde et la mise à jour est effectuée toutes les 30 secondes par défaut. Vous pouvez modifier le temps de mise à jour entre la configuration.
Dans la méthode de début, il s'agit d'ouvrir un calendrier qui s'exécute régulièrement et d'exécuter régulièrement UpdateAction.DoupDate ().
Retournez à la classe de démarrage de la méthode de l'appelant DynamicServerListLoadBalancer et jetez un œil à la définition de l'instance de mise à jour.
protégé Final ServerListUpDater.UpDateAction UpdateAction = new ServerListUpDater.updateAction () {@Override public void DoupDate () {UpdateListOfServers (); }};En fait, la méthode UpdateListOfServers de DynamicServerListLoadBalancer est appelée, ce qui est cohérent avec le chemin pour mettre à jour la liste d'informations de service immédiatement après la mise à jour du temps de démarrage.
Continuez à consulter la méthode UpdateListOfServers.
public void updateListOfServers () {list <t> servers = new ArrayList <T> (); if (serverListImpl! = null) {servers = serverListImpl.getUpDatedListOfServers (); Logger.debug ("Liste des serveurs pour {} obtenu à partir de Discovery Client: {}", getIdentifier (), serveurs); if (filter! = null) {servers = filter.getFilteredListOfServers (serveurs); Logger.debug ("Liste filtrée des serveurs pour {} obtenue à partir de Discovery Client: {}", getIdentifier (), serveurs); }} updateAlLServerList (serveurs); }1. Obtenez la liste des informations du service via l'instance de listes de serveur.
2. Filtrez la liste des informations de service obtenue via l'instance ServerListFilter.
3. Enregistrez la liste des informations de service filtrées sur les charges de chargement en tant que State Hold.
Jetons un coup d'œil séparément ensuite.
1. Obtenez la liste des informations du service via l'instance de listes de serveur.
L'instance ServerList est la DomaineExtractingSserverList list dans l'étape de configuration. Les informations de service sont déléguées à DiscoveryEnabledNiWSServerList.
classe publique DiscoveryEnabledNiwSserverList étend AbstractServerList <DiscoveryEnabledServer> {// omit @Override public list <DiscoveryEnabledServer> getInitialListOfServers () {return obtenueServerViaDiscovery (); } @Override Public List <DiscoveryEnabledServer> GetUpdatedListOfServers () {return obtenueServerViaDiscovery (); } Liste privée <découverteNabledServer> obtenueServerViaDiscovery () {list <DiscoveryEnabledServer> serverList = new ArrayList <découverteNabledServer> (); if (eurekaclientprovider == null || eurekaclientprovider.get () == null) {logger.warn ("eurekaclient n'a pas encore été initialisé, renvoyant une liste vide"); return new ArrayList <découverteNabledServer> (); } Eurekaclient eurekaclient = eurekaclientprovider.get (); if (vipaddress! = null) {for (String vipaddress: vipaddress.split (",")) {// Si TargetRegion est nul, il sera interprété comme la même région de la liste des clients <stanceInfo> ListoFinstanceInfo = eurekaclient.getInstancesBipadDress (VIPADDRESS, Issecure, cible); pour (instanceInfo ii: listoFinstanceInfo) {if (ii.getStatus (). equals (instanceStatus.up)) {if (devraitUserOverRideport) {if (logger.isdebugeNable ()) {logger.debug ("Port de remplacement sur le nom du client:" + nom de client + "à" + décontracté); } // Une copie est nécessaire car le constructeur InstanceInfo utilise simplement la référence d'origine, // et nous ne voulons pas corrompre la copie globale eureka de l'objet qui peut être // utilisé par d'autres clients dans notre système d'instance systèmeInfo Copy = nouvelle instanceInfo (ii); if (issesecure) {ii = new instanceInfo.builder (copy) .SetSecureport (OverRideport) .Build (); } else {ii = new instanceInfo.builder (copy) .setport (OverRideport) .Build (); }} DiscoveryEnabledServer des = new DiscoveryEnabledServer (II, ISSECure, ShousUsiPaddr); DES.SetZone (DiscoveryClient.getZone (II)); serverList.add (DES); }} if (serverList.size ()> 0 && priorizevipAddressBasedServers) {break; // Si le vipaddress actuel a des serveurs, nous n'utilisons pas de serveurs basés sur VIPADRESS ultérieurs}}} return serverList; } // omis}On peut voir qu'il s'agit en fait d'obtenir toutes les informations sur les instances de service du serveur Eureka via le client Eureka et d'emballer les instances en ligne dans DiscoveryEnabledServer, avec des informations de zone, et de les mettre dans la liste des services.
2. Filtrez la liste des informations de service obtenue via l'instance ServerListFilter.
L'instance ServerListFilte est la zonePreferencesServerListFilter générée à l'étape de configuration et est filtrée en appelant la méthode GetFilteredListOfServers de l'instance.
@ Data @ equalsAndHashCode (CALLUPER = false) Classe publique ZonePreferencesServerListFilter étend 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 <ver> serveurs) {list <ver> output = super.getFilteredListOfServers (serveurs); if (this.zone! = null && output.size () == servers.Size ()) {list <server> local = new ArrayList <Server> (); for (server server: output) {if (this.zone.equalsignorecase (server.getZone ())) {local.add (server); }} if (! local.isempty ()) {return local; }} return output; }}Dans la méthode GetFilteredListOfServers, la première chose que vous souhaitez est d'appeler le même nom de la classe parent pour filtrer d'abord. En fait, la classe des parents filtre également les services dans la même zone que le côté consommateur. Non seulement cela, il ajoute des jugements intelligents pour s'assurer que le filtrage dans la même zone n'est pas effectué lorsque la défaillance / la charge est élevée ou lorsqu'il y a peu d'instances disponibles.
Cependant, dans ZonePreferencesServerListFilter.GetFilteredListOfServers, même si la classe parent n'a pas filtrée, les services de la même zone doivent encore être filtrés et utilisés. Qui a dit que la classe ici est une zone de zone?
C'est une chose plutôt bizarre, et il estime que le jugement intelligent de la classe parent n'a aucun effet.
Jetons un coup d'œil au travail acharné effectué par ZoneAffinityServerListFilter.getFilteredLitListOfServers.
classe publique ZoneAffinityServerListFilter <T Extend Server> étend AbstractServerListFilter <T> implémente iClientConfigAware {// Boolean SauvelablezonEAFFINITY (List <T> filtrée) {if (! ZoneAffinity &&! ZoneExclusive) {return false; } if (ZoneExclusive) {return true; } LoadBalanceStats stats = getloadBalancerstats (); if (statts == null) {return zoneAffinity; } else {logger.debug ("Déterminer si l'affinité de la zone doit être activée avec la liste de serveurs donnée: {}", filtré); Zonesnapshot snapshot = stats.getZonesNapshot (filtré); Double LoadPerServer = snapshot.getloadPerServer (); int instanceCount = snapshot.getInStanceCount (); int circuitBreakerTrippedCount = snapshot.getCircuitTripperipCount (); if ((((double) circuitbreakerTripperippount) / instanceCount> = BlackoutsserverpercentageThreshold.get () || LoadPerServer> = activeReqeustSerververThoshold.get () || (instanceCount - CircuitBreakerTripperippount) <"DovileSerSthreshold.get ()) {logger.DebuG (" "ZonEaFinity. Blackoutsserverpercentage: {}, activeReQEustSperserver: {}, disponiblesservers: {} ", nouvel objet [] {(double) circuitbreakerripprippedCount / instanceCount, return false;} else {return true;}}}} @override list <t> GetFilteredListOfServers (List <T> serveurs) {if (Zone! = Null && (zoneAffinity || ZoneExclusive) && serveurs! = null && servers.size (iterables. (épaulenablezonEAFIGINY (filtrée ders) {return filtredServers;} else if (zonEAffinity) {overRideCounter.increment ();}} return serveurs;Tout d'abord, les services de la même zone que le côté consommateur seront filtrés, puis les services de la même zone seront déterminés par HautablezoneAffinity (Filthersservers) pour déterminer si les services de la même zone peuvent être adoptés ou que tous les services peuvent être adoptés.
Dans la méthode des épauleszono-affinité, un instantané est effectué pour les services de la même zone, et le nombre d'instances, la charge moyenne et le nombre d'instances de ces services sont obtenus pour le calcul et le jugement.
Vous pouvez jeter un œil aux valeurs des indicateurs clés dans la méthode initwithniwsconfig.
Conditions de décision:
Pourcentage de disjoncteurs> = 0,8 (nombre de disjoncteurs / nombre d'instances de service)
Charge moyenne> = 0,6
Nombre d'instances disponibles <2 (nombre d'instances - Nombre d'instances qui sont cassées)
Si les conditions de jugement sont remplies, tous les services seront utilisés pour assurer la disponibilité.
Cependant, comme mentionné ci-dessus, parce que ZonePreferencesServerListFilter choisit toujours des services cohérents avec les zones de consommation, les opérations intelligentes effectuées dans ZoneAffinityServerListFilter.GetFilteredLedListOfServers ne sont pas utiles.
Cependant, bien sûr, vous pouvez utiliser des instances ZoneAffinityServerListFilter via des configurations personnalisées.
3. Enregistrez la liste des informations de service filtrées sur les charges de chargement en tant que State Hold.
Suivi updateAllServerList(servers); Et allez plus profondément étape par étape, vous constaterez qu'il est en fait enregistré dans LoadBalancerStats , et les services à l'heure actuelle sont enregistrés dans HashMap<String, List<Server>> Selon le regroupement de zone, et la clé est la zone.
Sélectionnez un service
L'équilibreur de charge qui implémente l'interface Iloadbalancer est utilisé pour sélectionner les services en implémentant la méthode ChoiceServer, et le service sélectionné est utilisé comme service de demande cible.
Jetez un œil à la méthode ZoneAwareLoadbalancer.ChooseServer.
@Override Public Server ChooseServer (clé d'objet) {if (! Activé.get () || getloadBalancerstats (). GetAvailableZones (). Size () <= 1) {Logger.debug ("Zone Aware Logic Disabled ou il n'y a qu'une seule zone"); return super.chooseServer (clé); } Server server = null; essayez {loadbalancerstats lbStats = getloadBalanceStats (); Map <string, zonesnapshot> zonesnapshot = zoneAVoidANRULE.CREATESNAPSHOT (LBSTATS); Logger.debug ("Zone Snapshots: {}", zonesnapshot); if (triggeringload == null) {Triggerringload = dynamicPropertyFactory.getInstance (). GetDoubleProperty ("ZoneAwareniwsDiscoveryloadBalancer." + this.getName () + ".trigringloadPerServerThreshold", 0.2d); } if (TriggeringBlackOutterCentage == NULL) {TriggringBlackOutterCentage = DynamicProperTyFactory.getInstance (). GetDoubleProperty ("ZoneAwareniWsDiscoveryloadBalancer." + This.getName () + ".avoidzoneWithBlackOutPetCetage", 0.99999d); } Set <string> disponiblezones = zoneavoidancer.getAvailableZones (zonesnapshot, triggeringload.get (), déclencheurblackoutPentcentage.get ()); Logger.debug ("Zones disponibles: {}", disponibles); if (disponiblezones! = null && disponiblezones.size () <zonesnapshot.KeySet (). size ()) {String Zone = zoneavoidancerrule.randomChooseZone (Zonesnapshot, disponiblezones); Logger.debug ("Zone choisi: {}", zone); if (zone! = null) {BasEloadbalancer ZoneLoadbalancer = getloadBalancer (zone); server = zoneloadbalancer.chooseServer (clé); }}} catch (exception e) {Logger.Error ("Erreur choisissant le serveur Utilisation de la logique de conscience de zone pour Balancer Load = {}", name, e); } if (server! = null) {return Server; } else {logger.debug ("La logique d'évitement de la zone n'est pas invoquée."); return super.chooseServer (clé); }}Notez qu'il y a deux usages ici:
1. Désactivez l'équilibrage de la charge de la zone en configurant ZoneAwareniwsDiscoveryloadBalancer.enabled = false, ou le nombre de zones <= 1.
2. Utiliser la perception de la zone, ou le nombre de zones est> 1.
Jetons un coup d'œil un par un
1. Désactivez l'équilibrage de la charge de la zone en configurant ZoneAwareniwsDiscoveryloadBalancer.enabled = false, ou le nombre de zones <= 1.
Dans ce cas, la méthode de la classe parent Baseloadbalancer.ChooseServer est appelée.
Public Server ChooseServer (clé d'objet) {if (compter == null) {compter = createCounter (); } counter.increment (); if (règle == null) {return null; } else {try {return règle.choose (key); } catch (exception e) {Logger.Warn ("LoadBalancer [{}]: Erreur choisissant le serveur pour clé {}", nom, key, e); retourner null; }}}La règle de la politique d'équilibrage de charge utilisée ici est en fait l'instance de stratégie Zoneavoidancerule générée pendant la phase de configuration qui a été transmise lors de la construction du ZoneAwareLoadbalancer.
public void setRule (Rule Irule) {if (règle! = null) {this.rule = règle; } else {/ * Rule par défaut * / this.rule = new RoundRobinrule (); } if (this.rule.getloadBalancer ()! = this) {this.rule.setloadBalancer (this); }}Supposons que s'il n'y a pas de configuration, l'instance de stratégie RoundRobinrule par défaut est utilisée.
2. Utiliser la perception de la zone, ou le nombre de zones est> 1.
Public Server ChooseServer (touche objet) {if (! activé.get () || getloadBalancerstats (). getAvailableZones (). size () <= 1) {Logger.debug ("" Zone Aware Logic Disabled ou Il n'y a qu'une seule zone "); return super.chooseServer (clé); } Server server = null; essayez {loadbalancerstats lbStats = getloadBalanceStats (); Map <string, zonesnapshot> zonesnapshot = zoneAVoidANRULE.CREATESNAPSHOT (LBSTATS); Logger.debug ("Zone Snapshots: {}", zonesnapshot); if (triggeringload == null) {Triggerringload = dynamicPropertyFactory.getInstance (). GetDoubleProperty ("ZoneAwareniwsDiscoveryloadBalancer." + this.getName () + ".trigringloadPerServerThreshold", 0.2d); } if (TriggeringBlackOutterCentage == NULL) {TriggringBlackOutterCentage = DynamicProperTyFactory.getInstance (). GetDoubleProperty ("ZoneAwareniWsDiscoveryloadBalancer." + This.getName () + ".avoidzoneWithBlackOutPetCetage", 0.99999d); } Set <string> disponiblezones = zoneavoidancer.getAvailableZones (zonesnapshot, triggeringload.get (), déclencheurblackoutPentcentage.get ()); Logger.debug ("Zones disponibles: {}", disponibles); if (disponiblezones! = null && disponiblezones.size () <zonesnapshot.KeySet (). size ()) {String Zone = zoneavoidancerrule.randomChooseZone (Zonesnapshot, disponiblezones); Logger.debug ("Zone choisi: {}", zone); if (zone! = null) {BasEloadbalancer ZoneLoadbalancer = getloadBalancer (zone); server = zoneloadbalancer.chooseServer (clé); }}} catch (exception e) {Logger.Error ("Erreur choisissant le serveur Utilisation de la logique de conscience de zone pour Balancer Load = {}", name, e); } if (server! = null) {return Server; } else {logger.debug ("La logique d'évitement de la zone n'est pas invoquée."); return super.chooseServer (clé); }}Dans ce cas, la stratégie d'équilibrage de la charge de Zoneavoidancerule est utilisée par défaut.
Obtenez les informations d'instantané de la zone.
Obtenez la zone disponible, en observant la définition de zoneavoidancer.getavailablezones, la condition que la zone disponible n'est pas:
Une fois que toutes les zones disponibles sont obtenues, choisissez-en une au hasard.
Et dans cette zone, sélectionnez le service via la classe parent BasEloadbalancer de ZoneAwareLoadbalancer.ChooseServer. Comme compilé ci-dessus, si aucune règle n'est adoptée dans Baseloadbalancer, la politique RoundRobinrule est utilisée par défaut pour trouver un service.
En fait, c'est toujours le problème de l'obtention du filtre ZonePreferencesServerListFilter ci-dessus. En fait, un seul service avec la même zone que le côté consommateur est filtré. Par conséquent, la fonction de sélection des services dans les zones disponibles de la partie 2 ne peut pas être obtenue. Pour l'atteindre, le filtre doit être remplacé.
Résumer:
L'équilibreur de charge configuré démarrera le calendrier pour obtenir des informations de service. Lorsque vous utilisez le client Eureka, toutes les informations sur les instances de service seront obtenues à partir du service Eureka, et les services qui peuvent être utilisés seront filtrés via le filtre. Par défaut, le filtre ne filtrera que des services qui sont les mêmes que le côté consommateur. Si vous souhaitez vous assurer une haute disponibilité, vous pouvez configurer le filtre ZoneAffinityServerListFilter, et la liste des services filtrés sélectionnera le service correspondant en implémentant la politique d'équilibrage de charge de l'interface Irule. Si vous utilisez la politique de la zone, vous pouvez sélectionner le service approprié dans la zone avec de bonnes conditions de charge.