Ribbon เป็นโครงการโอเพ่นซอร์สที่ออกโดย Netflix ฟังก์ชั่นหลักของมันคือการจัดหาอัลกอริทึมการโหลดบาลานซ์ซอฟต์แวร์ฝั่งไคลเอ็นต์เพื่อเชื่อมต่อบริการระดับกลางของ Netflix เข้าด้วยกัน ส่วนประกอบไคลเอนต์ริบบิ้นมีชุดของรายการการกำหนดค่าที่สมบูรณ์เช่นการหมดเวลาการเชื่อมต่อการลองใหม่ ฯลฯ เพียงแค่ใส่มันคือการแสดงรายการเครื่องทั้งหมดที่อยู่ด้านหลังโหลดบาลานซ์ (LB สั้น ๆ ) ในไฟล์การกำหนดค่า Ribbon จะช่วยให้คุณเชื่อมต่อเครื่องเหล่านี้โดยอัตโนมัติตามกฎบางอย่าง (เช่นการสำรวจอย่างง่ายการเชื่อมต่อทันที ฯลฯ ) นอกจากนี้เรายังมีวิธีที่ง่ายมากในการใช้อัลกอริทึมการปรับสมดุลการโหลดแบบกำหนดเองโดยใช้ริบบิ้น
เมื่อพูดถึงการบาลานซ์โหลดคุณมักจะนึกถึงโหลดบาลานซ์บนเซิร์ฟเวอร์ ผลิตภัณฑ์ที่ใช้กันทั่วไป ได้แก่ LBS ฮาร์ดแวร์หรือบริการคลาวด์, Nginx, ฯลฯ ซึ่งเป็นผลิตภัณฑ์ที่คุ้นเคยทั้งหมด
Spring Cloud ให้ Ribbon ซึ่งช่วยให้ผู้เรียกบริการมีความสามารถในการโหลดบาลานซ์ ผ่านการรวมเข้าด้วยกันอย่างใกล้ชิดกับยูเรก้าไม่จำเป็นต้องตั้งค่าบริการโหลดบาลานซ์ในคลัสเตอร์บริการซึ่งทำให้สถาปัตยกรรมง่ายขึ้นอย่างมากภายในคลัสเตอร์บริการ
ฉันไม่ต้องการเขียนรายละเอียดการแนะนำเสมือนจริงมากขึ้น แต่ฉันสามารถเห็นการแนะนำที่เกี่ยวข้องได้ทุกที่
เพียงเปิดรหัสและดูว่าริบบิ้นถูกนำไปใช้อย่างไรผ่านรหัส
การกำหนดค่า
คำอธิบายโดยละเอียด:
1. การกำหนดค่า Ribbonautoconfiguration สร้างอินสแตนซ์ของ Ribbonloadbalancerclient
รหัสตำแหน่ง:
Spring-Cloud-Netflix-core-1.3.5.Release.jar
org.springframework.cloud.netflix.ribbon
Ribbonautoconfiguration.class
@configuration@conditionalOnclass ({iclient.class, resttemplate.class, asyncresttemplate.class, ribbon.class})@ribbonclients@autoconfigureafter (name = name = "org.springframework.cloud.netflix.eureka.eurekaclientautoconfiguration")@autoconfigurebefore ({loadbalancerautoconfiguration.class Ribbonautoconfiguration {// omit @bean @conditionalonmissingbean (loadbalancerclient.class) Public Loadbalancerclient Loadbalancerclient () {ส่งคืนริบบิ้นใหม่ } // omit}ก่อนอื่นให้ดูที่รายการเงื่อนไขการกำหนดค่า การกำหนดค่า Ribbonautoconfiguration จะต้องดำเนินการก่อนการกำหนดค่า loadbalancerautoconfiguration เนื่องจากอินสแตนซ์ของ Ribbonloadbalancerclient จะถูกใช้ในการกำหนดค่า loadbalancerautoconfiguration
Ribbonloadbalancerclient สืบทอดมาจากอินเทอร์เฟซ loadbalancerclient เป็นไคลเอนต์โหลดบาลานซ์และผู้โทรของนโยบายการปรับสมดุลการโหลด
2. การสร้างการกำหนดค่าการกำหนดค่าการกำหนดค่า:
1). อินสแตนซ์ของ load balancerceptor
รวม:
อินสแตนซ์ของ Ribbonloadbalancerclient ของคลาสการใช้งาน loadbalancerclient
LoadBalancerRequestFactory: อินสแตนซ์
2). resttemplate อินสแตนซ์ RESTTEMPLATECUSTOMIZER ที่กำหนดเอง
รหัสตำแหน่ง:
Spring-Cloud-commons-1.2.4.release.jar
org.springframework.cloud.client.loadbalancer
loadbalancerautoconfiguration.class
@Configuration@ConditionalOnClass (RestTemplate.class) @conditionalonbean (loadbalancerclient.class) @enableConfigurationProperties (loadbalancerretryproperties.class) ชั้นเรียนสาธารณะ loadbalancerautoconfiguration LoadBalancerRequestFactory (loadbalancerclient loadbalancerclient) {ส่งคืน loadbalancerrequestfactory ใหม่ (loadbalancerclient, หม้อแปลง); } @configuration @conditionalonmissingclass ("org.springframework.retry.support.retryTemplate") คลาสคงที่ loadbalancerceptorConfig {@bean public loadbalancerinterceptor ribboninterceptor LoadBalancerInterceptor (loadbalancerclient, RequestFactory); } @Bean @ConditionAlonMissingBean RESTTEMPLATECUSTOMIZER RESTTEMPLATECUSTOMIZER ขั้นสุดท้าย LOADBALANCERINTERPETOR LOADBALANCERINTERCETCORTOR) {ส่งคืนใหม่ RESTTEMPLATECUSTOMIZER () {@OverRide Public Void ปรับแต่ง RestTemplate.getInterceptors ()); list.add (loadbalancerinterceptor); RestTemplate.SetInterceptors (รายการ); - }} // ละเว้น}มาดูเงื่อนไขการกำหนดค่าก่อน:
จำเป็นต้องมีคลาส resttemplate ในสภาพแวดล้อมโครงการ
จำเป็นต้องมีอินสแตนซ์ของคลาสการใช้งานของอินเทอร์เฟซ loadbalancerclient นั่นคือ ribbonloadbalanclient ที่สร้างขึ้นในขั้นตอนก่อนหน้า
3. กำหนดค่าอินสแตนซ์ของ RestTemplate ทั้งหมดผ่าน RestTemplateCustomizer ที่สร้างขึ้นในขั้นตอนด้านบนซึ่งคือการตั้งค่าการดักจับโหลดบาลานซ์เป็นอินสแตนซ์ของ RestTemplate
@Configuration@conditionalOnClass (resttemplate.class) @conditionalonbean (loadbalancerclient.class) @enableConfigurationProperties (loadbalancerretryproperties.class) คลาสสาธารณะ loadbalancerautoconfiguration รายการ <resttemplatecustomizer> customizers) {ส่งคืนใหม่ smartinitializingsingleton () {@Override โมฆะสาธารณะ aftersingletonsinstantiated () {สำหรับ (resttemplate resttemplate: loadbalancerautoconfiguration.his.resttemplates) Customizer.customize (RestTemplate); - } // omit @configuration @conditionalonmissingclass ("org.springframework.retry.support.retertemplate") คลาสคงที่ loadbalancerinterceptorconfig {@bean public loadbalancerceptorceptor LoadBalancerInterceptor (loadbalancerclient, RequestFactory); } @Bean @ConditionAlonMissingBean RESTTEMPLATECUSTOMIZER RESTTEMPLATECUSTOMIZER ขั้นสุดท้าย LOADBALANCERINTERPETOR LOADBALANCERINTERCETCORTOR) {ส่งคืนใหม่ RESTTEMPLATECUSTOMIZER () {@OverRide Public Void ปรับแต่ง RestTemplate.getInterceptors ()); list.add (loadbalancerinterceptor); RestTemplate.SetInterceptors (รายการ); - }} // ละเว้น}RestTemplate.SetInterceptors (รายการ) สถานที่นี้เป็นสถานที่ที่ถูกฉีดเข้าโหลดบาลานซ์โหลด
จริง ๆ แล้วมันสามารถคาดเดาได้จากสถานที่นี้ที่ RestTemplate สามารถสร้างคำขอที่สอดคล้องกันเพื่อให้ได้การปรับสมดุลโหลดผ่าน interceptors ที่ฉีด
นอกจากนี้ยังสามารถเห็นได้ว่าคุณสามารถปรับแต่ง interceptor เพื่อให้บรรลุวัตถุประสงค์อื่น
4. การกำหนดค่า RibbonClientConfiguration สร้างอินสแตนซ์ ZoneAwareloadBalancer
รหัสตำแหน่ง:
Spring-Cloud-Netflix-core-1.3.5.Release.jar
org.springframework.cloud.netflix.ribbon
RibbonclientConfiguration.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); } // ละเว้น}ZoneAwareloadBalancer สืบทอดมาจากอินเตอร์เฟส iloadbalancer ซึ่งมีวิธีการ:
/*** เลือกเซิร์ฟเวอร์จาก Load Balancer * * @param คีย์วัตถุที่โหลดบาลานซ์อาจใช้เพื่อกำหนดเซิร์ฟเวอร์ที่จะส่งคืน NULL ถ้า * ตัวโหลดบาลานซ์ไม่ได้ใช้พารามิเตอร์นี้ * @return Server ที่เลือก */ Public Server CHOCOSESERVER (คีย์วัตถุ);
ZoneAwareloadBalancer เป็นคลาสการใช้งานโหลดบาลานซ์ที่เฉพาะเจาะจงและยังเป็นคลาสโหลดบาลานซ์เริ่มต้นด้วย อินสแตนซ์บริการบางอย่างถูกเลือกโดยการใช้วิธีตัวเลือก
สกัดกั้นและคำขอ
1. ใช้ RestTemplate เพื่อดำเนินการตามคำขอต่างๆเช่น GET และ POST ซึ่งทั้งหมดจะถูกนำไปใช้ผ่านวิธี DoExecute
รหัสตำแหน่ง:
Spring-web-4.3.12.release.jar
org.springframework.web.client
RestTemplate.class
Public Class Resttemplate ขยายการสกัดกั้น httpaccessor ใช้ restoperations {// ได้รับการป้องกันเล็กน้อย <t> t doexecute (Uri url, httpmethod วิธีการขอร้อง requestcallback, responseextractor <t> reperctextractor) assert.notnull (วิธีการ "'วิธี' จะต้องไม่เป็นโมฆะ"); clienthttpresponse การตอบสนอง = null; ลอง {clienthttpRequest Request = createRequest (URL, Method); if (requestCallback! = null) {requestCallback.DoWithRequest (คำขอ); } response = request.execute (); HandlerEsponse (URL, วิธีการตอบสนอง); if (responseextractor! = null) {return responsExtractor.extractData (การตอบกลับ); } else {return null; }} catch (iOexception ex) {string resource = url.toString (); string query = url.getRawQuery (); Resource = (Query! = NULL? Resource.SubString (0, Resource.indexof ('?'))): ทรัพยากร); โยน ResourceAccessException ใหม่ ("I/O ข้อผิดพลาดบน" + method.name () + "คำขอ/" " + ทรัพยากร +"/":" + ex.getMessage (), ex); } ในที่สุด {ถ้า (ตอบกลับ! = null) {response.close (); }}} // ละเว้น}วิธีการร้องขอ HTTP ที่ได้รับการสนับสนุนต่าง ๆ ในที่สุดเรียกใช้วิธี DoExecute ซึ่งเรียกใช้วิธีการสร้างเพื่อสร้างอินสแตนซ์คำขอและดำเนินการคำขอเพื่อรับวัตถุการตอบสนอง
2. สร้างอินสแตนซ์คำขอเพื่อสร้างโรงงาน
ในรหัสก่อนหน้าวิธีการ createRequest ถูกเรียกให้สร้างอินสแตนซ์คำขอซึ่งกำหนดไว้ในคลาสพาเรนต์
ครั้งแรกจัดระเบียบความสัมพันธ์การสืบทอดหลัก:
วิธีการ createRequest ถูกกำหนดไว้ในคลาสบทคัดย่อ HTTPACCESSOR
บทคัดย่อคลาสสาธารณะ HTTPACCESSOR {Private ClienthttpRequestFactory RequestFactory = ใหม่ SimpleClienthtttpRequestFactory (); โมฆะสาธารณะ setRequestFactory (clienthtttprequestFactory RequestFactory) {assert.notnull (RequestFactory, "clienthtttprequestFactory ต้องไม่เป็นโมฆะ"); this.requestFactory = requestFactory; } public clienthttprequestfactory getRequestFactory () {return this.requestFactory; } clienthttprequest createRequest (uri url, httpmethod วิธี) พ่น Ioexception {clienthttprequest Request = getRequestFactory (). createRequest (URL, วิธีการ); if (logger.isdebugenabled ()) {logger.debug ("สร้าง" + method.name () + "คำขอ /" " + url +" /""); } คำขอส่งคืน; -โทรหาวิธี getRequestFactory ในวิธี createRequest เพื่อรับอินสแตนซ์คำขอเพื่อสร้างโรงงาน ในความเป็นจริง GetRequestFactory ไม่ได้ถูกกำหนดไว้ในคลาส HTTPACCESSOR ปัจจุบัน แต่ถูกกำหนดไว้ใน subclass interceptinghttpaccessor
บทคัดย่อคลาสสาธารณะ Interceptinghttpaccessor ขยาย httpaccessor {รายการส่วนตัว <clienthttprequestinterceptor> interceptors = new ArrayList <clienthttprequestInterceptor> (); โมฆะสาธารณะ setInterceptors (รายการ <clienthttprequestInterceptor> interceptors) {this.interceptors = interceptors; } รายการสาธารณะ <clienthttprequestInterceptor> getInterceptors () {return interceptors; } @Override public clienthtttprequestfactory getRequestFactory () {clienthttprequestfactory Delegate = super.getRequestFactory (); if (! collectionutils.isempty (getInterceptors ())) {ส่งคืนใหม่ InterceptingClienthtttprequestFactory (Delegate, getInterceptors ()); } else {return Delegate; -ฉันทำสิ่งเล็ก ๆ น้อย ๆ ที่นี่ ก่อนอื่นฉันสร้างและได้รับโรงงาน SimpleClienthttpRequestFactory ผ่านคลาส Httpaccessor โรงงานนี้ส่วนใหญ่จะสร้างอินสแตนซ์การร้องขอพื้นฐานเมื่อไม่มีการสกัดกั้น
ประการที่สองเมื่อมีการฉีด Interceptor ให้สร้างโรงงาน InterceptingClientHtttpRequestFactory โรงงานนี้สร้างอินสแตนซ์คำขอด้วยตัวดักจับ เนื่องจากตัวดักจับโหลดบาลานซ์ถูกฉีดมันจึงถูกสร้างขึ้นจากโรงงาน InterceptingClienthtttprequestFactory
3. สร้างอินสแตนซ์คำขอผ่านโรงงาน
เมื่อสร้างอินสแตนซ์มันขึ้นอยู่กับวิธี createRequest ของโรงงาน
คลาสสาธารณะ InterceptingClienthtttprequestFactory ขยาย AbstractClientHttpRequestFactoryWrapper {รายการสุดท้ายส่วนตัว <clienthttprequestInterceptor> interceptors; Public InterceptingClienthttpRequestFactory (clienthtttprequestFactory RequestFactory, รายการ <clienthttprequestinterceptor> interceptors) {super (requestFactory); this.interceptors = (interceptors! = null? interceptors: collections. <clienthttprequestinterceptor> emptylist ()); } @Override Protected Clienthttprequest CreateRequest (Uri uri, httpmethod httpmethod, clienthttprequestfactory RequestFactory) {ส่งคืน InterceptingClienthttprequest -มันหมายถึงอินสแตนซ์ InterceptingClienthtttprequest ใหม่และฉีด Interceptor และการร้องขอพื้นฐานการสร้างโรงงานอินสแตนซ์
4. ขออินสแตนซ์เพื่อเรียกวิธีการสกัดกั้นของการสกัดกั้นการโหลดบาลานซ์ในขั้นตอนการกำหนดค่า
จะเห็นได้จากขั้นตอนที่ 1 ว่าหลังจากสร้างอินสแตนซ์คำขอคำขอจะดำเนินการโดยดำเนินการวิธีการดำเนินการของอินสแตนซ์คำขอ
clienthttpRequest request = createRequest (url, method); ถ้า (requestcallback! = null) {requestcallback.dowithRequest (คำขอ);} response = request.execute ();อินสแตนซ์การร้องขอจริงคือ InterceptingClienthttprequest และดำเนินการอยู่ในคลาสหลัก
ตำแหน่งนิยามคลาส:
Spring-web-4.3.12.release.jar
org.springframework.http.client
InterceptingClientHttpRequest.class
ดูความสัมพันธ์ที่สืบทอดมาของพวกเขา
วิธีการ ExecuteInternal ที่ใช้โดยคลาสย่อยจะเรียกจริงในวิธีการดำเนินการ
บทคัดย่อระดับสาธารณะ AbstractClientHttpRequest ดำเนินการ clienthttpRequest {ส่วนหัว httpheaders สุดท้ายส่วนตัว = httpheaders ใหม่ (); บูลีนส่วนตัวดำเนินการ = false; @Override สาธารณะ httpheaders getheaders () {return (this.executed? httpheaders.readonlyhttpheaders (this.headers): this.headers); } @Override Public Final OutputStream getBody () พ่น IOException {assertNotExecuted (); กลับ getbodyinternal (this.headers); } @Override Public Clienthttpresponse Execute () พ่น IOException {assertNotExecuted (); clienthttpresponse result = executeInternal (this.headers); this.executed = true; ผลการกลับมา; } void void assertNotExecuted () {assert.state (! this.executed, "clienthttprequest ดำเนินการแล้ว"); } การป้องกันบทคัดย่อ outputstream getBodyInternal (ส่วนหัว httpheaders) พ่น IOException; ได้รับการป้องกันบทคัดย่อไคลเอนต์ httpresponse executeInternal (ส่วนหัว httpheaders) พ่น IOException;}ในความเป็นจริงมันเป็นวิธีการ executeInternal ของคลาส InterceptingClientHttpRequest ซึ่งการดำเนินการของผู้ดำเนินการ InterceptingRequestExecution เรียกว่า ผ่านระดับและตรวจสอบว่าหากมีการฉีดสารสกัดกั้นวิธีการสกัดกั้นของ interceptor จะเรียกว่า
ตัวดักจับที่นี่เป็นจริงอินสแตนซ์ Load -Balancing Interceptor LoadBalancerInterceptor ที่ถูกฉีดเข้าไปในอินสแตนซ์ RestTemplate ระหว่างขั้นตอนการกำหนดค่า คุณสามารถอ้างถึงขั้นตอนที่ 2 ของขั้นตอนการกำหนดค่าด้านบน
Class InterceptingClienthttprequest ขยาย AbstractBufferingClientHttpRequest {// omit @Override ป้องกัน clienthttpresponse ขั้นสุดท้าย executeInternal (httpheaders ส่วนหัว, byte [] bufferedput) โยน ioexception return requestExecution.execute (นี่, bufferedOutput); } คลาสส่วนตัว interceptingRequestExecution ใช้ clienthtttprequestExecution {ตัววนซ้ำสุดท้าย <clienthttprequestinterceptor> iterator; Public InterceptingRequestExecution () {this.iterator = interceptors.iterator (); } @Override public clienthttpresponse ดำเนินการ (คำขอ httprequest, byte [] body) พ่น ioexception {ถ้า (this.iterator.hasnext ()) {clienthtttprequestinterceptor nextinterceptor = this.iterator.next (); ส่งคืน nextinterceptor.intercept (คำขอ, ร่างกาย, สิ่งนี้); } else {clienthttprequest Delegate = requestFactory.createRequest (request.geturi (), request.getMethod ()); สำหรับ (map.entry <string, รายการ <String>> รายการ: request.getheaders (). entrySet ()) {list <String> values = entry.getValue (); สำหรับ (ค่าสตริง: ค่า) {delegate.getheaders (). เพิ่ม (entry.getKey (), ค่า); }} if (body.length> 0) {streamutils.copy (body, delegate.getbody ()); } return delegate.execute (); -5. ตัวดักจับโหลดโหลดเรียกว่าไคลเอนต์โหลดบาลานซ์
ในวิธีการสกัดกั้นของคลาส LoadBalancerInterceptor คลาส Load Balancing Interceptor คลาสวิธีการดำเนินการของคลาสการใช้งาน LoadBalancerClient Loadbalanclient
LoadBalancerInterceptor คลาสสาธารณะใช้ clienthtttprequestInterceptor {private loadbalancerclient loadbalancer; LoadBalancerRequestFactory Private Public LoadBalancerInterceptor (loadbalancerclient loadbalancer, loadbalancerRequestFactory RequestFactory) {this.loadbalancer = loadbalancer; this.requestFactory = requestFactory; } public loadbalancerInterceptor (loadbalancerclient loadbalancer) {// สำหรับความเข้ากันได้ย้อนหลังนี้ (loadbalancer, loadbalancerrequestfactory ใหม่ (loadbalancer)); } @Override public clienthttpresponse intercept (คำขอ httprequest สุดท้าย, byte สุดท้าย [] Body, clienthtttprequestexecution การดำเนินการ) โยน ioexception {ขั้นสุดท้าย uri Originaluri = request.geturi (); ServiceName String = Originaluri.getHost (); assert.state (serviceName! = null, "คำขอ URI ไม่มีชื่อโฮสต์ที่ถูกต้อง:" + Originaluri); ส่งคืนสิ่งนี้ loadbalancer.execute (serviceName, requestFactory.createRequest (คำขอ, ร่างกาย, การดำเนินการ)); -ในขั้นตอนที่ 1 ของขั้นตอนการกำหนดค่าคุณจะเห็นว่าคลาสการใช้งานคือ Ribbonloadbalancerclient
6. ไคลเอ็นต์โหลดบาลานซ์เรียกใช้นโยบายการโหลดบาลานซ์เพื่อเลือกอินสแตนซ์บริการเป้าหมายและเริ่มคำขอ
ในวิธีการดำเนินการครั้งแรกและวิธีการ GetServer ของ Ribbonloadbalancerclient เราจะเห็นได้ว่าในความเป็นจริงวิธีการเลือกของคลาสการใช้งาน IloadBalancer นั้นถูกเลือกและส่งมอบให้กับวัตถุคำขอถัดไปเพื่อเริ่มคำขอ
คลาสการใช้งาน Load Balancing ที่นี่คืออินสแตนซ์ Load Balancer ที่รับรู้ของ ZoneAwareloadBalancer โดยค่าเริ่มต้นและเลือกบริการภายในผ่านนโยบายการปรับสมดุล
การสร้าง ZoneAwareloadBalancer สามารถพบได้ในขั้นตอนที่ 4 ของขั้นตอนการกำหนดค่า
คลาสสาธารณะ Ribbonloadbalancerclient ใช้ loadbalancerclient {@Override สาธารณะ <t> t ดำเนินการ (String ServiceId, loadBalancerRequest <t> คำขอ) พ่น IOException เซิร์ฟเวอร์เซิร์ฟเวอร์ = getServer (loadbalancer); if (server == null) {โยน ungelmalStateException ใหม่ ("ไม่มีอินสแตนซ์สำหรับ" + serviceId); } RibBonserver RibBonserver = ใหม่ RibBonserver (ServiceId, Server, ISSECURE (เซิร์ฟเวอร์, ServiceID), ServerIntrospector (ServiceId) .getMetAdata (เซิร์ฟเวอร์)); return execute (serviceId, Ribbonserver, คำขอ); } @Override สาธารณะ <t> t ดำเนินการ (String ServiceId, ServiceInstance ServiceInstance, LoadBalancerRequest <T> คำขอ) พ่น IOException {เซิร์ฟเวอร์เซิร์ฟเวอร์ = null; if (ServiceInstance instanceof ribbonserver) {server = ((Ribbonserver) ServiceInstance) .getServer (); } if (server == null) {โยนใหม่ที่ผิดกฎหมาย StateException ("ไม่มีอินสแตนซ์สำหรับ" + serviceId); } ribbonloadbalancercontext context = this.clientfactory .getLoadBalanconText (ServiceId); ribbonstatsRecorder statsRecorder = ใหม่ ribbonstatsRecorder (บริบท, เซิร์ฟเวอร์); ลอง {t returnVal = request.apply (ServiceInstance); StatsRecorder.recordstats (returnVal); returnval; } // จับ ioexception และ rethrow ดังนั้น resttemplate ทำงานได้อย่างถูกต้องจับได้อย่างถูกต้อง (ioexception ex) {statsrecorder.recordstats (ex); โยนอดีต; } catch (Exception Ex) {statsRecorder.RecordStats (ex); ReflectionUtils.rethrowruntimeException (Ex); } return null; } // เซิร์ฟเวอร์ที่ได้รับการป้องกันเล็กน้อย getServer (iloadbalancer loadbalancer) {ถ้า (loadbalancer == null) {return null; } return loadbalancer.chooseserver ("ค่าเริ่มต้น"); // todo: การจัดการคีย์ที่ดีขึ้น} ป้องกัน iloadbalancer getloadbalancer (String serviceId) {return this.clientFactory.getLoadBalancer (ServiceId); } Public Static Class Ribbonserver ใช้ ServiceInstance {String ServiceId ขั้นสุดท้ายส่วนตัว; เซิร์ฟเวอร์เซิร์ฟเวอร์สุดท้ายส่วนตัว บูลีนสุดท้ายส่วนตัวปลอดภัย; แผนที่ส่วนตัว <สตริงสตริง> ข้อมูลเมตา; Ribbonserver สาธารณะ (String ServiceId, เซิร์ฟเวอร์เซิร์ฟเวอร์) {this (serviceId, เซิร์ฟเวอร์, เท็จ, การรวบรวม <สตริง, สตริง> emgymap ()); } Public Ribbonserver (String ServiceId, เซิร์ฟเวอร์เซิร์ฟเวอร์, บูลีนปลอดภัย, แผนที่ <สตริง, สตริง> ข้อมูลเมตา) {this.serviceId = serviceId; this.server = เซิร์ฟเวอร์; this.secure = ปลอดภัย; this.metadata = ข้อมูลเมตา; } // ละเว้น}}หลังจากจบรหัสให้สรุป
เมื่อใช้ RestTemplate เพื่อขอบริการอื่น ๆ อินสแตนซ์คำขอ HTTP ปกติจะถูกใช้ภายในเพื่อส่งคำขอ
หลังจากเพิ่มคำอธิบายประกอบ @LoanBalanced ลงใน RestTemplate จริง ๆ แล้วผ่านการกำหนดค่าตัวดักจับโหลดบาลานซ์จะถูกฉีดลงใน RestTemplate ทำให้โหลดบาลานซ์สามารถเลือกบริการที่เหมาะสมตามนโยบายที่เกี่ยวข้องก่อนส่งคำขอ
ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการเรียนรู้ของทุกคนและฉันหวังว่าทุกคนจะสนับสนุน wulin.com มากขึ้น