بعد ذلك ، دعونا نلقي نظرة على كيفية الحصول على مثيل الخدمة ، وما هي المعالجة التي تم إجراؤها بعد الحصول عليها ، وكيفية تحديد مثيل الخدمة بعد المعالجة.
اقسم إلى ثلاثة أجزاء:
إعدادات
في قسم التكوين في المقالة السابقة "مبادئ الشريط السحابي الربيعي" ، يمكنك أن ترى أن موازن التحميل الافتراضي هو ZoneawareloadBalancer.
ألقِ نظرة على فئة التكوين.
موقع:
spring-cloud-netflix-core-1.3.5
suppressWarnings ("deprecation")@configuration@enableConfigurationProperties // أمر مهم هنا ، يجب أن يكون الأخير هو الافتراضي ، يجب أن يكون أولاً اختياريًا // انظر https://github.com/spring-cloud/spring-cloud-netflix/issues/2086#issueComment-316281653@import( {OKHTTPRIBBOBBONCONFIGURINT.CLASCINGURINT.CLASTCONFIGURIN حذف bean @conditionalonmissingbean public iLoAdbalancer RibbonLoadBalancer (ICLientConfig config ، serverlist <Server> serverlist ، serverlistfilter <Server> serverlistfilter ، IRUL this.propertiesfactory.get (iloadbalancer.class ، config ، name) ؛ } إرجاع ZoneAwareloadBalancer الجديد <> (التكوين ، القاعدة ، ping ، قائمة الخادم ، ServerListFilter ، ServerListUpDater) ؛ } // حذفت}حقن في مثيل التكوين ، القاعدة ، ping ، serverlist ، serverlistfilter ، serverlistupdater.
التكوين: تكوين المثيل.
القاعدة: مثيل سياسة موازنة التحميل.
بينغ: مثيل بينغ.
قائمة الخادم: يحصل وتحديث مثيل للخدمة.
ServerListFilter: مثيل تصفية الخدمة.
ServerListUpdater: مثيل تحديث معلومات قائمة الخدمة.
suppressWarnings ("deprecation")@configuration@enableConfigurationProperties // أمر مهم هنا ، يجب أن يكون الأخير هو الافتراضي ، يجب أن يكون أولاً اختياريًا // انظر https://github.com/spring-cloud/spring-cloud-netflix/issues/2086#issueComment-316281653@import( {OKHTTPRIBBOBBONCONFIGURINT.CLASCINGURINT.CLASTCONFIGURIN DEFINCONDITITIONALONMISSINGBEAN Public ICLIENTCONFIG RIBBONCLIENTCONFIG () {defaultClientConfigimpl config = new DefaultClientConfigimpl () ؛ config.loadProperties (this.name) ؛ إرجاع التكوين. } beanconditionalonmissingbean public irule ribbonrule (iclientConfig config) {if (this.propertiesfactory.isset (irule.class ، name)) {return this.propertiesfactory.get (irule.class ، config ، name) ؛ } Zoneavoidancerule Rule = New ZoneavoidanCerule () ؛ rule.initwithniwsconfig (config) ؛ قاعدة العودة } beanconditionalonmissingbean public iping ripbonping (iclientConfig config) {if (this.propertiesfactory.isset (iping.class ، name)) {return this.propertiesfactory.get (iping.class ، config ، name) ؛ } إرجاع new dummyping () ؛ } beanconditionalonMissingBeanSuppressWarnings ("Uncheced") قائمة الخادم العامة <sropr> ribbonserverlist (iclientConfig config) {if (this.propertiesfactory.isset (serverlist.class ، name)) } configurationBaredServerList Serverlist = جديد configurationBasedServerList () ؛ serverlist.initwithniwsconfig (config) ؛ إرجاع قائمة الخادم ؛ } beanconditionalonmissingbean public serverlistupdater ribbonserverlistupdater (iclientConfig config) {return new pollingserverlistupdater (config) ؛ } beanconditionalonmissingbean public IloAdbalancer RibbonLoadBalancer (IclientConfig config ، serverlist <server> serverlistfilter <stall> serverlistfilter ، irule rule ، iping ping ، serverlistupdater serveristupdater) {if (this.propertiesfactory.isset. this.propertiesfactory.get (iloadbalancer.class ، config ، name) ؛ } إرجاع ZoneAwareloadBalancer الجديد <> (التكوين ، القاعدة ، ping ، قائمة الخادم ، ServerListFilter ، ServerListUpDater) ؛ } beanconditionalonMissingBeanSuppressWarnings ("Unchected") public serverlistfilter <sroper> ribbonserverlistfilter (iclientConfig config) {{this.propertiesfactory.isset (serverlistfilter.class ، name)) } ZonePreferenceserVerlistFilter Filter = new ZonePreferenceserverListFilter () ؛ filter.initwithniwsconfig (config) ؛ مرشح الإرجاع } beanconditionalonmissingbean public lipbonloadbalancertext ribbonloadbalancertext (iloadbalancer loadbalancer ، iclientconfig config ، restryHandler RetryHandler) {return new RibbonLoadbalancerTex } // حذفت}تكوين الأمثلة ذات الصلة هنا
التكوين: DefaultClientConfigimpl.
القاعدة: ZoneaeAvoidancerule.
بينغ: dummyping.
Serverlist: ConfigurationBariveServerList ، مثيل قائمة الخدمة المستندة إلى التكوين.
ServerListFilter: ZonePreferenceserListFiLter.
ServerListUpdater: PollingServerListupDater.
تجدر الإشارة إلى أن مثيل قائمة الخادم هنا هو ConfigurationBaranceServerList ، وهو مثيل يحصل على معلومات الخدمة عند عدم استخدام Eureka ، ويتم الحصول عليه من ملف التكوين.
لذلك عند استخدام Eureka ، تحتاج إلى الحصول على معلومات الخدمة من خادم Eureka. أي مثال يجب أن يستخدم للقيام بذلك؟
عند تمكين اكتشاف خدمة Eureka ، سيتم اعتماد فئة تكوين EurekaribbonClientConfiguration لأول مرة.
موقع:
spring-cloud-netflix-eureka-client-1.3.5
@configuration @commonslogpublic class eurekaribbonClientConfiguration {// dishbean @conditionalonmissingbean public iping ribbonping (iclientConfig) {if (this.propertiesfactory.isset (iping.class ، serviceid)) } niwsdiscoveryping ping = niwsdiscoveryping () جديد ؛ ping.initwithniwsconfig (config) ؛ العودة بينغ. } beanconditionalonmissingbean public serverlist <؟> ribbonserverlist (iclientConfig config ، مزود <EureKaclient> eurekaclientprovider) {if (this.propertiesfactory.isset (serverlist.class ، serviceid) {return this.propileties. } DiscoveryEnabledNiwsServerList DiscoveryServerList = جديد DiscoveryEnableDniwsServerList (config ، eurekaclientprovider) ؛ DomainExtractingSerVerlist ServerList = New DomainExtractingServerList (DiscoveryServerList ، config ، this.approximatezonefromhostname) ؛ إرجاع قائمة الخادم ؛ } // حذفت}بعد استخدام تكوين EurekaribbonClientConfiguration أولاً ، أصبحت الحالات بالفعل
التكوين: DefaultClientConfigimpl.
القاعدة: ZoneaeAvoidancerule.
بينغ: niwsdiscoveryping.
Serverlist: DomainExtractingSerVerlist ، داخليًا DiscoveryEnableNIWSServerList ، الحصول على قائمة معلومات الخدمة من خلال اكتشاف الخدمة.
ServerListFilter: ZonePreferenceserListFiLter.
ServerListUpdater: PollingServerListupDater.
الحصول على الخدمات
قبل العثور على الوصول إلى الحصول على معلومات الخدمة ، قم أولاً بتحرير علاقة الميراث الفصل من موازن التحميل.
يتم استدعاء بنية DynamicServerListlancer Parent Class في بناء ZoneawareloadBalancer.
موقع:
الشريط الحمل 2.2.2.jar
com.netflix.loadbalancer
ZoneawareloadBalancer.class
في بناء DynamicServerListloadBalancer ، تسمى وظيفة restofinit.
الشريط الحمل 2.2.2.jar
com.netflix.loadbalancer
DynamicServerListListloadBalancer.class
void restofinit (iclientConfig clientConfig) {boolean primeconnection = this.isenablePrimingConnections () ؛ // أوقف هذا الأمر لتجنب التحضير غير المتزامن التكراري في baseloadbalancer.setserverlist () this.setenablePrimingConnections (false) ؛ enableAndInitLearnnewServersFeature () ؛ updatelistofservers () ؛ if (primeConnection && this.getPrimeConnections ()! = null) {this.getPrimEConnections () .primeconnections (getReachableservers ()) ؛ } this.setEnablePrimingConnections (primeconnection) ؛ logger.info ("DynamicServerListListBalancer للعميل {} تهيئة: {}" ، clientConfig.getClientName () ، this.toString ()) ؛ }أولاً ، يتم تحديث قائمة الخدمة بانتظام عن طريق استدعاء طريقة ENALLEANDINITLEARNNEWServersFeature ، ثم اتصل على الفور بوظيفة updatelistofservers للحصول على معلومات قائمة الخدمة على الفور.
دعونا أولاً نلقي نظرة على طريقة enileAndIndinitLearnnewServersFeature. في الواقع ، يتم استدعاء طريقة بدء تشغيل معلومات قائمة الخدمة لبدء وظيفة التحديث المحددة.
/ ** * ميزة تتيح لنا إضافة مثيلات جديدة (من AMIS) إلى قائمة الخوادم الموجودة التي ستستخدمها LB هذه الطريقة إذا كنت تريد هذه الميزة */// void public enileAndIndInitLearnnewServersFeature () {logger.info ("باستخدام serverlistupdater {}} ، serveripdater.getclas (). ServerListUpdater.start (updateaction) ؛ } مثال تحديث معلومات قائمة الخدمة هنا هو مثيل PollingServerListupDater الذي تم تكوينه في مرحلة التكوين. ألقِ نظرة على البناء وبدء طريقة هذه الفئة.
Public Class PollingSerVervistupDater تنفذ ServerListupDater {// Private Static Long ListofServers_Cache_Update_Delay = 1000 ؛ // MSECS ؛ private int intipservers_cache_repeat_interval = 30 * 1000 ؛ // MSECS ؛ // private Final AtomicBoolean Isactive = new AtomicBoolean (false) ؛ private prolatile lastupdated = system.currentTimeMillis () ؛ الأبعاد النهائية الطويلة الطويلة ؛ نهائي خاص طويل RefreshIntervalms. . } publicserverlistupdater (النهائيات الطويلة الطويلة ، refreshInterValms النهائية) {this.initialDelayms = initialDelayms ؛ this.refreshintervalms = RefreshInterValms ؛ } Override Public Synchronized void start (updateaction updateaction النهائي) {if (isactive.compareandset (false ، true)) {final runnable wrapperrunnable = new runnable () } يعود؛ } try {updateaction.doupdate () ؛ lastUpdated = system.currentTimeMillis () ؛ } catch (استثناء e) {logger.warn ("فشلت دورة تحديث واحدة" ، e) ؛ }}}} ؛ ScheduleDfuture = getRefreshexecutor (). } آخر {logger.info ("بالفعل نشط ، no-op") ؛ }} // shf}من البناء والتعريف المستمر ، يتم تأخير التنفيذ بمقدار ثانية واحدة ، ويتم تنفيذ التحديث كل 30 ثانية بشكل افتراضي. يمكنك تعديل وقت التحديث بين التكوين.
من طريقة البدء ، يتم فتح جدول زمني ينفذ بانتظام وتنفيذ updateaction.doupdate () بانتظام.
ارجع إلى فئة START Method Caller DynamicServerListloadBalancer واعلق على تعريف مثيل التحديث.
Final ServerListupDater.upDateAction updateactation = new ServerListupDater.upDateAction () {Override public void doupdate () {updateListofServers () ؛ }} ؛في الواقع ، تم استدعاء طريقة updatelistofservers لفئة DynamicServerListListLoadBalancer ، والتي تتوافق مع المسار لتحديث قائمة معلومات الخدمة مباشرة بعد تحديث وقت بدء التشغيل.
استمر في النظر إلى طريقة updatelistofservers.
public void updatelistofservers () {list <t> servers = new ArrayList <T> () ؛ if (serverListImpl! = null) {servers = serverListImpl.getUpDatedListofServers () ؛ logger.debug ("قائمة الخوادم لـ {} التي تم الحصول عليها من Discovery Client: {}" ، getIdentifier () ، خوادم) ؛ if (filter! = null) {servers = filter.getFilternistofServers (servers) ؛ logger.debug ("قائمة خوادم مرشحين لـ {} تم الحصول عليها من Discovery Client: {}" ، getIdentifier () ، خوادم) ؛ }} updateallserverlist (خوادم) ؛ }1. احصل على قائمة معلومات الخدمة من خلال مثيل قائمة الخادم.
2. تصفية قائمة معلومات الخدمة التي تم الحصول عليها من خلال مثيل ServerListFilter.
3. احفظ قائمة معلومات الخدمة التي تمت تصفيتها إلى LoadBalanCerstats كعقد الدولة.
دعونا نلقي نظرة على ذلك بشكل منفصل بعد ذلك.
1. احصل على قائمة معلومات الخدمة من خلال مثيل قائمة الخادم.
مثيل Serverlist هو DomainExtractingSerVerlist الذي تم إنشاؤه في مرحلة التكوين. يتم تفويض معلومات الخدمة إلى DiscoveryEnabledNiwsServerList.
الطبقة العامة DiscoveryEniableNiwsServerList يمتد الملخصات erverSerList <DiscoveryEnabledServer> {// desferride public list <DiscoveryEnabledServer> getInitialListofServers () {return getverseServersViadscovery () ؛ } Override Public List <SupcistaryEnabledServer> getUpdatedListofServers () {return gettedserversviadiscovery () ؛ } القائمة الخاصة <SuccessyEnabledServer> GOUSTERVERSVIRVIADISSOVERY () {list <DiscoveryEnabledServer> serverlist = new ArrayList <DiscoveryEnableServer> () ؛ if (eurekaclientProvider == null || eurekaclientprovider.get () == null) {logger.warn ("لم يتم تهيئة eurekaclient بعد ، وإعادة قائمة فارغة") ؛ إرجاع ArrayList جديد <DiscoveryEnabledServer> () ؛ } eurekaclient eurekaclient = eurekaclientProvider.get () ؛ if (vipaddresses! = null) {for (string vipaddress: vipaddresses.split ("،")) {// إذا كان targetregion خاليًا ، فسيتم تفسيره على أنه نفس منطقة العميل <exateininfo> listofinstanceinfo = eurekaclient.getInstancesByvress (vipaddress ، لـ (extueInfo II: listofinstanceInfo) {if (ii.getStatus (). equals (instancestatus.up)) {if (us outuedoverrideport) {if (logger.isdebugenabled ()) } // COPY ضرورية نظرًا لأن Builder extalInfo يستخدم فقط المرجع الأصلي ، // لا نريد أن نتفقد نسخة Eureka العالمية من الكائن الذي قد يتم استخدامه من قبل عملاء آخرين في copyinfo system extorly = new exateinfo (ii) ؛ if (issecure) {ii = new extalinfo.builder (copy) .SetSecurePort (overrideport) .build () ؛ } else {ii = new easuleInfo.builder (copy) .setport (overrideport) .build () ؛ }} discoveryEnabledServer des = new DiscoveryEnabledServer (II ، issecure ، heaustueipaddr) ؛ des.setzone (discoveryclient.getzone (ii)) ؛ serverlist.add (des) ؛ }} if (serverlist.size ()> 0 && plirstizeVipAdDressBasedServers) {break ؛ // إذا كان لدى Vipaddress الحالي خوادم ، فإننا لا نستخدم Server Servial}}}}} ؛ } // حذفت}يمكن ملاحظة أنه في الواقع الحصول على جميع معلومات مثيل الخدمة من خادم Eureka من خلال عميل Eureka وحزمها عبر الإنترنت في مثيلات DiscoveryEnabledServer ، مع معلومات المنطقة ، ووضعها في قائمة الخدمة.
2. تصفية قائمة معلومات الخدمة التي تم الحصول عليها من خلال مثيل ServerListFilter.
مثيل ServerListFilte هو ZonePreferenceserListFilter الذي تم إنشاؤه في مرحلة التكوين ، ويتم ترشيحه عن طريق استدعاء طريقة getFilternistofServers للمثيل.
@data@equalsandhashcode (callsuper = false) ZonePreferenceserRistFlisterfilter يمتد ZoneaffinityServerListFilter <stall> {منطقة السلسلة الخاصة ؛ Override public void initWithNiwsConfig (IclientConfig niwsClientConfig) {super.initwithniwsconfig (niwsclientConfig) ؛ if (configurationManager.getDeploymentContext ()! = null) {this.zone = configurationManager.getDeploymentContext (). getValue (contextKey.Zone) ؛ }} Override Public List <Sropr> getFilterNedListoFServers (List <Server> Servers) {List <Server> output = super.getFilternistofServers (servers) ؛ if (this.zone! = null && output.size () == suver.size ()) {list <sroper> local = new ArrayList <Server> () ؛ لـ (Server Server: Output) {if (this.zone.equalsignorecase (server.getzone ())) {local.add (server) ؛ }} if (! local.isempty ()) {return local ؛ }} إخراج الإرجاع ؛ }}في طريقة getFilteredListofServers ، فإن أول شيء تريده هو استدعاء نفس اسم الفئة الأصل للتصفية أولاً. في الواقع ، تقوم فئة الوالدين أيضًا بتصفية الخدمات في نفس منطقة جانب المستهلك. ليس ذلك فحسب ، بل يضيف بعض الأحكام الذكية لضمان عدم إجراء التصفية في نفس المنطقة عندما يكون الفشل/الحمل مرتفعًا أو عندما يكون هناك عدد قليل من الحالات المتاحة.
ومع ذلك ، في ZonePreferenceserListFilter.getFilternistofServers ، حتى لو لم تتم تصفية الفئة الأم ، لا تزال خدمات نفس المنطقة تحتاج إلى ترشيحها واستخدامها. من قال أن الفصل هنا هو ZonePreference؟
هذا شيء غريب إلى حد ما ، ويشعر أن الحكم الذكي لفئة الوالدين ليس له أي تأثير.
دعنا نلقي نظرة على العمل الشاق الذي قامت به ZoneaffinityServerListFilter.getFilternistofServers.
ZoneaftInityServerListFilter <t يمتد الخادم> تمديد ملخصات agrusserverlistfilter <t> تنفذ iclientConfigaWare {// private boolean dithenablezoneaffint (list <t> fultled) {if (! zoneaffinity &&! } if (ZoneExClusive) {return true ؛ } stats loadbalancerstats = getLoadBalancerStats () ؛ if (stats == null) {return Zoneaftinity ؛ } آخر {logger.debug ("تحديد ما إذا كان ينبغي تمكين تقارب المنطقة مع قائمة الخادم المعطى: {}" ، filleded) ؛ ZonesNapshot snapshot = stats.getzonesnapshot (مرشح) ؛ double loadperserver = snapshot.getloadperserver () ؛ int instancecount = snapshot.getInStanCecount () ؛ int circuterbreakerTructionCount = snapshot.getCircuitTructionCount () ؛ إذا ((((مزدوج) دائرة breakerTructionCount) / instancecount> = BlackoutServerPerCengethReshold.get () || loadPerserver> = ActivereQeustSperServerThold.get () || (instanceCount - CircuitBreakerTructionCount) <vivalistableSreshold.get () {logger.debug. BlackoutServerPerPerCentage: {} ، activereqeustsperserver: {} ، متوفرون: {} "، كائن جديد [] {(double) circuterBreakerTructionCount / Instancecount ، loadPerserver ، instancecount - circuterbreakertructioncount}) ؛ getFilternistofServers (قائمة <T> خوادم) {if (Zone! = null && (Zoneaffint || ZoneExclusive) (chitenablezoneaffint (filterservers)) {return filterservers ؛أولاً ، سيتم تصفية خدمات نفس منطقة المستهلك ، وبعد ذلك سيتم تحديد خدمات نفس المنطقة من خلال UnderenableZoneaffinity (filterdservers) لتحديد ما إذا كان يمكن اعتماد خدمات نفس المنطقة أو يمكن اعتماد جميع الخدمات.
في طريقة itnudenablezoneaffinity ، يتم إجراء لقطة لخدمات من نفس المنطقة ، ويتم الحصول على عدد الحالات ، ومتوسط الحمل ، وعدد مثيلات هذه الخدمات للحساب والحكم.
يمكنك إلقاء نظرة على قيم المؤشرات الرئيسية في طريقة initWithNiwsConfig.
شروط القرار:
النسبة المئوية من قواطع الدوائر> = 0.8 (عدد قواطع الدائرة/عدد مثيلات الخدمة)
متوسط التحميل> = 0.6
عدد الحالات المتاحة <2 (عدد الحالات - عدد الحالات المكسورة)
إذا تم استيفاء شروط الحكم ، فسيتم استخدام جميع الخدمات لضمان التوفر.
ومع ذلك ، كما ذكر أعلاه ، نظرًا لأن ZonePreferenceserverlistFilter نفسها تختار دائمًا الخدمات التي تتوافق مع مناطق المستهلكين ، فإن العمليات الذكية التي تم إجراؤها في ZoneafinityServerListFilter.GetFilternistofServers لا تستخدم.
ومع ذلك ، بالطبع ، يمكنك استخدام مثيلات ZoneaffinityServerListFilter من خلال التكوينات المخصصة.
3. احفظ قائمة معلومات الخدمة التي تمت تصفيتها إلى LoadBalanCerstats كعقد الدولة.
متابعة updateAllServerList(servers); وانتقل إلى أعمق خطوة بخطوة ، ستجد أنه يتم حفظه فعليًا في LoadBalancerStats ، ويتم حفظ الخدمات في هذا الوقت في HashMap<String, List<Server>> وفقًا لتجميع المنطقة ، والمفتاح هو المنطقة.
حدد خدمة
يتم استخدام موازن التحميل الذي ينفذ واجهة IloAdbalancer لتحديد الخدمات عن طريق تطبيق طريقة Choiceserver ، ويتم استخدام الخدمة المحددة كخدمة الطلب المستهدف.
ألقِ نظرة على طريقة ZoneaWareloadBalancer.ChooseServer.
Override Public Server Toinserver (مفتاح الكائن) {if (! enupper.get () || getLoadBalancerStats (). getAvailable (). size () <= 1) {logger.debug ("Zone Aware Logic is or year arey") ؛ إرجاع Super.ChooseServer (مفتاح) ؛ } خادم الخادم = null ؛ حاول {loadBalanCerstats lbstats = getLoadBalanCerstats () ؛ MAP <string ، ZONESNAPSHOT> ZONESNAPSHOT = ZONEAVOIDANCERULE.CRATESNAPSHOT (LBSTATS) ؛ logger.debug ("لقطات المنطقة: {}" ، ZonesNapshot) ؛ if (triggeringload == null) {triggeringload = dynamicpropertyfactory.getInstance (). } if (triggeringBlackoutPerCenge == null) {triggeringBlackoutPerCenage = dynamicPropertyFactory.getInstance (). getDoubleProperty ( } set <String> AvailableZones = Zoneavoidancerule.getAvailablezones (ZonesNapshot ، triggeringload.get () ، triggerblackoutpercentage.get ()) ؛ logger.debug ("المناطق المتوفرة: {}" ، متاحة للـ) ؛ if (AvailableSones! = null && Avavorezones.size () <zonesnapshot.keyset (). size ()) {string Zone = Zoneavoidancerule.RandomChoosezone (Zonesnapshot ، Availesszones) ؛ logger.debug ("المنطقة المختارة: {}" ، Zone) ؛ if (Zone! = null) {baseloadbalancer ZonelOadBalancer = getLoadBalancer (Zone) ؛ server = zoneloadbalancer.ChooseServer (key) ؛ }}} catch (استثناء e) {logger.error ("خطأ في اختيار الخادم باستخدام منطق Zone Aware for load balancer = {}" ، name ، e) ؛ } if (server! = null) {return server ؛ } آخر {logger.debug ("لا يتم استدعاء منطق تجنب المنطقة.") ؛ إرجاع Super.ChooseServer (مفتاح) ؛ }}لاحظ أن هناك استخدامان هنا:
1. قم بإيقاف تشغيل موازنة التحميل المدركة للمنطقة عن طريق تكوين ZoneaWareniwsDiscoveryLoadBalancer.endabled = false ، أو عدد المناطق <= 1.
2. استخدام إدراك المنطقة ، أو عدد المناطق هو> 1.
دعونا نلقي نظرة واحدة تلو الأخرى
1. قم بإيقاف تشغيل موازنة التحميل المدركة للمنطقة عن طريق تكوين ZoneaWareniwsDiscoveryLoadBalancer.endabled = false ، أو عدد المناطق <= 1.
في هذه الحالة ، تسمى طريقة BaseLoadBalancer.
Server Public CoinserVer (مفتاح الكائن) {if (counter == null) {counter = createCounter () ؛ } counter.increment () ؛ if (rule == null) {return null ؛ } else {try {return rule.choose (key) ؛ } catch (استثناء e) {logger.warn ("loadbalancer [{}]: خطأ في اختيار الخادم للمفتاح {}" ، الاسم ، المفتاح ، e) ؛ العودة لاغية. }}}قاعدة سياسة موازنة التحميل المستخدمة هنا هي في الواقع مثيل سياسة Zoneavoidancerule الذي تم إنشاؤه خلال مرحلة التكوين التي تم نقلها عند بناء zoneawareloadbalancer.
public void setRule (قاعدة irule) {if (rule! = null) {this.rule = rule ؛ } آخر { / * القاعدة الافتراضية * / this.rule = new RoundRobinRule () ؛ } if (this.rule.getLoadBalancer ()! = this) {this.rule.setLoadBalancer (this) ؛ }}افترض أنه إذا لم يكن هناك تكوين ، يتم استخدام مثيل سياسة RoundRobinRule الافتراضي.
2. استخدام إدراك المنطقة ، أو عدد المناطق هو> 1.
server public choinserver (مفتاح الكائن) {if (! enabled.get () || getLoadBalancerStats (). getavailable (). size () <= 1) {logger.debug ("تعطيل المنطق المدير للمنطقة أو هناك منطقة واحدة فقط") ؛ إرجاع Super.ChooseServer (مفتاح) ؛ } خادم الخادم = null ؛ حاول {loadBalanCerstats lbstats = getLoadBalanCerstats () ؛ MAP <string ، ZONESNAPSHOT> ZONESNAPSHOT = ZONEAVOIDANCERULE.CRATESNAPSHOT (LBSTATS) ؛ logger.debug ("لقطات المنطقة: {}" ، ZonesNapshot) ؛ if (triggeringload == null) {triggeringload = dynamicpropertyfactory.getInstance (). } if (triggeringBlackoutPerCenge == null) {triggeringBlackoutPerCenage = dynamicPropertyFactory.getInstance (). getDoubleProperty ( } set <String> AvailableZones = Zoneavoidancerule.getAvailablezones (ZonesNapshot ، triggeringload.get () ، triggerblackoutpercentage.get ()) ؛ logger.debug ("المناطق المتوفرة: {}" ، متاحة للـ) ؛ if (AvailableSones! = null && Avavorezones.size () <zonesnapshot.keyset (). size ()) {string Zone = Zoneavoidancerule.RandomChoosezone (Zonesnapshot ، Availesszones) ؛ logger.debug ("المنطقة المختارة: {}" ، Zone) ؛ if (Zone! = null) {baseloadbalancer ZonelOadBalancer = getLoadBalancer (Zone) ؛ server = zoneloadbalancer.ChooseServer (key) ؛ }}} catch (استثناء e) {logger.error ("خطأ في اختيار الخادم باستخدام منطق Zone Aware for load balancer = {}" ، name ، e) ؛ } if (server! = null) {return server ؛ } آخر {logger.debug ("لا يتم استدعاء منطق تجنب المنطقة.") ؛ إرجاع Super.ChooseServer (مفتاح) ؛ }}في هذه الحالة ، يتم استخدام سياسة موازنة تحميل Zoneavoidancerule بشكل افتراضي.
الحصول على معلومات لقطة في المنطقة.
احصل على المنطقة المتاحة ، من خلال مراقبة تعريف Zoneavoidancerule.getavailable ، الشرط الذي ليس المنطقة المتاحة هي:
بعد الحصول على جميع المناطق المتاحة ، اختر واحدة بشكل عشوائي.
ومن هذه المنطقة ، حدد الخدمة من خلال فئة الأصل BASELOADBALANCER من ZONEAWARELOADBALANCER.CHOOSESERVER. كما تم تجميعه أعلاه ، إذا لم يتم تمرير قاعدة في BaseloadBalancer ، يتم استخدام سياسة RoundRobinrule افتراضيًا للعثور على خدمة.
في الواقع ، لا تزال مشكلة الحصول على مرشح ZonePreferenceserListFilter أعلاه. في الواقع ، يتم ترشيح خدمة واحدة فقط مع نفس المنطقة التي يتم تصفية جانب المستهلك. لذلك ، لا يمكن تحقيق وظيفة اختيار الخدمات من المناطق المتاحة في الجزء 2. للوصول إليه ، يجب استبدال المرشح.
تلخيص:
ستبدأ موازن التحميل المكون من الجدول الزمني للحصول على معلومات الخدمة. عند استخدام عميل Eureka ، سيتم الحصول على جميع معلومات مثيل الخدمة من خدمة Eureka ، وسيتم تصفية الخدمات التي يمكن استخدامها من خلال المرشح. بشكل افتراضي ، سيقوم المرشح فقط بتصفية الخدمات التي تشبه جانب المستهلك. إذا كنت ترغب في التأكد من توافر عالي ، فيمكنك تكوين مرشح ZoneAffinityServerListFilter ، وستختار قائمة الخدمة التي تمت تصفيتها الخدمة المقابلة عن طريق تنفيذ سياسة موازنة التحميل الخاصة بواجهة Irule. إذا كنت تستخدم سياسة تدرك المنطقة ، فيمكنك تحديد الخدمة المناسبة من المنطقة مع ظروف تحميل جيدة.