Selanjutnya, mari kita lihat cara mendapatkan instance layanan, pemrosesan apa yang telah dilakukan setelah mendapatkan, dan bagaimana memilih instance layanan setelah diproses.
Bagilah menjadi tiga bagian:
Konfigurasi
Di bagian konfigurasi artikel sebelumnya "Prinsip -prinsip Spring Cloud Ribbon", Anda dapat melihat bahwa penyeimbang beban default adalah ZoneAwareloadbalancer.
Lihatlah kelas konfigurasi.
Lokasi:
Spring-cloud-netflix-core-1.3.5.release.jarorg.springframework.cloud.netflix.ribbonribbonClientConfiguration.class
@SuppressWarnings ("Deprecation")@configuration@enableConfigurationProperties // pesanan penting di sini, terakhir harus menjadi default, pertama harus opsional // lihat https://github.com/spring-cloud/spring-cloud-netflix/issues/2086#issueComment-316281653@import( {okhttpribbonConfiguration.classcclasscconfiguration.classcclass.class, httpconfiguration.classcclass.class, httpconfiguration.classcclass.classcconfiguration.classcconfiguration oMit @Bean @ConditionAlonMissingBean Iloadbalancer RibbonLoadBalancer Publik (ICLIENTCONCONFIG, ServerList <Server> Disterion, serverListFilter <Server> serverListFilter, aturan iRule) {serverlistupater (serverlistUpdater) {if ini. kembalikan this.propertiesfactory.get (iloadbalancer.class, config, name); } return zoneagareLoadBalancer baru <> (config, aturan, ping, serverlist, serverlistFilter, serverlistupdater); } // dihilangkan}Disuntikkan dalam contoh konfigurasi, aturan, ping, daftar server, serverlistFilter, serverlistupdater.
Config: Konfigurasikan instance.
Aturan: Load Balancing Policy Instance.
Ping: Instance ping.
SERVERLIST: Mendapat dan memperbarui instance layanan.
ServerListFilter: Contoh penyaringan layanan.
ServerListUpdater: Instalasi Pembaruan Informasi Daftar Layanan.
@SuppressWarnings ("Deprecation")@configuration@enableConfigurationProperties // pesanan penting di sini, terakhir harus menjadi default, pertama harus opsional // lihat https://github.com/spring-cloud/spring-cloud-netflix/issues/2086#issueComment-316281653@import( {okhttpribbonConfiguration.classcclasscconfiguration.classcclass.class, httpconfiguration.classcclass.class, httpconfiguration.classcclass.classcconfiguration.classcconfiguration omit @bean @conditionAlonMissingBean public iclientConfig ribbonClientConfig () {defaultClientConfigImpl config = new DefaultClientConfigImpl (); config.loadproperties (this.name); return config; } @Bean @conditionAlonMissingBean public ribbonrule public (iclientConfig config) {if (this.propertiesfactory.isset (irule.class, name)) {return this.propertiesfactory.get (irule.class, config, name); } ZoneAvoidancerule aturan = zonevoidancerule baru (); aturan.initwithniwsconfig (config); aturan pengembalian; } @Bean @conditionAlonMissingBean publicping public pubbonping (iclientConfig) {if (this.propertiesfactory.isset (iping.class, name)) {return this.propertiesfactory.get (iPing.class, config, name); } return new dummyping (); } @Bean @conditionAlonMissingBean @suppressWarnings ("Uncecked") Public ServerList <Server> RibbonserverList (iclientConfig) {if (this.propertiesfactory.isset (serverList.class, name)) {return this.proPertiesFactory.isset (serverList.class, name)) {return this.proPertiesFactory.isset (serverList.class, name)) {return this.propertiesfactory.isset (serverList.class, name)) {return this.propertiesfactory.isset (serverList.class, name)) {return this.propertiesfactory.isset (serverList.class.class } ConfigurationBasedServerList serverList = new ConfigurationBasedServerList (); serverlist.initwithniwsconfig (config); mengembalikan daftar server; } @Bean @ConditionAlonMissingBean Public ServerListUpdater RibbonserverListUpdater (config iclientConfig) {return new PollingServerListUpdater (config); } @Bean @ConditionAlonMissingBean Iloadbalancer RibbonLoadBalancer Publik (config iclientConfig, serverlist <server> serverlistFilter <server> serverlistFilter, aturan irule, ping iPing, serverlistupdater (serverlistUpdater) {if (this.propertiesfactory. this.propertiesfactory.get (iloadbalancer.class, config, name); } return zoneagareLoadBalancer baru <> (config, aturan, ping, serverlist, serverlistFilter, serverlistupdater); } @Bean @conditionAlonMissingBean @suppressWarnings ("Uncecked") Public ServerListFilter <Server> RibbonserverListFilter (iclientConfig config) {if (this.propertiesfactory.isset (serverListFilter.class, name.propertiesfactory.isset (serverListFilter.class, name) {name.propertiesfactory.isset (serverListFilter.class, name) {name.propertiesfactory.isset (serverlistFilter.class, name) {name.propertiesFactory.isset (serverlistFilter.class, name) {name.properterfactory.isset (serverListFilter.class, name) {name) {name. nama); } ZonePreferenceServerListFilter filter = new ZonePreferenceServerListFilter (); filter.initwithniwsconfig (config); filter pengembalian; } @Bean @ConditionAlonMissingBean Public RibbonloadBalancerContext RibbonloadBalancerContext (ILoadBalancer LoadBalancer, ICLIENTCONFIG, RETRYHANDLER RETRYHIDLER) {Return New RibboBLoadBalancerContext (LoadBalancer, Config, RetryHandler); } // dihilangkan}Konfigurasikan contoh yang relevan di sini
Config: DefaultClientConfigImpl.
Aturan: ZoneAvoidancerule.
Ping: Dummyping.
Daftar Server: ConfigurationBasedServerList, Instance Daftar Layanan Berbasis Konfigurasi.
ServerListFilter: ZonePreferenceServerListFilter.
ServerListUpdater: PollingServerListUpdater.
Perlu dicatat bahwa instance Daftar Server di sini adalah ConfigurationBasedServerList, yang merupakan instance yang mendapatkan informasi layanan ketika Eureka tidak digunakan, dan diperoleh dari file konfigurasi.
Jadi saat menggunakan Eureka, Anda perlu mendapatkan informasi layanan dari Eureka Server. Contoh mana yang harus digunakan untuk melakukan ini?
Saat mengaktifkan penemuan layanan Eureka, kelas konfigurasi EurekaribbonClientConfiguration akan diadopsi pertama kali.
Lokasi:
Spring-cloud-netflix-eureka-client-1.3.5.release.jarorg.springframework.cloud.netflix.ribbon.eurekaeurekaribbonClientConfiguration.class
@Configuration @commonslogpublic kelas eurekaribbonClientConfiguration {// omit @bean @conditionalonmissingbean publonping public pubbonping (iClientConfig config) {if (this.propertiesfactory.isset (iPing.class, serviceId)) {return this. } NiwsDiscoveryping ping = new niwsdiscoveryping (); ping.initwithniwsconfig (config); kembali ping; } @Bean @conditionAlonMissingBean Publiclist Public <?> RibbonserverList (config configconfig, penyedia <eureKaclient> eureKaclientProvider) {if (this.propertiesfactory.isset (serverlist.class, serviceId)) {return this.propertiesfactory.isset (serverList.class, serviceId)) {return this.propertiesfactory.isset (serverList.class, serviceId)) {return this.propertiesFactory.isset (serverList.class, serviceId)) {return this.propersies.isset } DiscoveryEnabledNiWSServerList DiscoveryServerList = new DiscoveryEnableDniWsServerList (config, eureKaclientProvider); DomainExtracTingServerList ServerList = DomainExtracTingServerList baru (DiscoveryServerList, config, this.approximatezonefromhostname); mengembalikan daftar server; } // dihilangkan}Setelah pertama kali menggunakan konfigurasi EurekaribbonClientConfiguration, instance sebenarnya menjadi
Config: DefaultClientConfigImpl.
Aturan: ZoneAvoidancerule.
Ping: niwsdiscoveryping.
SERVERLIST: DomainExtracTingServerList, DiscoveryEnabledNiWsServerList internal, sebenarnya mendapatkan daftar informasi layanan melalui penemuan layanan.
ServerListFilter: ZonePreferenceServerListFilter.
ServerListUpdater: PollingServerListUpdater.
Dapatkan layanan
Sebelum menemukan akses untuk mendapatkan informasi layanan, pertama -tama edit hubungan warisan kelas dari penyeimbang beban.
Konstruk DynamicServerListLoFloadBalancer kelas induk disebut dalam konstruk zoneagareloadbalancer.
Lokasi:
Ribbon-LoadBalancer-2.2.2.jar
com.netflix.loadBalancer
Zoneagareloadbalancer.class
Dalam konstruksi DynamicServerListLoadBalancer, fungsi restofinit disebut.
Ribbon-LoadBalancer-2.2.2.jar
com.netflix.loadBalancer
DynamicServerListLoadBalancer.class
void restofinit (iclientConfig clientConfig) {boolean primeConnection = this.isEnablePrimingConnections (); // Matikan ini untuk menghindari duplikat priming asinkron yang dilakukan di BaseloadBalancer.setserverList () this.setEnablePrimingConnections (false); enableAndInitlearnnewserverfeature (); UpdateListOfServer (); if (primeconnection && this.getPrimeConnections ()! = null) {this.getPrimeConnections () .primeConnections (getReachableServer ()); } this.setEnablePrimingConnections (primeConnection); Logger.info ("DynamicServerListLoadBalancer untuk klien {} diinisialisasi: {}", clientConfig.getClientName (), this.toString ()); }Pertama, daftar layanan diperbarui secara berkala dengan menghubungi metode EnableAndInItlearnNewServerSfeature, dan kemudian segera hubungi fungsi UpdateListOfServer untuk mendapatkan dan memperbarui informasi daftar layanan segera.
Pertama -tama mari kita lihat metode enableAndInitlearnNnewServer. Bahkan, metode start dari instance pembaruan informasi daftar layanan dipanggil untuk memulai fungsi pembaruan waktunya.
/ ** * Fitur yang memungkinkan kami menambahkan instance baru (dari AMIS) ke daftar * server yang ada bahwa LB akan menggunakan Call Metode ini jika Anda menginginkan * fitur ini diaktifkan */ public enableAndInitLearnNNewSerVersFeature () {logger.info ("Menggunakan serverListUpdater {}") (serverget. serverlistupdater.start (UpdateAction); } Contoh Pembaruan Informasi Daftar Layanan di sini adalah instance PollingServerListUpdater yang dikonfigurasi dalam tahap konfigurasi. Lihatlah metode konstruksi dan mulai dari kelas ini.
PollingServerServerListUpdater kelas publik mengimplementasikan serverListUpdater {// private static Long listOfServer_cache_update_delay = 1000; // msec; private static int listOfServer_cache_repeat_interval = 30 * 1000; // msec; // atomicboolean final private isactive = atomicboolean baru (false); private volatile long lastupdated = system.currentTimemillis (); inisial long final swasta; Final Private Long Refreshintervalms; // sedikit PollingServerListUpdater (iclientConfig clientConfig) {this (listOfServer_cache_update_delay, getRefreshInterValMS (client config)); } PollingServerListUpdater publik (inisial panjang akhir, final panjang refreshintervalms) {this.initialDelayms = initialDelayms; this.refreshintervalms = RefreshIntervalms; } @Override public disinkronkan void start (updateAction updateAction final) {if (isactive.coeAndset (false, true)) {final runnable wrapperrunnable = new runnable () {@Override public run () {if (! IsActive.get ()) {if (scheduled) {if (! IsActive.get ()) {if () {if () {if () {IF () {ifeled () } kembali; } coba {UpdateAction.DoupDate (); lastupdated = system.currentTimemillis (); } catch (Exception e) {logger.warn ("Gagal satu siklus pembaruan", e); }}}}; SCRETDULEDFUTURE = getRefreshExecutor (). SCHORDULEWITHFIXEDDELAY (Wrapperrunnable, InitialDelayms, RefreshIntervalms, TimeUnit.Milliseconds); } else {logger.info ("sudah aktif, no-op"); }} // hilangkan}Dari definisi konstruksi dan konstan, eksekusi ditunda satu detik, dan pembaruan dilakukan setiap 30 detik secara default. Anda dapat memodifikasi waktu pembaruan antara konfigurasi.
Dari metode start, ini adalah untuk membuka jadwal yang dijalankan secara teratur dan menjalankan updateAction.doupDate () secara teratur.
Kembali ke Metode Mulai Penelepon DynamicServerListLoadBalancer kelas dan lihat definisi instance UpdateAction.
Final ServerListUpdater.UpDateAction UpdateAction = baru serverListUpdater.UpDateAction () {@Override public void doupDate () {UpdateListOfServer (); }};Bahkan, metode UpdateListOfServer dari kelas DynamicServerListLoadBalancer dipanggil, yang konsisten dengan jalur untuk memperbarui daftar informasi layanan segera setelah pembaruan waktu startup.
Lanjutkan untuk melihat metode UpdateListOfServer.
public void updateListOfServer () {list <t> server = new ArrayList <T> (); if (serverListImpl! = null) {server = serverListImpl.GetUpdatedListOfServer (); Logger.debug ("Daftar server untuk {} yang diperoleh dari klien penemuan: {}", getIdentifier (), server); if (filter! = null) {server = filter.getFilteredlistOfserver (server); Logger.debug ("Daftar server yang difilter untuk {} yang diperoleh dari klien penemuan: {}", getIdentifier (), server); }} UpdateLiLServerList (Server); }1. Dapatkan Daftar Informasi Layanan melalui instance Daftar Server.
2. Saring daftar informasi layanan yang diperoleh melalui instance ServerListFilter.
3. Simpan daftar informasi layanan yang difilter ke LoadBalanStats sebagai negara yang ditahan.
Mari kita lihat secara terpisah selanjutnya.
1. Dapatkan Daftar Informasi Layanan melalui instance Daftar Server.
Contoh serverlist adalah DomainExtracTingServerList yang dihasilkan pada tahap konfigurasi. Informasi layanan didelegasikan ke DiscoveryEnabledNiWsServerList.
DiscoveryEnableDniWsServerList } @Override Public List <CoveryEnabledServer> getUpdatedListOfServer () {return quidServerViadiscovery (); } Daftar Privat <ScoveryEnabledServer> DiperolehServerViadiscovery () {Daftar <ScoveryEnabledServer> serverList = ArrayList baru <ScoveryEnabledServer> (); if (eureKaClientProvider == null || eureKaclientProvider.get () == null) {logger.warn ("eureKaclient belum diinisialisasi, mengembalikan daftar kosong"); kembalikan daftar array baru <CoveryEnabledServer> (); } EureKaclient eureKaclient = eureKaclientProvider.get (); if (vipaddresses! = null) {for (string vipaddress: vipaddresses.split (",")) {// Jika target null, itu akan ditafsirkan sebagai wilayah yang sama dari daftar klien <stanceInfo> listOfInstanceInfo = eureKaclient.getinstancesByViPApApadRESS (vipAclress, eureKaclient.getInstancesBiPApadregress (viPadRress, eureKaclient.getinstancesBiPApadregress, viPadRESS, EUREKACLIENT.getInstancesByViPApApadRESS, VIPADRESS, EUREKACLIENT.GETINSTANCESSBYVIPAIPAIPAIPAIPRECRESS (EUREKACLIENT. untuk (instanceInfo II: listOfInstanceInfo) {if (ii.getStatus (). Equals (instanceStatus.up)) {if (hiseUseOverrideport) {if (logger.isdebugeNabled ()) {logger.debug ("overriding port pada nama klien:" + clientne clientn } // Salin diperlukan karena pembangun instanceinfo hanya menggunakan referensi asli, // dan kami tidak ingin merusak salinan eureka global dari objek yang mungkin // digunakan oleh klien lain dalam sistem kami 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 = new DiscoveryEnabledServer (II, Issecure, Hustuseipaddr); des.setzone (DiscoveryClient.GetZone (II)); serverlist.add (des); }} if (serverlist.size ()> 0 && priorItizevIpaddressBasedServer) {break; // Jika vipaddress saat ini memiliki server, kami tidak menggunakan server berbasis VIPAddress berikutnya}}} return sverlist; } // dihilangkan}Dapat dilihat bahwa itu sebenarnya untuk mendapatkan semua informasi instance layanan dari server Eureka melalui klien Eureka dan mengemas yang online ke instance DiscoveryEnabledServer, dengan informasi zona, dan memasukkannya ke dalam daftar layanan.
2. Saring daftar informasi layanan yang diperoleh melalui instance ServerListFilter.
Instance ServerListFilte adalah zonePreferenceServerListFilter yang dihasilkan pada tahap konfigurasi, dan difilter dengan memanggil metode GetFilteredListOfServer dari instance.
@Data@equalsandHashCode (calluper = false) kelas publik zonePreferenceServerListFilter memperluas zoneaffinityserverlistFilter <server> {private string zona; @Override public void initwithniwsconfig (iclientConfig niwsclientConfig) {super.initwithniwsconfig (niwsclientConfig); if (configurationManager.getDeploymentContext ()! = null) {this.zone = configurationManager.getDeploymentContext (). getValue (contextKey.zone); }} @Override Daftar publik <server> getFilteredListOfServer (Daftar <Server> Server) {Daftar <Server> output = super.getFilteredListOfServer (server); if (this.zone! = null && output.size () == server.size ()) {list <sver> local = new ArrayList <server> (); untuk (server server: output) {if (this.zone.equalSignorecase (server.getZone ())) {local.add (server); }} if (! local.isempty ()) {return local; }} return output; }}Dalam metode GetFilteredListOfServer, hal pertama yang Anda inginkan adalah memanggil nama yang sama dengan kelas orang tua untuk memfilter terlebih dahulu. Bahkan, kelas induk juga menyaring layanan di area yang sama dengan sisi konsumen. Tidak hanya itu, tetapi juga menambahkan beberapa penilaian cerdas untuk memastikan bahwa penyaringan di area yang sama tidak dilakukan ketika kegagalan/beban tinggi atau ketika ada beberapa contoh yang tersedia.
Namun, di zonepreferenceserverlistfilter.getFilteredListOfServer, bahkan jika kelas induk belum disaring, layanan dari zona yang sama masih perlu disaring dan digunakan. Siapa bilang kelas di sini adalah zonepreference?
Ini adalah hal yang agak aneh, dan rasanya bahwa penilaian cerdas dari kelas orang tua tidak berpengaruh.
Mari kita lihat kerja keras yang dilakukan oleh zoneaffinityserverlistfilter.getFilteredlistofserver.
kelas publik zoneaffinityserverlistfilter <t extends server> memperluas abstractServerlistFilter <t> mengimplementasikan iclientConfigAware {// boolean private handenablezoneaffinity (daftar <t> difilter) {if (! zoneaffinity &&! zoneExclusive) {return false; } if (zoneExclusive) {return true; } Statistik loadBalanStats = getLoadBaNCerstats (); if (stats == null) {return zoneaffinity; } else {logger.debug ("Menentukan apakah afinitas zona harus diaktifkan dengan daftar server yang diberikan: {}", difilter); Snapshot zonesnapshot = stats.getzonesnapshot (difilter); double loadPerserver = snapshot.getLoadPerserver (); int instanceCount = snapshot.getInstanceCount (); int circuitbreakertrippedCount = snapshot.getCircuTtrippedCount (); if (((((double) circuitbreakertrippedCount) / instanceCount> = blackoutserverPerCentAgethreshold.get () || loadperserver> = ActiveReQeustSperServerRhreshold.get () || (InstanceCount - CircuitBreakerTippount) <versableServersSthreshold.get (). blackOutServerPercentage: {}, activeReqeustsPerServer: {}, availableServers: {}", new Object[] {(double) circuitBreakerTrippedCount / instanceCount, loadPerServer, instanceCount - circuitBreakerTrippedCount}); return false; } else { return true; } } } @Override public List<T> getFilteredListOfServers(List<T> servers) { if (zone != null && (zoneAffinity || zoneExclusive) && servers !=null && servers.size() > 0){ List<T> filteredServers = Lists.newArrayList(Iterables.filter( servers, this.zoneaffinitypredicate.getServeronlypredicate ()));Pertama, layanan dari zona yang sama dengan sisi konsumen akan disaring, dan kemudian layanan dari zona yang sama akan ditentukan oleh seharusnya dapatEnablezoneaffinity (filteredserver) untuk menentukan apakah layanan dari zona yang sama dapat diadopsi atau semua layanan dapat diadopsi.
Dalam metode seharusnya dapat dilakukan, snapshot dilakukan untuk layanan dari zona yang sama, dan jumlah instance, beban rata -rata, dan jumlah contoh layanan ini diperoleh untuk perhitungan dan penilaian.
Anda dapat melihat nilai -nilai indikator kunci dalam metode initwithniwsconfig.
Kondisi Keputusan:
Persentase pemutus sirkuit> = 0,8 (jumlah pemutus sirkuit/jumlah instance layanan)
Beban rata -rata> = 0,6
Jumlah contoh yang tersedia <2 (jumlah instance - jumlah instance yang rusak)
Jika kondisi penilaian dipenuhi, maka semua layanan akan digunakan untuk memastikan ketersediaan.
Namun, seperti yang disebutkan di atas, karena zonePreferenceServerListFilter sendiri selalu memilih layanan yang konsisten dengan zona konsumen, operasi cerdas yang dilakukan di zoneaffinityserverlistfilter.getFilteredListofserver tidak berguna.
Namun, tentu saja, Anda dapat menggunakan instance ZoneaffinityServerListFilter melalui konfigurasi khusus.
3. Simpan daftar informasi layanan yang difilter ke LoadBalanStats sebagai negara yang ditahan.
Tindak lanjut updateAllServerList(servers); Dan melangkah lebih dalam langkah demi langkah, Anda akan menemukan bahwa itu sebenarnya disimpan di LoadBalancerStats , dan layanan pada saat ini disimpan dalam struktur HashMap<String, List<Server>> sesuai dengan pengelompokan zona, dan kuncinya adalah zona.
Pilih Layanan
Penyeimbang beban yang mengimplementasikan antarmuka Iloadbalancer digunakan untuk memilih layanan dengan mengimplementasikan metode ChoiceServer, dan layanan yang dipilih digunakan sebagai layanan permintaan target.
Lihatlah metode zoneawareloadbalancer.Chooseserver.
@Override Public Server ChooseserVer (Kunci Objek) {if (! Enabled.get () || getLoadBalanCerstats (). GetAvailablezones (). Size () <= 1) {logger.debug ("logika naskah zona dinonaktifkan atau hanya ada satu zona"); return super.chooseserver (kunci); } Server server = null; coba {loadBalanCerstats lbstats = getLoadBaNCerstats (); Peta <string, zonesnapshot> zonesnapshot = zoneAvoidancerule.createSnapshot (lbstats); logger.debug ("Snapshot zona: {}", zonesnapshot); if (TriggeringLoad == null) {TriggeringLoad = DynamicPropertyFactory.getInstance (). GetDoubleProperty ("ZoneAwareniWsDiscoveryLoadBalancer." + this.getname () + ".TrigeringLoadPerServerThreshold", 0.2d); } if (TriggeringBlackOutPerCentage == null) {triggeringBlackOutPentage = DynamicPropertyFactory.getInstance (). GetDoubleProperty ("ZoneAwareniWsDiscoveryBalAncer." + This.getName () + ". } Atur <string> tersediazones = zoneAvoidancerule.getAvailablezones (zonesnapshot, triggeringload.get (), triggeringblackoutpercentage.get ()); logger.debug ("zona yang tersedia: {}", tersediazones); if (tersediazones! = null && adventSezones.size () <zonesnapshot.keyset (). size ()) {string zone = zoneAvoidancerule.randomchooseZone (zonesnapshot, adventhones); logger.debug ("zona dipilih: {}", zona); if (zona! = null) {BaseloadBalancer zoneloadbalancer = getloadbalancer (zona); server = zoneloadbalancer.chooseserver (key); }}} catch (Exception e) {logger.error ("Kesalahan Memilih Server Menggunakan Logika Penghargaan Zona untuk Load Balancer = {}", name, e); } if (server! = null) {return server; } else {logger.debug ("Logika penghindaran zona tidak dipanggil."); return super.chooseserver (kunci); }}Perhatikan bahwa ada dua penggunaan di sini:
1. Matikan Balancing Load-Ware Load dengan Mengkonfigurasi ZoneAwareniWsDiscoveryLoadBalancer.enabled = false, atau jumlah zona <= 1.
2. Gunakan persepsi zona, atau jumlah zona adalah> 1.
Mari kita lihat satu per satu
1. Matikan Balancing Load-Ware Load dengan Mengkonfigurasi ZoneAwareniWsDiscoveryLoadBalancer.enabled = false, atau jumlah zona <= 1.
Dalam hal ini, metode kelas induk Baseloadbalancer.Chooseserver disebut.
server publik memilihPer (tombol objek) {if (counter == null) {counter = createCounter (); } counter.increment (); if (aturan == null) {return null; } else {coba {return aturan.Choose (key); } catch (exception e) {logger.warn ("loadBalancer [{}]: kesalahan memilih server untuk kunci {}", name, key, e); kembali nol; }}}Aturan kebijakan penyeimbang beban yang digunakan di sini sebenarnya adalah instance kebijakan zonevoidancerule yang dihasilkan selama fase konfigurasi yang ditransmisikan saat membangun zoneagareloadbalancer.
public void setRule (aturan irule) {if (aturan! = null) {this.rule = aturan; } else { / * aturan default * / this.rule = new roundrobinrule (); } if (this.rule.getLoadBalancer ()! = this) {this.rule.setloadBalancer (this); }}Asumsikan bahwa jika tidak ada konfigurasi, instance kebijakan Roundrobinrule default digunakan.
2. Gunakan persepsi zona, atau jumlah zona adalah> 1.
Public Server ChooseserVer (Kunci Objek) {if (! Diaktifkan.get () || getLoadBaNCerstats (). getAvailableZones (). size () <= 1) {logger.debug ("logika nikmat zona dinonaktifkan atau hanya ada satu zona"); return super.chooseserver (kunci); } Server server = null; coba {loadBalanCerstats lbstats = getLoadBaNCerstats (); Peta <string, zonesnapshot> zonesnapshot = zoneAvoidancerule.createSnapshot (lbstats); logger.debug ("Snapshot zona: {}", zonesnapshot); if (TriggeringLoad == null) {TriggeringLoad = DynamicPropertyFactory.getInstance (). GetDoubleProperty ("ZoneAwareniWsDiscoveryLoadBalancer." + this.getname () + ".TrigeringLoadPerServerThreshold", 0.2d); } if (TriggeringBlackOutPerCentage == null) {triggeringBlackOutPentage = DynamicPropertyFactory.getInstance (). GetDoubleProperty ("ZoneAwareniWsDiscoveryBalAncer." + This.getName () + ". } Atur <string> tersediazones = zoneAvoidancerule.getAvailablezones (zonesnapshot, triggeringload.get (), triggeringblackoutpercentage.get ()); logger.debug ("zona yang tersedia: {}", tersediazones); if (tersediazones! = null && adventSezones.size () <zonesnapshot.keyset (). size ()) {string zone = zoneAvoidancerule.randomchooseZone (zonesnapshot, adventhones); logger.debug ("zona dipilih: {}", zona); if (zona! = null) {BaseloadBalancer zoneloadbalancer = getloadbalancer (zona); server = zoneloadbalancer.chooseserver (key); }}} catch (Exception e) {logger.error ("Kesalahan Memilih Server Menggunakan Logika Penghargaan Zona untuk Load Balancer = {}", name, e); } if (server! = null) {return server; } else {logger.debug ("Logika penghindaran zona tidak dipanggil."); return super.chooseserver (kunci); }}Dalam hal ini, kebijakan penyeimbangan beban zonevoidancerule digunakan secara default.
Dapatkan informasi snapshot dari zona tersebut.
Dapatkan zona yang tersedia, dengan mengamati zonevoidancerule.getavailablezones definisi, kondisi bahwa bukan zona yang tersedia adalah:
Setelah semua zona yang tersedia diperoleh, pilih satu secara acak.
Dan dari zona ini, pilih layanan melalui kelas induk Baseloadbalancer dari ZoneAwareloadbalancer.Chooseserver. Seperti yang dikompilasi di atas, jika tidak ada aturan yang disahkan di Baseloadbalancer, maka kebijakan Roundrobinrule digunakan secara default untuk menemukan layanan.
Bahkan, masih menjadi masalah mendapatkan filter zonepreferenceserverlistFilter di atas. Bahkan, hanya satu layanan dengan zona yang sama dengan sisi konsumen disaring. Oleh karena itu, fungsi memilih layanan dari zona yang tersedia di Bagian 2 tidak dapat dicapai. Untuk mencapainya, filter harus diganti.
Meringkaskan:
Penyeimbang beban yang dikonfigurasi akan memulai jadwal untuk mendapatkan informasi layanan. Saat menggunakan klien Eureka, semua informasi instance layanan akan diperoleh dari layanan Eureka, dan layanan yang dapat digunakan akan disaring melalui filter. Secara default, filter hanya akan menyaring layanan yang sama dengan sisi konsumen. Jika Anda ingin memastikan ketersediaan tinggi, Anda dapat mengonfigurasi filter ZoneaffinityServerListFilter, dan daftar layanan yang difilter akan memilih layanan yang sesuai dengan mengimplementasikan kebijakan penyeimbangan beban antarmuka Irule. Jika Anda menggunakan kebijakan yang sadar zona, Anda dapat memilih layanan yang sesuai dari zona dengan kondisi beban yang baik.