다음으로 서비스 인스턴스를 얻는 방법, 획득 한 후 수행 된 처리 및 처리 후 서비스 인스턴스를 선택하는 방법을 살펴 보겠습니다.
세 부분으로 나눕니다.
구성
이전 기사 "스프링 클라우드 리본의 원리"의 구성 섹션에서 기본로드 밸런서가 Zoneawareloadbalancer임을 알 수 있습니다.
구성 클래스를 살펴보십시오.
위치:
Spring-Cloud-Netflix-core-1.3.3.5.release.jarorg.springframework.cloud.netflix.ribbonribbonclientconfiguration.class
@SuppressWarnings ( "Dequrecation")@configuration@enableConfigurationProperties // 순서는 여기에서 중요합니다. 마지막으로 기본값이어야합니다. 먼저 선택 사항이어야합니다. // see해야합니다. https://github.com/spring-cloud/spring-cloud-netflix/issues/2086#issuecomment-316281653@import ({khttpribbonconconfiguration.class, restclientribbonconfiguration.class, httpclientribbonconconfiguration.publassclass rivbonclientscigeration})))))). @bean @conditionalonmissingbean public iloadbalancer ribbonloadbalancer (iclientconfig config, serverList> ServerList, ServerListFilter <Server> ServerListFilter, Irule Rule, IPing Ping, ServerListUpdater ServerListupDater) {thistlist. reture this.propertiesFactory.get (iloadbalancer.class, config, name); } 새 ZoneAwarEloadBalancer <> (config, Rule, Ping, ServerList, ServerListFilter, ServerListUpDater); } // 생략}구성, 규칙, ping, serverList, ServerListFilter, ServerListUpdater 인스턴스에 주입됩니다.
구성 : 인스턴스를 구성합니다.
규칙 :로드 밸런싱 정책 인스턴스.
핑 : 핑 인스턴스.
ServerList : 서비스 인스턴스를 가져 와서 업데이트합니다.
ServerListFilter : 서비스 필터링 인스턴스.
ServerListUpdater : 서비스 목록 정보 업데이트 인스턴스.
@SuppressWarnings ( "Dequrecation")@configuration@enableConfigurationProperties // 순서는 여기에서 중요합니다. 마지막으로 기본값이어야합니다. 먼저 선택 사항이어야합니다. // see해야합니다. https://github.com/spring-cloud/spring-cloud-netflix/issues/2086#issuecomment-316281653@import ({khttpribbonconconfiguration.class, restclientribbonconfiguration.class, httpclientribbonconconfiguration.publassclass rivbonclientscigeration})))))). @bean @conditionalonmissingbean public iclientconfig ribbonclientConfig () {defaultClientConfigimpl config = new defaultClientConfigimpl (); config.loadProperties (this.name); 반환 구성; } @bean @bean @conditionalonmissingbean public irule ribbonrule (iclientconfig config) {if (this.propertiesfactory.isset (irule.class, name)) {return this.propertiesfactory.get (irule.class, config, name); } ZoneaVoidancerule Rule = 새로운 ZoneaVoidancerule (); rule.initwithniwsconfig (config); 반환 규칙; } @Bean @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 @bean @conditionalonmissingbean @suppresswarnings ( "선택 취소") public serverList <Server> RibbonServerList (iclientConfig config) {if (this.propertiesfactory.isset (serverlist.class, name)) {return this.propertiesfactory.get (serverlist.class, conflass, name); } configurationBasedServerList ServerList = 새로운 구성 기반ServerList (); ServerList.initWithNiwsConfig (config); Return ServerList; } @bean @bean @conditionalonmissingbean public serverlistupdater ribbonserverlistupdater (iclientconfig config) {새로운 pollingserverlistupdater (config); } @bean @bean @conditionalonmissingbean public iloadbalancer ribbonloadbalancer (iclientconfig config, serverList> serverListFilter <Server> serverListFilter, iRule 규칙, iping ping, serverListUpdater serverListupDater) {if (this.propertiesfactory.isset) {iloadbolancer, iloadbals, istopertfactory.isset. this.propertiesfictory.get (iloadbalancer.class, config, name); } 새 ZoneAwarEloadBalancer <> (config, Rule, Ping, ServerList, ServerListFilter, ServerListUpDater); } @Bean @ConditionalOnMissingBean @SuppressWarnings ( "선택 취소") public serverListFilter <Server> ribBonserVerListFilter (iclientConfig solitg) {if (this.properTiesfactory.isset (serverListFilter.class, name)) {return theys.get.get, serverlistfilter. 이름); } ZonePreferenceserVerListFilter 필터 = New ZonePreferenceserVerListFilter (); filter.initwithniwsconfig (config); 반환 필터; } @bean @bean @conditionalonmissingbean public ribbonlancerContext ribbonloadbalancerContext (iloadbalancer loadbalancer, iclientconfig config, retryhandler retryhandler) {return new return balancerContext (loadbalancer, config, retryandler); } // 생략}여기에서 관련 예제를 구성하십시오
구성 : DefaultClientConfigimpl.
규칙 : zoneavoidancerule.
핑 : 더미 핑.
ServerList : ConfigurationBasedServerList, 구성 기반 서비스 목록 인스턴스.
ServerListFilter : ZonePreferencesErverListFilter.
ServerListUpdater : PollingServerListUpdater.
여기서 ServerList의 인스턴스는 configurationbasedServerList이며, 이는 Eureka를 사용하지 않을 때 서비스 정보를 얻는 인스턴스이며 구성 파일에서 얻습니다.
따라서 Eureka를 사용할 때는 Eureka Server에서 서비스 정보를 얻어야합니다. 이 작업을 수행하기 위해 어떤 인스턴스를 사용해야합니까?
Eureka Service Discovery를 활성화하면 EurekaribbonclientConfiguration 구성 클래스가 처음 채택됩니다.
위치:
Spring-Cloud-Netflix-Eureka-Client-1.3.5.release.jarorg.springframework.cloud.netflix.ribbon.eurekaeurekaribbonclientConfiguration.class
@commonslogpublic class eurekaribbonclientConfiguration {// omit @bean @conditionalonMissingbean public iping ribbonping (iclientconfig config) {if (this.propertiesfactory.isset (ipping.class, serviceid)) {return this.propertiesfactory.get (iping.class); } niwsdiscoveryping ping = new niwsdiscoveryping (); ping.initwithniwsconfig (config); 반환 핑; } @Bean @ConditionalOnMissingBean Public ServerList <?> ribbonserverlist (iclientConfig Config, Provider <EureKaclient> eureKaclientProvider) {if (this.propertiesfictory.isset (serverlist.class, serviceId)) {return this.properties.get.get.get. } DiscoveryEnabledNiwsServerList DiscoverySerVerList = New DiscoverYENDEDNIWSSERVERLIST (Config, EureKaclientProvider); DomainExtractingServerList ServerList = New DomainExtractingServerList (DiscoveryServerList, Config, this.ApproximatezonefromHostName); Return ServerList; } // 생략}EureKaribbonClientConfiguration 구성을 처음 사용한 후 인스턴스는 실제로
구성 : DefaultClientConfigimpl.
규칙 : zoneavoidancerule.
핑 : niwsdiscoveryping.
ServerList : DomainExtractingServerlist, 내부 DiscoveryEnabledNiwsServerList는 실제로 서비스 검색을 통해 서비스 정보 목록을 얻습니다.
ServerListFilter : ZonePreferencesErverListFilter.
ServerListUpdater : PollingServerListUpdater.
서비스를 받으십시오
서비스 정보를 얻기위한 액세스를 찾기 전에 먼저로드 밸런서의 클래스 상속 관계를 편집하십시오.
부모 클래스 DynamicserVerlistloadBalancer 구조는 Zoneawareloadbalancer의 구성에서 호출됩니다.
위치:
리본로드 밸런서 -2.2.2.jar
com.netflix.loadbalancer
Zoneawareloadbalancer.class
DynamicserverListloadBalancer의 구성에서 나머지 기능을 호출합니다.
리본로드 밸런서 -2.2.2.jar
com.netflix.loadbalancer
DynamicserverListloadBalancer.class
void restofinit (iclientConfig ClientConfig) {boolean primeConnection = this.isenablePrimingConnections (); // baseloadbalancer.setserverlist () this.setablePrimingConnection (false)에서 수행 된 복제 된 비동기 프라이밍을 피하기 위해이 꺼짐; enableAndInitLearnNewServersFeature (); updateListOfServers (); if (primeConnection && this.getPrimeConnection ()! = null) {this.getPrimeConnection () .primeConnection (getReachableServers ()); } this.setenablePrimingConnection (primeConnection); logger.info ( "클라이언트의 DynamicServerListLoadBalancer {} 초기화 : {}", clientConfig.getClientName (), this.toString ()); }먼저, 서비스 목록은 enableAntLearnNewServersFeature 메소드를 호출하여 정기적으로 업데이트 된 다음 즉시 updateListOfServers 기능을 호출하여 서비스 목록 정보를 즉시 얻고 업데이트합니다.
먼저 enableAnitLearnNewServersFeature 방법을 살펴 보겠습니다. 실제로 서비스 목록 정보 업데이트 인스턴스의 시작 방법은 시간이 지정된 업데이트 기능을 시작하도록 호출됩니다.
/ ** * LB 가이 메소드를 사용하려면이 메소드를 호출 할 수있는 기존 서버 목록에 (AMI에서) 새로운 인스턴스 (AMI에서)를 추가 할 수있는 기능 */ public void enableAnitLearnNewServersFeature () {logger.info ( "ServerListupDater {}", ServerListupDater.get getSimplass (). ServerListUpDater.Start (UpdateAction); } 서비스 목록 정보 업데이트 예제는 구성 단계에서 구성된 PollingServerListUpdater 인스턴스입니다. 이 수업의 구성 및 시작 방법을 살펴보십시오.
공개 클래스 폴링 서버리스트 updater는 ServerListupDater를 구현합니다. {// 개인 정적 장거리 목록이 _cache_update_delay = 1000; // msecs; 개인 정적 int listofservers_cache_repeat_interval = 30 * 1000; // msecs; // Private Final AtomicBoolean isactive = New AtomicBoolean (false); 비공개 휘발성 긴 최후의 최후화 = System.CurrentTimeMillis (); 개인 최종 최종 긴 초기 델 레이스; 개인 최종 최종 긴 CompertionIntervalms; // 약간 공개 폴링 서버리스트 updater (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 synchronized void start (최종 업데이트 updateAction) {if (isactive.compareAndset (false, true)) {최종 runnable wrapperRunnable = new Runnable () {@override public void Run () {if (! isactive.get ()) {scheduledfuture! } 반품; } try {updateAction.doupDate (); lastupdated = System.CurrentTimeMillis (); } catch (예외 e) {logger.warn ( "실패한 업데이트 사이클", e); }}}}; scheduledFuture = getRefreshExecutor (). ScheduLewitHfixEdDelay (wrapperRunnable, InitialDelayms, RefreshInterValms, timeUnit.milliseconds); } else {logger.info ( "이미 활성, No-OP"); }} // 생략}구조 및 일정한 정의에서 실행은 1 초씩 지연되며 업데이트는 기본적으로 30 초마다 수행됩니다. 구성 사이의 업데이트 시간을 수정할 수 있습니다.
시작 방법에서 정기적으로 실행하고 updateection.doupdate ()를 정기적으로 실행하는 일정을 열어야합니다.
시작 방법 발신자 DynamicserVerlistloadBalancer 클래스로 돌아가서 업데이트 아이템 인스턴스의 정의를 살펴보십시오.
보호 된 최종 ServerListUpdater.upDateAction UpdateAction = new ServerListUpDater.upDateAction () {@Override public void doupdate () {updateListOfServers (); }};실제로, DynamicServerListLoadBalancer 클래스의 UpdatEListOfServers 메소드가 호출되며, 이는 시작 시간 업데이트 직후 서비스 정보 목록을 업데이트하는 경로와 일치합니다.
UpdatEListOfServers 메소드를 계속 살펴보십시오.
public void updateListOfServers () {list <t> servers = new ArrayList <t> (); if (serverListImpl! = null) {servers = serverListImpl.getUpDatedListOfServers (); logger.debug ( "Discovery Client에서 얻은 {}의 서버 목록 : {}", getIndifier (), 서버); if (filter! = null) {servers = filter.getFilternListOfServers (서버); logger.debug ( "Discovery Client에서 얻은 {}에 대한 필터링 된 서버 목록 : {}", getIndifier (), 서버); }} updateallServerList (서버); }1. ServerList 인스턴스를 통해 서비스 정보 목록을 가져옵니다.
2. ServerListFilter 인스턴스를 통해 얻은 서비스 정보 목록을 필터링하십시오.
3. 필터링 된 서비스 정보 목록을 State Hold로 LoadBalancerstats에 저장하십시오.
다음에 따로 살펴 보겠습니다.
1. ServerList 인스턴스를 통해 서비스 정보 목록을 가져옵니다.
ServerList 인스턴스는 구성 단계에서 생성 된 DomainExtractingServerList입니다. 서비스 정보는 DiscoveryEnabledNiwsServerList에 위임됩니다.
Public Class DiscoveryEnabledNiwsServerList는 AbstractServerList를 확장합니다 <DiscoveryEnabledServer> {// amit @override public list <DepdepheryEnabledServer> getInitialListOfServers () {return 획득 획득 retoversviadiscovery (); } @override public list <DiscoveryEnabledServer> getUpdatedListOfServers () {return guveServersViadiscovery (); } private list <DiscoveryEnabledServer> aftServersViadiscovery () {list <discoveryEnabledServer> serverList = new ArrayList <DiscoveryEnabledServer> (); if (eureKaclientProvider == null || eureKaclientProvider.get () == null) {logger.warn ( "eureKaclient는 아직 초기화되지 않았으며 빈 목록을 반환했습니다"); 새로운 ArrayList를 반환 <DiscoveryEnabledServer> (); } eureKaclient eureKaclient = eureKaclientProvider.get (); if (vipaddresses! = null) {for (String vipaddress : vipaddresses.split ( ",")) {// target 영역이 null이면 클라이언트 목록의 동일한 영역으로 해석됩니다. for (instinesInfo II : listOfInstanceInfo) {if (ii.getStatus (). equals (instancestatus.up)) {if (ustuseOverRidePort) {if (logger.isdebugenabled ()) {logger.debug ( "클라이언트 이름의 포트 :" + ClientName + "to" + reportiderport); } // instanceinfo builder가 원본 참조를 사용하기 때문에 복사가 필요합니다. // 우리는 시스템에서 다른 클라이언트가 사용할 수있는 // 객체의 글로벌 유레카 사본을 손상시키고 싶지 않습니다. if (issecure) {ii = new instanceinfo.builder (copy) .setsecureport (OverridePort) .build (); } else {ii = new instanceInfo.builder (copy) .setport (OverridePort) .build (); }} DiscoveryEnabledServer des = new DiscoveryEnabledServer (II, issecure, rustuseIpaddr); des.setzone (DiscoveryClient.getzone (ii)); ServerList.add (des); }} if (serverList.Size ()> 0 && priorItizeVipAdDressBasedServers) {break; // 현재 VIPADDRESS에 서버가있는 경우 후속 VIPADDRESS 기반 서버}}} return serverList; } // 생략}실제로 Eureka 클라이언트를 통해 Eureka Server에서 모든 서비스 인스턴스 정보를 얻고 온라인 정보를 DiscoveryEnabledServer 인스턴스로 패키지하고 서비스 목록에 넣는 것이 실제로 알 수 있습니다.
2. ServerListFilter 인스턴스를 통해 얻은 서비스 정보 목록을 필터링하십시오.
ServerListFilte 인스턴스는 구성 단계에서 생성 된 ZonePreferencesErverListFilter이며 인스턴스의 getFilterStOfServers 메소드를 호출하여 필터링됩니다.
@data@equalsandhashcode (callsuper = false) public class ZonepreferenceserVerlistFilter 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> getFilternListOfServers (list <server> 서버) {list <server> output = super.getFilternListOfServers (서버); if (this.zone! = null && output.size () == 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; }}getFilternListOfServers 메소드에서 가장 먼저 원하는 것은 부모 클래스의 동일한 이름을 호출하여 먼저 필터를 필터링하는 것입니다. 실제로, 부모 클래스는 소비자 측과 같은 영역에서 서비스를 걸러냅니다. 뿐만 아니라, 고장/하중이 높거나 사용 가능한 인스턴스가 거의 없을 때 동일한 영역의 필터링이 수행되지 않도록 지능적인 판단을 추가합니다.
그러나 ZonePreferenceserVerlistFilter.getFilternListOfServers에서는 상위 클래스가 필터링되지 않더라도 동일한 영역의 서비스를 필터링하고 사용해야합니다. 누가 여기에 수업이 ZonePreference라고 말했습니까?
이것은 다소 이상한 일이며, 부모 계급의 지적 판단은 효과가 없다고 생각합니다.
ZoneaffinityServerListFilter.getFilternListOfServers의 노력을 살펴 보겠습니다.
Public Class ZoneaffinityServerListFilter <t 확장 서버> AbstractServerListFilter <T> 확장 ICLIENTCONFIGAWARE {// private boolean rooplean rooplean roudenablezoneaffinity (list <t> 필터링) {if (! zoneaffinity &&! ZoneExcclusive) {return false; } if (ZoneExcluction) {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 repuitbreakertrippedCount = snapshot.getCircuitTrippedCount (); if (((Double) CircuitBreakerTriptionCount) / instanceCount> = BlackoutServerPerCentagetHreshold.get () || LoadPerserver> = activeReeQeustSperServerThreshold.get () || (InstanCecount -CircuitbreakErtriptionCount) <availablesterVersthreshold.get ()) { "Zoneafity Is Is BlackoutServerperCentage : {}, activeReqeEStsperServer : {}, availableservers : {} ", new Object [] {(Double) CircuitBreakerTriptingCount / InstanceCount, Loadperserver, InstanCecount -CircuitBreakErtriptionCount}); return}}}}}}}}}}}}}}}}}. getFilternListOfServers (List <T> 서버) {if (Zone! = null && (ZoneAffinity || ZoneExcluction) && servers! = null && size.size ()> 0) {list <T> FilteredServers = lists.newArrayList (iterables.filter (server). zoneaffinitypredicate.getserveronlypredicate ());먼저, 소비자 측과 동일한 구역의 서비스가 필터링 된 다음 동일한 구역의 서비스를 채택 할 수 있는지 또는 모든 서비스를 채택 할 수 있는지 여부를 결정하기 위해 동일한 영역의 서비스를 결정합니다.
ShouldenableZoneaffinity 방법에서 동일한 영역의 서비스에 대한 스냅 샷이 수행되며, 계산 및 판단을 위해 이러한 서비스의 인스턴스 수, 평균 부하 및 인스턴스 수가 얻어집니다.
initwithniwsconfig 메소드에서 주요 표시기의 값을 살펴볼 수 있습니다.
의사 결정 조건 :
회로 차단기의 백분율> = 0.8 (회로 차단기 수/서비스 인스턴스 수)
평균 부하> = 0.6
사용 가능한 인스턴스 수 <2 (인스턴스 수 - 깨진 인스턴스 수)
판단 조건이 충족되면 모든 서비스를 사용하여 가용성을 보장합니다.
그러나 위에서 언급 한 바와 같이, ZonePreferenceserverListFilter 자체는 항상 소비자 구역과 일치하는 서비스를 선택하기 때문에 ZoneAffinityServerListFilter.getFiltersTofServers에서 수행 된 지능형 작업은 전혀 사용되지 않습니다.
그러나 물론 사용자 정의 구성을 통해 zoneaffinityserverlistfilter 인스턴스를 사용할 수 있습니다.
3. 필터링 된 서비스 정보 목록을 State Hold로 LoadBalancerstats에 저장하십시오.
후속 조치 updateAllServerList(servers); 단계별로 더 깊이 들어가면 실제로 LoadBalancerStats 에 저장되어 있으며 현재 서비스는 HashMap<String, List<Server>> 구역 그룹에 따라 구조에 저장되며 키는 영역입니다.
서비스를 선택하십시오
Iloadbalancer 인터페이스를 구현하는로드 밸런서는 Choiceserver 메소드를 구현하여 서비스를 선택하는 데 사용되며 선택된 서비스는 대상 요청 서비스로 사용됩니다.
zoneawareloadbalancer.chooseserver 메소드를 살펴보십시오.
@override public server 선택 선택자 (개체 키) {if (! enabled.get () || getloadbalancerstats (). getavailablezones (). size () <= 1) {logger.debug ( "Zone Aware Logic 또는 하나의 영역 만있는"); Super.ChooseServer (키)를 반환합니다. } 서버 서버 = null; try {loadbalancerstats lbstats = getloadbalancerstats (); Map <String, ZonesNapShot> ZonesNapShot = ZoneAvoidancerule.createsNapShot (lbstats); logger.debug ( "Zone Snapshots : {}", ZonesNapShot); if (triggeringload == null) {triggeringload = dynamicPropertyFactory.getInstance (). getDoubleProperty ( "ZoneAwareniwsDiscoveryLoadBalancer." + this.getName () + ". 트리거로드 로드PerserTreshold", 0.2d); } if (triggeringingBlackOutperCentage == null) {triggeringingBlackOutperCentage = DynamicPropertyFactory.getInstance (). getDoubleProperty ( "ZoneAwareniwsDiscoveryLoadBalancer." + this.getName () + ".AvoidzOneWithBlackOutcetage", 0.9999D); }} set <string> avidezones = ZoneaVoidancerule.getAvailableZones (ZonesNapShot, triggeringload.get (), triggeringingBlackOutperCentage.get ()); logger.debug ( "사용 가능한 영역 : {}", used zones); if (avidezones! = null && uadingzones.size () <zonesnapshot.keyset (). size ()) {String Zone = ZoneaVoidancerule.randomchoosezone (ZonesnapShot, avidezones); logger.debug ( "구역 선택 : {}", Zone); if (Zone! = null) {Baseloadbalancer ZonEloadBalancer = getLoadbalancer (Zone); Server = ZonEloadBalancer.ChooseServer (키); }}} catch (Exception e) {logger.error ( "로드 밸런서에 대한 영역 인식 로직을 사용하여 서버 선택 오류 = {}", name, e); } if (server! = null) {return server; } else {logger.debug ( "영역 회피 로직은 호출되지 않습니다."); Super.ChooseServer (키)를 반환합니다. }}여기에는 두 가지 사용법이 있습니다.
1. ZoneawareniwsDiscoveryLoadBalancer.enabled = false 또는 Zores <= 1을 구성하여 영역 인식로드 밸런싱을 끄십시오.
2. 영역 인식을 사용하거나 구역 수는> 1입니다.
하나씩 봅시다
1. ZoneawareniwsDiscoveryLoadBalancer.enabled = false 또는 Zores <= 1을 구성하여 영역 인식로드 밸런싱을 끄십시오.
이 경우 부모 클래스 Baseloadbalancer.ChooseServer 메소드가 호출됩니다.
공용 서버 선택기 (개체 키) {if (counter == null) {counter = createCounter (); } counter.increment (); if (rule == null) {return null; } else {try {return rule.choose (키); } catch (예외 e) {logger.warn ( "loadbalancer [{}] : key {}"에 대한 서버 선택 오류, 이름, key, e); 널 리턴; }}}여기에 사용 된로드 밸런싱 정책 규칙은 실제로 Zoneawareloadbalancer를 구성 할 때 전송 된 구성 단계에서 생성 된 ZoneaVoidancerule 정책 인스턴스입니다.
public void setrule (irule lule) {if (rule! = null) {this.rule = rule; } else { / * 기본 규칙 * / this.rule = new RoundRobinrule (); } if (this.rule.getLoadBalancer ()! = this) {this.rule.setloadbalancer (this); }}구성이 없으면 기본 RoundRobinrule 정책 인스턴스가 사용된다고 가정하십시오.
2. 영역 인식을 사용하거나 구역 수는> 1입니다.
공개 서버 선택 선택자 (객체 키) {if (! enabled.get () || getloadbalancerstats (). getAvailableZones (). size () <= 1) {logger.debug ( "영역 인식 논리 또는 하나의 영역 만 있습니다"); Super.ChooseServer (키)를 반환합니다. } 서버 서버 = null; try {loadbalancerstats lbstats = getloadbalancerstats (); Map <String, ZonesNapShot> ZonesNapShot = ZoneAvoidancerule.createsNapShot (lbstats); logger.debug ( "Zone Snapshots : {}", ZonesNapShot); if (triggeringload == null) {triggeringload = dynamicPropertyFactory.getInstance (). getDoubleProperty ( "ZoneAwareniwsDiscoveryLoadBalancer." + this.getName () + ". 트리거로드 로드PerserTreshold", 0.2d); } if (triggeringingBlackOutperCentage == null) {triggeringingBlackOutperCentage = DynamicPropertyFactory.getInstance (). getDoubleProperty ( "ZoneAwareniwsDiscoveryLoadBalancer." + this.getName () + ".AvoidzOneWithBlackOutcetage", 0.9999D); }} set <string> avidezones = ZoneaVoidancerule.getAvailableZones (ZonesNapShot, triggeringload.get (), triggeringingBlackOutperCentage.get ()); logger.debug ( "사용 가능한 영역 : {}", used zones); if (avidezones! = null && uadingzones.size () <zonesnapshot.keyset (). size ()) {String Zone = ZoneaVoidancerule.randomchoosezone (ZonesnapShot, avidezones); logger.debug ( "구역 선택 : {}", Zone); if (Zone! = null) {Baseloadbalancer ZonEloadBalancer = getLoadbalancer (Zone); Server = ZonEloadBalancer.ChooseServer (키); }}} catch (Exception e) {logger.error ( "로드 밸런서에 대한 영역 인식 로직을 사용하여 서버 선택 오류 = {}", name, e); } if (server! = null) {return server; } else {logger.debug ( "영역 회피 로직은 호출되지 않습니다."); Super.ChooseServer (키)를 반환합니다. }}이 경우, ZoneaVoidancerule Load Balancing Policy는 기본적으로 사용됩니다.
구역의 스냅 샷 정보를 얻으십시오.
zoneavoidancerule.getavailablezones 정의를 관찰하여 사용 가능한 영역을 가져옵니다.
모든 가용 구역을 얻은 후에는 무작위로 선택하십시오.
이 영역에서 Zoneawareloadbalancer.chooseserver의 부모 클래스 Baseloadbalancer를 통해 서비스를 선택하십시오. 위에서 편집 한대로 Baseloadbalancer에서 규칙이 전달되지 않으면 Roundrobinrule 정책이 기본적으로 서비스를 찾기 위해 사용됩니다.
실제로, 위의 ZonePreferenceserVerlistFilter 필터를 얻는 것은 여전히 문제입니다. 실제로 소비자 측과 동일한 영역을 가진 하나의 서비스 만 필터링됩니다. 따라서 2 부에서 사용 가능한 영역에서 서비스를 선택하는 기능은 달성 할 수 없습니다. 도달하려면 필터를 교체해야합니다.
요약 :
구성된로드 밸런서는 서비스 정보를 얻기 위해 일정을 시작합니다. Eureka 클라이언트를 사용하는 경우 Eureka Service에서 모든 서비스 인스턴스 정보가 얻어지며 사용할 수있는 서비스는 필터를 통해 필터링됩니다. 기본적으로 필터는 소비자 측과 동일한 서비스 만 걸러냅니다. 고 가용성을 보장하려면 ZoneAffinityServerListFilter 필터를 구성 할 수 있으며 필터링 된 서비스 목록은 IRULE 인터페이스의로드 밸런싱 정책을 구현하여 해당 서비스를 선택합니다. 구역 인식 정책을 사용하는 경우 부하 조건이 양호한 영역에서 적절한 서비스를 선택할 수 있습니다.