จากนั้นมาดูวิธีรับอินสแตนซ์บริการการประมวลผลสิ่งที่ทำหลังจากได้รับและวิธีการเลือกอินสแตนซ์บริการหลังจากการประมวลผล
แบ่งออกเป็นสามส่วน:
การกำหนดค่า
ในส่วนการกำหนดค่าของบทความก่อนหน้านี้ "หลักการของริบบิ้นคลาวด์สปริง" คุณจะเห็นว่าตัวโหลดบัลแลนเซอร์เริ่มต้นคือ ZoneAwareloadBalancer
ดูคลาสการกำหนดค่า
ที่ตั้ง:
Spring-Cloud-Netflix-Core-1.3.5.Release.jarorg.springframework.cloud.netflix.ribbonribbonclientConfiguration.class
@suppresswarnings ("การเสื่อมราคา")@configuration@enableConfigurationProperties // คำสั่งซื้อมีความสำคัญที่นี่ควรเป็นค่าเริ่มต้นก่อนควรเป็นทางเลือก // ดู https://github.com/spring-cloud/spring-cloud-netflix/issues/2086#issuecomment-316281653@import( {okhttpribbonconfiguration.class, restcliribbonconfiguration.class omit @Bean @ConditionAlonMissingBean IloadBalancer RibbonloadBalancer (iClientConfig config, ServerList <Server> ServerList, ServerListFilter <Server> ServerListFilter, IRULE RULE, IPING PING this.propertiesfactory.get (iloadbalancer.class, config, ชื่อ); } ส่งคืน ZoneAwareloadBalancer ใหม่ <> (config, กฎ, ping, serverList, ServerListFilter, ServerListUpDater); } // ละเว้น}ฉีดในอินสแตนซ์ของการกำหนดค่ากฎ ping, ServerList, ServerListFilter, ServerListUpDater
กำหนดค่า: กำหนดค่าอินสแตนซ์
กฎ: อินสแตนซ์นโยบายการปรับสมดุล
PING: อินสแตนซ์ ping
ServerList: รับและอัปเดตอินสแตนซ์ของบริการ
ServerListFilter: อินสแตนซ์การกรองบริการ
ServerListUpDater: อินสแตนซ์ข้อมูลการอัปเดตรายการบริการ
@suppresswarnings ("การเสื่อมราคา")@configuration@enableConfigurationProperties // คำสั่งซื้อมีความสำคัญที่นี่ควรเป็นค่าเริ่มต้นก่อนควรเป็นทางเลือก // ดู https://github.com/spring-cloud/spring-cloud-netflix/issues/2086#issuecomment-316281653@import( {okhttpribbonconfiguration.class, restcliribbonconfiguration.class omit @Bean @ConditionAlonMissingBean public iClientConfig RibbonClientConfig () {DefaultClientConfigimpl config = new DefaultClientConfigimpl (); config.loadproperties (this.name); ส่งคืนการกำหนดค่า; } @Bean @ConditionAlonMissingBean Irule RibbonRule (IClientConfig config) {ถ้า (this.propertiesFactory.isset (irule.class, ชื่อ)) {ส่งคืนสิ่งนี้ } zoneavoidancerule กฎ = zoneavoidancerule ใหม่ (); Rule.initwithniwsconfig (config); กฎคืน; } @Bean @ConditionAlonMissingBean Iping Ribbonping (IClientConfig config) {ถ้า (this.propertiesFactory.isset (iping.class, ชื่อ)) {ส่งคืนสิ่งนี้ } ส่งคืน dummyping ใหม่ (); } @Bean @ConditionAlonMissingBean @SuppressWarnings ("Unchecked") ServerList <Server> RibbonServerList (iClientConfig config) {ถ้า (this.propertiesFactory.Isset.class.class.class, ชื่อ) {return.properties. } configurationBasedServerList ServerList = ใหม่ configurationBasedServerList (); ServerList.initWithNiWSconfig (config); ส่งคืน ServerList; } @Bean @ConditionAlonMissingBean ServerListUpDater RibbonServerListUpDater (IClientConfig config) {ส่งคืน PollingServerListupDater (config); } @Bean @ConditionAlonMissingBean IloadBalancer RibbonloadBalancer (iClientConfig config, ServerList <Server> ServerListFilter <Server> ServerListFilter, irule Rule, iping ping, serverListupDater) {if.properties. this.propertiesfactory.get (iloadbalancer.class, config, ชื่อ); } ส่งคืน ZoneAwareloadBalancer ใหม่ <> (config, กฎ, ping, serverList, ServerListFilter, ServerListUpDater); } @Bean @ConditionAlonMissingBean @suppresswarnings ("ไม่ได้ตรวจสอบ") ServerListFilter <Server> RibbonServerListFilter (IClientConfig config) {ถ้า (this.propertiSfactory.Isset (ServerListFilter.Class, ชื่อ) ชื่อ); } zonepreferenceserverlistFilter ตัวกรอง = ใหม่ zonepreferenceserverlistfilter (); filter.initwithniwsconfig (config); ตัวกรองส่งคืน; } @Bean @ConditionAlonMissingBean RibbonloadBalanconTetext RibbonloadBalanconText (iloadbalancer loadbalancer, iClientConfig config, retryhandler retryhandler) {ส่งคืนริบบิ้นใหม่ } // ละเว้น}กำหนดค่าตัวอย่างที่เกี่ยวข้องที่นี่
กำหนดค่า: DefaultClientConfigimpl
กฎ: Zoneavoidancerule
Ping: Dummyping
ServerList: ConfigurationBasedServerList อินสแตนซ์รายการบริการตามการกำหนดค่า
ServerListFilter: ZonePreferencesERverListFilter
ServerListUpDater: PollingsERVerlistUpDater
ควรสังเกตว่าอินสแตนซ์ของ ServerList ที่นี่คือ ConfigurationBasedServerList ซึ่งเป็นอินสแตนซ์ที่ได้รับข้อมูลบริการเมื่อไม่ได้ใช้ยูเรก้าและได้มาจากไฟล์การกำหนดค่า
ดังนั้นเมื่อใช้ยูเรก้าคุณจะต้องได้รับข้อมูลบริการจากเซิร์ฟเวอร์ยูเรก้า อินสแตนซ์ใดที่ควรใช้ในการทำสิ่งนี้?
เมื่อเปิดใช้งานการค้นพบบริการยูเรก้าระดับระดับการกำหนดค่า EurekaribbonClientConfiguration จะถูกนำมาใช้เป็นครั้งแรก
ที่ตั้ง:
Spring-Cloud-Netflix-eureka-client-1.3.5.5Release.jarorg.springframework.cloud.netflix.ribbon.eurekaurekaribbonclientconfiguration
@configuration @commonslogpublic คลาส eeurekaribbonclientconfiguration {// omit @bean @conditionalonmissingbean iping ribbonping สาธารณะ (iClientConfig config) {ถ้า (นี่ } niwsdiscoveryping ping = ใหม่ niwsdiscoveryping (); ping.initwithniwsconfig (config); กลับ Ping; } @Bean @ConditionAlonMissingBean Public ServerList <?> RibbonserverList (iClientConfig config ผู้ให้บริการ <Eurekaclient> EurekaclientProvider) {ถ้า (นี่ } DiscoveryEnabledNiWSServerList DiscoveryServerList = ใหม่ DiscoveryEnabledNiWSServerList (config, EurekaclientProvider); domainextractingserverList ServerList = ใหม่ domainextractingserverList (DiscoveryServerList, config, this.approximatezonefromhostname); ส่งคืน ServerList; } // ละเว้น}หลังจากใช้การกำหนดค่า EurekaribbonclientConfiguration ครั้งแรกอินสแตนซ์จะกลายเป็นจริง
กำหนดค่า: DefaultClientConfigimpl
กฎ: Zoneavoidancerule
PING: NIWSDISCOVERINPING
ServerList: domainextractingserverlist, DiscoveryEnabledNiWSServerList ภายในซึ่งได้รับรายการข้อมูลบริการผ่านการค้นพบบริการ
ServerListFilter: ZonePreferencesERverListFilter
ServerListUpDater: PollingsERVerlistUpDater
รับบริการ
ก่อนที่จะค้นหาการเข้าถึงเพื่อรับข้อมูลบริการให้แก้ไขความสัมพันธ์การสืบทอดคลาสของ Load Balancer ก่อน
ตัวสร้างคลาสแม่แบบ DynamicserListloadBalancer เรียกว่าในโครงสร้างของ ZoneAwareloadBalancer
ที่ตั้ง:
Ribbon-Loadbalancer-2.2.2.jar
com.netflix.loadbalancer
zoneawareloadbalancer.class
ในการสร้าง DynamicserverListloadBalancer ฟังก์ชัน restofinit เรียกว่า
Ribbon-Loadbalancer-2.2.2.jar
com.netflix.loadbalancer
Dynamicserverlistloadbalancer.class
เป็นโมฆะ restofinit (iClientConfig clientConfig) {boolean primeconnection = this.isenablePrimingConnections (); // ปิดสิ่งนี้เพื่อหลีกเลี่ยงการรองพื้นแบบอะซิงโครนัสที่ทำซ้ำใน baseloadbalancer.setserverlist () this.setenableprimingConnections (เท็จ); ENABLEANDINITLEARNEWSERVERSFEATURE (); updateListofServers (); if (primeconnection && this.getPrimeConnections ()! = null) {this.getPrimeConnections () .primeconnections (getReachableServers ()); } this.setenableprimingConnections (Primeconnection); logger.info ("DynamicserverListloadBalancer สำหรับไคลเอนต์ {} เริ่มต้น: {}", clientConfig.getClientName (), this.toString ()); -ขั้นแรกรายการบริการจะได้รับการอัปเดตเป็นประจำโดยเรียกใช้วิธีการ enableandinitlearnewserversfeature จากนั้นเรียกใช้ฟังก์ชัน updateListofServers ทันทีเพื่อรับและอัปเดตข้อมูลรายการบริการทันที
ก่อนอื่นให้ดูที่วิธีการ enableandinitlearnnewserversfeature อันที่จริงวิธีการเริ่มต้นของอินสแตนซ์ข้อมูลการอัปเดตข้อมูลรายการบริการถูกเรียกให้เริ่มฟังก์ชั่นการอัปเดตที่กำหนดเวลา
/ ** * คุณลักษณะที่ให้เราเพิ่มอินสแตนซ์ใหม่ (จาก AMIS) ไปยังรายการ * เซิร์ฟเวอร์ที่มีอยู่ที่ LB จะใช้วิธีการโทรนี้หากคุณต้องการ * คุณลักษณะนี้เปิดใช้งาน */ โมฆะสาธารณะ enableandinitlearNnewServersFeature () {logger.info ("การใช้ ServerListUpDater ServerListUpDater.Start (updateAction); - ตัวอย่างการอัปเดตข้อมูลรายการบริการที่นี่คืออินสแตนซ์ของ PollingServerListUpDater ที่กำหนดค่าไว้ในขั้นตอนการกำหนดค่า ดูวิธีการก่อสร้างและเริ่มต้นของชั้นเรียนนี้
PollingServerListUpDater ใช้ ServerListUpDater {// รายการยาวคงที่ส่วนตัวแบบคงที่ lestofservers_cache_update_delay = 1,000; // msecs; รายการ int คงที่ส่วนตัว listofservers_cache_repeat_interval = 30 * 1000; // msecs; // ส่วนตัว Atomicboolean isactive = new Atomicboolean (เท็จ); ความผันผวนส่วนตัวยาว lastupdated = system.currentTimeMillis (); เริ่มต้น Long Initialdelayms ส่วนตัว; การรีเฟรชยาวส่วนตัวสุดท้าย // pollingserverlistupdater (iClientConfig clientConfig เล็กน้อย) {this (listofservers_cache_update_delay, getRefreshIntervalms (clientConfig)); } PublingserverListUpDater (ขั้นสุดท้ายเริ่มต้น Long Initialdelayms, RefreshIntervalms ระยะยาวสุดท้าย) {this.initialdelayms = initialdelayms; this.refreshInterValms = RefreshInterValms; } @Override public synchronized void start (updateaction updateaction ขั้นสุดท้าย) {ถ้า (isactive.compareandset (เท็จจริง)) {wrapperrunnable final runnable = new runnable () {@Override Public Void Run () {if (! } กลับ; } ลอง {updateAction.doupdate (); LastUpDated = System.currentTimeMillis (); } catch (exception e) {logger.warn ("ล้มเหลวหนึ่งรอบการอัปเดต", e); - scheduledFuture = getRefreshexecutor (). ScheduLeWithFixedDelay (wrapperrunnable, initialdelayms, RefreshIntervalms, timeunit.milliseconds); } else {logger.info ("ใช้งานอยู่แล้วไม่มี"); }} // omit}จากการก่อสร้างและคำจำกัดความคงที่การดำเนินการล่าช้าหนึ่งวินาทีและการอัปเดตจะดำเนินการทุก ๆ 30 วินาทีโดยค่าเริ่มต้น คุณสามารถแก้ไขเวลาอัปเดตระหว่างการกำหนดค่า
จากวิธีการเริ่มต้นคือการเปิดตารางเวลาที่ดำเนินการอย่างสม่ำเสมอและดำเนินการ updateAction.doupdate () เป็นประจำ
กลับไปที่คลาส Start Method Caller DynamicserverListloadBalancer และดูคำจำกัดความของอินสแตนซ์ updateAction
ได้รับการป้องกันขั้นสุดท้าย ServerListUpDater.UpDateAction updateAction = ใหม่ ServerListUpDater.UpDateAction () {@Override โมฆะสาธารณะ doupdate () {updateListofServers (); -ในความเป็นจริงเมธอด updateListofServers ของคลาส DynamicserverListloadBalancer เรียกว่าซึ่งสอดคล้องกับเส้นทางเพื่ออัปเดตรายการข้อมูลบริการทันทีหลังจากการอัปเดตเวลาเริ่มต้น
ดำเนินการต่อเพื่อดูวิธี updateListofServers
โมฆะสาธารณะ updateListofServers () {รายการ <t> เซิร์ฟเวอร์ = new ArrayList <T> (); if (serverlistimpl! = null) {เซิร์ฟเวอร์ = serverlistimpl.getUpdatedListofServers (); logger.debug ("รายการเซิร์ฟเวอร์สำหรับ {} ที่ได้รับจากการค้นพบไคลเอนต์: {}", getIdentifier (), เซิร์ฟเวอร์); if (ตัวกรอง! = null) {เซิร์ฟเวอร์ = filter.getFilterEdListoFServers (เซิร์ฟเวอร์); logger.debug ("รายการที่กรองของเซิร์ฟเวอร์สำหรับ {} ที่ได้รับจากการค้นพบไคลเอนต์: {}", getIdentifier (), เซิร์ฟเวอร์); }} updateAllServerList (เซิร์ฟเวอร์); -1. รับรายการข้อมูลบริการผ่านอินสแตนซ์ ServerList
2. กรองรายการข้อมูลบริการที่ได้รับผ่านอินสแตนซ์ ServerListFilter
3. บันทึกรายการข้อมูลบริการที่ผ่านการกรองไปยัง LoadBalancerstats ตามสถานะของรัฐ
ลองมาดูกันแยกกัน
1. รับรายการข้อมูลบริการผ่านอินสแตนซ์ ServerList
อินสแตนซ์ ServerList คือ DomainextractingServerList ที่สร้างขึ้นในขั้นตอนการกำหนดค่า ข้อมูลบริการจะถูกมอบหมายให้ DiscoveryEnabledNiWSServerList
DiscoveryEnabledNiwSServerList ขยายบทคัดย่อ abstractServerList <IncoveryEnabledServer> {// omit @Override รายการสาธารณะ <ExcoveryEnabledServer> getInitialListofServers () {return } @Override รายการสาธารณะ <ExcoveryEnabledServer> getUpDatedListoFServers () {return atainserversviadiscovery (); } รายการส่วนตัว <ExcoveryEnabledServer> detainedServersViadIscovery () {รายการ <ExcoveryEnabledServer> ServerList = new ArrayList <IncoveryEnabledServer> (); if (EurekaclientProvider == NULL || EurekaclientProvider.get () == null) {logger.warn ("Eurekaclient ยังไม่ได้เริ่มต้น ส่งคืน ArrayList ใหม่ <ExcoveryEnabledServer> (); } Eurekaclient Eurekaclient = EurekaclientProvider.get (); if (vipaddresses! = null) {สำหรับ (String vipaddress: vipaddresses.split (",")) {// ถ้า targetErgion เป็นโมฆะมันจะถูกตีความว่าเป็นภูมิภาคเดียวกันของรายการลูกค้า สำหรับ (InstanceInfo II: listofinstanceInfo) {ถ้า (ii.getStatus (). เท่ากับ (instancestatus.up)) {ถ้า (ควร (ควรจะเป็น {{ควรจะเป็น {logger.debug (ogger.isdebugenabled } // การคัดลอกเป็นสิ่งจำเป็นเนื่องจากตัวสร้างอินสแตนซ์จะใช้การอ้างอิงดั้งเดิม // และเราไม่ต้องการทำลายสำเนายูเรก้าทั่วโลกของวัตถุซึ่งอาจเป็น // ที่ลูกค้าอื่นใช้ในระบบของเรา InstanceInfo Copy = New InstanceInfo (II); if (issecure) {ii = new InstanceInfo.builder (Copy) .setSecurePort (overrideport) .build (); } else {ii = new InstanceInfo.builder (Copy) .setport (overrideport) .build (); }} DiscoveryEnabledServer DES = ใหม่ DiscoveryEnabledServer (II, ISSECURE, ISBELUSEIPADDR); des.setzone (discoveryclient.getzone (ii)); ServerList.add (DES); }} if (serverList.size ()> 0 && prioritizeVipaddressBasedServers) {break; // หาก Vipaddress ปัจจุบันมีเซิร์ฟเวอร์เราจะไม่ใช้เซิร์ฟเวอร์ที่ใช้ vipaddress ที่ตามมา}}} ส่งคืน ServerList; } // ละเว้น}จะเห็นได้ว่ามันเป็นจริงที่จะได้รับข้อมูลอินสแตนซ์บริการทั้งหมดจากเซิร์ฟเวอร์ยูเรก้าผ่านไคลเอนต์ยูเรก้าและจัดเก็บข้อมูลออนไลน์ลงในอินสแตนซ์ DiscoveryEnabledServer พร้อมข้อมูลโซนและใส่ไว้ในรายการบริการ
2. กรองรายการข้อมูลบริการที่ได้รับผ่านอินสแตนซ์ ServerListFilter
อินสแตนซ์ ServerListFilte คือ ZonePreferencesERverListFilter ที่สร้างขึ้นในขั้นตอนการกำหนดค่าและถูกกรองโดยการเรียกใช้วิธี getFilterEdListofServers ของอินสแตนซ์
@data@equalsandHashCode (callyUper = false) คลาสสาธารณะ zonepreferenceserverlistFilter ขยาย ZoneAffinityServerListFilter <Server> {โซนส่วนตัว @Override โมฆะสาธารณะ initwithniwsconfig (iclientconfig niwsclientconfig) {super.initwithniwsconfig (niwsclientconfig); if (configurationManager.getDeploymentContext ()! = null) {this.zone = configurationManager.getDeploymentContext (). getValue (contextKey.zone); }} @Override รายการสาธารณะ <Server> getFilterEdListoFServers (รายการ <server> เซิร์ฟเวอร์) {รายการ <server> output = super.getFilterEdListoFServers (เซิร์ฟเวอร์); if (this.zone! = null && output.size () == servers.size ()) {list <server> local = new ArrayList <Server> (); สำหรับ (เซิร์ฟเวอร์เซิร์ฟเวอร์: เอาต์พุต) {ถ้า (this.zone.equalsignorecase (server.getzone ())) {local.add (เซิร์ฟเวอร์); }} if (! local.isempty ()) {return local; }} return output; -ในเมธอด GetFilteredListofServers สิ่งแรกที่คุณต้องการคือเรียกชื่อเดียวกันกับคลาสแม่ของผู้ชื่อเพื่อกรองก่อน ในความเป็นจริงชั้นผู้ปกครองยังกรองบริการในพื้นที่เดียวกันกับด้านผู้บริโภค ไม่เพียงเท่านั้นมันจะเพิ่มการตัดสินอัจฉริยะบางอย่างเพื่อให้แน่ใจว่าการกรองในพื้นที่เดียวกันไม่ได้ดำเนินการเมื่อความล้มเหลว/โหลดสูงหรือเมื่อมีอินสแตนซ์น้อย
อย่างไรก็ตามใน ZonePreferenceserverListFilter.GetFilterEdListofServers แม้ว่าคลาสแม่จะไม่ได้กรองบริการของโซนเดียวกันยังคงต้องถูกกรองและใช้งาน ใครบอกว่าชั้นเรียนที่นี่คือ zonepreference?
นี่เป็นสิ่งที่ค่อนข้างแปลกและรู้สึกว่าการตัดสินที่ชาญฉลาดของชั้นเรียนหลักไม่มีผล
ลองมาดูการทำงานอย่างหนักโดย ZoneAffinityServerListFilter.GetFilterEdListoFServers
คลาสสาธารณะ zoneaffinityserverlistfilter <t ขยายเซิร์ฟเวอร์> ขยายบทคัดย่อ abstractserverlistfilter <t> ใช้ iclientconfigaware {// บูลีนส่วนตัวที่ควรจะเป็น zoneeaffinity (รายการ <t> กรอง) } if (zoneexClusive) {return true; } loadbalancerstats stats = getloadbalancerstats (); if (stats == null) {return zoneaffinity; } else {logger.debug ("การพิจารณาว่าควรเปิดใช้งานโซนความสัมพันธ์กับรายการเซิร์ฟเวอร์ที่กำหนด: {}", กรอง); zonesNapShot snapshot = stats.getzonesnapshot (กรอง); double loadPerserver = snapshot.getLoadPerserver (); instancecount = snapshot.getInstanceCount (); int circuitbreakerTrippedCount = snapshot.getCircuittrippedCount (); if (((((สองเท่า) CircuitBreakerTrippedCount) / InstanCecount> = blackoutserverpercentagethreshold.get () || loadperserver> = activeereqeustserververthreshold.get () || blackoutserverpercentage: {}, activeereqeustsperserver: {}, availableservers: {} ", วัตถุใหม่ [] {((สองครั้ง) CircuitBreakerTrippedCount / Instancecount, loadperserver,}}} getFilteredListofServers (รายการ <t> เซิร์ฟเวอร์) {ถ้า (โซน! = null && (zoneaffinity || zoneexClusive) && เซิร์ฟเวอร์! = null && เซิร์ฟเวอร์. this.zoneaffinitypredicate.getServerOnlyPredicate ());ขั้นแรกบริการของโซนเดียวกันกับด้านผู้บริโภคจะถูกกรองออกจากนั้นบริการของโซนเดียวกันจะถูกกำหนดโดยที่ควรจะเป็น zoneaffinity (FilteredServers) เพื่อตรวจสอบว่าบริการของโซนเดียวกันสามารถนำมาใช้หรือสามารถนำบริการทั้งหมดมาใช้
ในวิธีการที่ควรจะเป็น snapshot snapshot ทำเพื่อบริการของโซนเดียวกันและจำนวนอินสแตนซ์โหลดเฉลี่ยและจำนวนอินสแตนซ์ของบริการเหล่านี้ได้รับสำหรับการคำนวณและการตัดสิน
คุณสามารถดูค่าตัวบ่งชี้สำคัญในวิธีการเริ่มต้นของ NIWSCONFIG
เงื่อนไขการตัดสินใจ:
เปอร์เซ็นต์ของเบรกเกอร์วงจร> = 0.8 (จำนวนเบรกเกอร์วงจร/จำนวนอินสแตนซ์ของบริการ)
โหลดเฉลี่ย> = 0.6
จำนวนอินสแตนซ์ที่มีอยู่ <2 (จำนวนอินสแตนซ์ - จำนวนอินสแตนซ์ที่เสีย)
หากเป็นไปตามเงื่อนไขการตัดสินจะใช้บริการทั้งหมดเพื่อให้แน่ใจว่ามีความพร้อมใช้งาน
อย่างไรก็ตามดังที่ได้กล่าวไว้ข้างต้นเนื่องจาก ZonePreferenceserverListFilter เลือกบริการที่สอดคล้องกับเขตผู้บริโภคการดำเนินงานอัจฉริยะที่ทำใน ZoneAffinityServerListFilter.GetFilterEdListoFServers ไม่มีประโยชน์
อย่างไรก็ตามแน่นอนคุณสามารถใช้อินสแตนซ์ ZoneAffinityServerListFilter ผ่านการกำหนดค่าที่กำหนดเอง
3. บันทึกรายการข้อมูลบริการที่ผ่านการกรองไปยัง LoadBalancerstats ตามสถานะของรัฐ
ติดตาม updateAllServerList(servers); และก้าวต่อไปทีละขั้นตอนคุณจะพบว่าจริง ๆ แล้วมันถูกบันทึกไว้ใน LoadBalancerStats และบริการในเวลานี้จะถูกบันทึกไว้ใน HashMap<String, List<Server>> โครงสร้างตามการจัดกลุ่มโซนและคีย์คือโซน
เลือกบริการ
Load Balancer ที่ใช้อินเทอร์เฟซ IloadBalancer ใช้เพื่อเลือกบริการโดยใช้วิธีการเลือกตัวเลือกและบริการที่เลือกใช้เป็นบริการคำขอเป้าหมาย
ลองดูที่ ZoneAwareloadBalancer.CHOOSESERVER วิธี
@Override เซิร์ฟเวอร์สาธารณะเลือก (คีย์วัตถุ) {if (! enabled.get () || getLoadbalancerstats (). getAvailablezones (). size () <= 1) {logger.debug ( return super.chooseserver (คีย์); } เซิร์ฟเวอร์เซิร์ฟเวอร์ = null; ลอง {loadbalancerstats lbstats = getloadbalancerstats (); แผนที่ <string, zonesnapshot> zonesnapshot = zoneavoidancerule.createsnapshot (lbstats); logger.debug ("โซนสแน็ปช็อต: {}", zonesnapshot); if (triggeringload == null) {triggeringload = dynamicPropertyFactory.getInstance (). getDoubleProperty ("ZoneAwareniwsDiscoveryloadBalancer" + this.getName () + " } if (triggeringblackoutpercentage == null) {triggeringblackoutpercentage = DynamicPropertyfactory.getInstance (). getDoubleProperty ("ZoneAwareniwsdiscoveryloadbalancer" + this.getName () } ตั้งค่า <string> railezones = zoneavoidancerule.getavailableablezones (zonesnapshot, triggeringload.get (), triggeringblackoutpercentage.get ()); logger.debug ("โซนที่มีอยู่: {}", raveingzones); if (railezones! = null && arablezones.size () <zonesnapshot.keyset (). size ()) {string zone = zoneavoidancerule.randomchoosezone (zonesnapshot, arightzones); logger.debug ("โซนที่เลือก: {}", โซน); if (zone! = null) {baseloadbalancer zoneloadbalancer = getloadbalancer (โซน); เซิร์ฟเวอร์ = zoneloadbalancer.chooseserver (คีย์); }}} catch (exception e) {logger.error ("ข้อผิดพลาดในการเลือกเซิร์ฟเวอร์โดยใช้ zone aray logic สำหรับ load balancer = {}", ชื่อ, e); } if (เซิร์ฟเวอร์! = null) {return server; } else {logger.debug ("โซนการหลีกเลี่ยงตรรกะไม่ได้ถูกเรียกใช้"); return super.chooseserver (คีย์); -โปรดทราบว่ามีสองประเพณีที่นี่:
1. ปิดการปรับสมดุลโหลดโซนโดยการกำหนดค่า ZoneAwareniwsDiscoveryloadBalancer.enabled = FALSE หรือจำนวนโซน <= 1
2. ใช้การรับรู้โซนหรือจำนวนโซนคือ> 1
ลองมาดูกันทีละคน
1. ปิดการปรับสมดุลโหลดโซนโดยการกำหนดค่า ZoneAwareniwsDiscoveryloadBalancer.enabled = FALSE หรือจำนวนโซน <= 1
ในกรณีนี้เมธอด BaseloadBalancer ผู้ปกครองจะเรียกใช้
เซิร์ฟเวอร์สาธารณะเลือก (คีย์วัตถุ) {if (counter == null) {counter = createCounter (); } counter.increment (); ถ้า (กฎ == null) {return null; } else {ลอง {return rule.choose (คีย์); } catch (exception e) {logger.warn ("loadbalancer [{}]: ข้อผิดพลาดการเลือกเซิร์ฟเวอร์สำหรับคีย์ {}", ชื่อ, คีย์, e); คืนค่า null; -กฎนโยบายการปรับสมดุลการโหลดที่ใช้ในที่นี้เป็นอินสแตนซ์นโยบาย ZoneAvoidAncerule ที่สร้างขึ้นในระหว่างขั้นตอนการกำหนดค่าที่ส่งเมื่อสร้าง ZoneAwareloadBalancer
โมฆะสาธารณะ setRule (กฎ irule) {ถ้า (กฎ! = null) {this.rule = กฎ; } else { / * กฎเริ่มต้น * / this.rule = ใหม่ roundrobinRule (); } if (this.rule.getLoadBalancer ()! = this) {this.rule.setloadbalancer (นี่); -สมมติว่าหากไม่มีการกำหนดค่าจะใช้อินสแตนซ์นโยบาย RoundRobinRule เริ่มต้น
2. ใช้การรับรู้โซนหรือจำนวนโซนคือ> 1
เซิร์ฟเวอร์สาธารณะเลือก (คีย์วัตถุ) {if (! enabled.get () || getloadbalancerstats (). getAvailableZones (). size () <= 1) {logger.debug ("โซนรับรู้ตรรกะหรือมีเพียงโซนเดียว"); return super.chooseserver (คีย์); } เซิร์ฟเวอร์เซิร์ฟเวอร์ = null; ลอง {loadbalancerstats lbstats = getloadbalancerstats (); แผนที่ <string, zonesnapshot> zonesnapshot = zoneavoidancerule.createsnapshot (lbstats); logger.debug ("โซนสแน็ปช็อต: {}", zonesnapshot); if (triggeringload == null) {triggeringload = dynamicPropertyFactory.getInstance (). getDoubleProperty ("ZoneAwareniwsDiscoveryloadBalancer" + this.getName () + " } if (triggeringblackoutpercentage == null) {triggeringblackoutpercentage = DynamicPropertyfactory.getInstance (). getDoubleProperty ("ZoneAwareniwsdiscoveryloadbalancer" + this.getName () } ตั้งค่า <string> railezones = zoneavoidancerule.getavailableablezones (zonesnapshot, triggeringload.get (), triggeringblackoutpercentage.get ()); logger.debug ("โซนที่มีอยู่: {}", raveingzones); if (railezones! = null && arablezones.size () <zonesnapshot.keyset (). size ()) {string zone = zoneavoidancerule.randomchoosezone (zonesnapshot, arightzones); logger.debug ("โซนที่เลือก: {}", โซน); if (zone! = null) {baseloadbalancer zoneloadbalancer = getloadbalancer (โซน); เซิร์ฟเวอร์ = zoneloadbalancer.chooseserver (คีย์); }}} catch (exception e) {logger.error ("ข้อผิดพลาดในการเลือกเซิร์ฟเวอร์โดยใช้ zone aray logic สำหรับ load balancer = {}", ชื่อ, e); } if (เซิร์ฟเวอร์! = null) {return server; } else {logger.debug ("โซนการหลีกเลี่ยงตรรกะไม่ได้ถูกเรียกใช้"); return super.chooseserver (คีย์); -ในกรณีนี้นโยบายการปรับสมดุลการโหลด Zoneavoidancerule จะถูกใช้โดยค่าเริ่มต้น
รับข้อมูลสแน็ปช็อตของโซน
รับโซนที่มีอยู่โดยการสังเกต zoneavoidancerule.getAvailableablezones นิยามเงื่อนไขที่ไม่ใช่โซนที่มีอยู่คือ:
หลังจากได้รับโซนที่มีอยู่ทั้งหมดให้เลือกแบบสุ่ม
และจากโซนนี้เลือกบริการผ่านชั้นเรียนหลักของ BaseloadBalancer ของ ZoneAwareloadBalancer.chooseserver ตามที่รวบรวมไว้ข้างต้นหากไม่มีกฎใด ๆ ถูกส่งผ่านใน BaseloadBalancer นโยบาย RoundrobinRule จะถูกใช้โดยค่าเริ่มต้นเพื่อค้นหาบริการ
ในความเป็นจริงมันยังคงเป็นปัญหาของการได้รับตัวกรอง zonepreferenceserverlistfilter ด้านบน ในความเป็นจริงมีเพียงหนึ่งบริการที่มีโซนเดียวกันกับด้านผู้บริโภคถูกกรองออก ดังนั้นฟังก์ชั่นของการเลือกบริการจากโซนที่มีอยู่ในส่วนที่ 2 จึงไม่สามารถทำได้ ในการเข้าถึงตัวกรองจะต้องเปลี่ยน
สรุป:
โหลดบาลานซ์ที่กำหนดค่าจะเริ่มกำหนดการเพื่อรับข้อมูลบริการ เมื่อใช้ไคลเอนต์ยูเรก้าข้อมูลอินสแตนซ์บริการทั้งหมดจะได้รับจากบริการยูเรก้าและบริการที่สามารถใช้งานได้จะถูกกรองผ่านตัวกรอง โดยค่าเริ่มต้นตัวกรองจะกรองเฉพาะบริการที่เหมือนกับด้านผู้บริโภค หากคุณต้องการให้แน่ใจว่ามีความพร้อมใช้งานสูงคุณสามารถกำหนดค่าตัวกรอง ZoneAffinityServerListFilter และรายการบริการที่กรองจะเลือกบริการที่เกี่ยวข้องโดยใช้นโยบายการปรับสมดุลโหลดของอินเทอร์เฟซ IRULE หากคุณใช้นโยบายการรับรู้โซนคุณสามารถเลือกบริการที่เหมาะสมจากโซนที่มีเงื่อนไขการโหลดที่ดี