في بنية الخدمات المجهرية ، نقسم مشروعًا إلى العديد من الوحدات المستقلة ، التي تعمل معًا من خلال المكالمات البعيدة. ومع ذلك ، في حالة التزامن العالي ، ستؤدي الزيادة في عدد الاتصالات إلى زيادة في إجمالي وقت الاتصال. في الوقت نفسه ، تكون موارد تجمع الخيوط محدودة أيضًا. سوف تتسبب بيئة التزامن العالية في أن تكون هناك عدد كبير من الخيوط في حالة انتظار ، مما سيؤدي إلى تأخير الاستجابة. من أجل حل هذه المشكلات ، نحتاج إلى فهم دمج طلب Hystrix.
طلب الدمج في Hystrix هو استخدام معالج دمج لدمج الطلبات المتتالية التي يتم بدءها من قبل نفس الخدمة في طلب واحد للمعالجة (النافذة الزمنية لهذه الطلبات المستمرة هي 10 مللي ثانية افتراضيًا). واحدة من الفئات الأساسية المشاركة في هذه العملية هي HystrixCollapser ، حسنًا. بعد ذلك ، دعونا نلقي نظرة على كيفية تنفيذ دمج طلب Hystrix.
واجهة مزود الخدمة
أحتاج إلى توفير واجهتين في مزود الخدمة لمستهلكي الخدمة للاتصال ، على النحو التالي:
requestmapping ("/getBook6") القائمة العامة <book> Book6 (string ids) { system.out.println ("ids >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 33 ، "Hu Shi" ، "None")) ؛ دار النشر 2 ") ؛ كتاب العودة ؛}الواجهة الأولى هي واجهة دفعة والواجهة الثانية هي واجهة تعالج طلبًا واحدًا. في واجهة الدُفعات ، يكون تنسيق معلمة IDS المرسلة من قبل مستهلك الخدمة 1 ، 2 ، 3 ، 4 ... هذا التنسيق. في ظل الظروف العادية ، نحتاج إلى الاستعلام عن البيانات المقابلة بناءً على المعرفات ، ثم تجميعها في مجموعة للعودة. من أجل المعالجة السهلة ، سأعيد نفس مجموعة البيانات بغض النظر عن نوع الطلب ؛ واجهة معالجة طلب واحد بسيط نسبيًا ، لذلك لن أكرره.
خدمة المستهلكين
حسنًا ، بعد أن تعامل مزود الخدمة ، دعونا نلقي نظرة على كيفية التعامل مع مستهلكي الخدمة.
Bookservice
أولاً ، أضف طريقتين إلى Bookservice لاستدعاء الواجهة المقدمة من مزود الخدمة ، على النحو التالي:
اختبار الكتاب العام (معرف طويل) {resttemplate.getForObject ("http: // hello-service/getBook6/{1}" ، book.class ، id) ؛} القائمة العامة <book> test9 (list> ids) {system.out.println ("test9 ------------- thread.currentThRead (). getName ()) ؛ book [] books = restTemplate.getForObject ("http: // hello-service/getBook6؟ ids = {1}" ، book []. class ، stringutils.join (ids ، "،")) ؛ عودة صفائف. aslist (كتب) ؛}يتم استخدام Test8 لاستدعاء الواجهة التي توفر معرفًا واحدًا ، يتم استخدام Test9 لاستدعاء الواجهة التي يتم معالجة الدُفعات. في Test9 ، أقوم بطباعة الخيط حيث يتم تنفيذ Test9 لتسهيلنا لمراقبة نتائج التنفيذ. بالإضافة إلى ذلك ، في RestTemplate ، إذا كانت قيمة الإرجاع عبارة عن مجموعة ، فيجب علينا أن نستقبلها أولاً مع صفيف ، ثم تحويلها إلى مجموعة (ربما هناك طرق أخرى ، يتمتع الأصدقاء باقتراحات أفضل).
BookBatchCommand
حسنًا ، بعد أن تكون الطريقة في Bookservice جاهزة ، يمكننا إنشاء bookbatchCommand ، وهو أمر دفعة ، على النحو التالي:
فئة Public BookBatchCommand يمتد HystrixCommand <List <book >> {قائمة خاصة <Ngt> IDS ؛ Bookservice Bookservice ؛ Public BookBatchCommand (قائمة <Ngt> IDS ، BookService Bookservice) {Super (setter.withgroupkey (HystrixCommandGroupKey.factory.askey ("cloplapsinggroup")))). this.ids = ids ؛ this.bookservice = bookservice ؛ } Override List المحمي <Book> Run () يلقي الاستثناء {return bookservice.test9 (ids) ؛ }}يشبه هذا الفصل في الواقع الفصل الذي قدمناه في المدونة السابقة. كلاهما ورثتهما من HystrixCommand ويستخدمون للتعامل مع الطلبات المدمجة والاتصال بالطريقة Test9 في Bookservice في طريقة التشغيل.
BookCollapseCommand
بعد ذلك ، نحتاج إلى إنشاء BookCollapSecommand الموروث من HystrixCollapser لتنفيذ دمج الطلب. على النحو التالي:
الطبقة العامة bookCollapsEcmand يمتد HystrixCollapseer <list <book> ، كتاب ، long> {private bookservice bookservice ؛ معرف طويل خاص ؛ Public BookCollapseCommand (Bookservice Bookservice ، Long Id) {Super (setter.withCollapserKey (HystrixCollapserKey.factory.askey ("bookcollapseCommand")). this.bookservice = bookservice ؛ this.id = id ؛ } Override public long getRequestArgument () {return id ؛ } Override HystrixCommand المحمي <list <book >> createCommand (مجموعة <cloplapsedRequest <book ، long >> cloplapsedRequests) {list <long> ids = new ArrayList <> (cloplapsedRequests.size ()) ؛ ids.addall (clollapsedRequests.stream (). الخريطة (cloopsedrequest :: getArgument) .collect (collectors.tolist ())) ؛ BookBatchCommand BookBatchCommand = New BookBatchCommand (Ids ، Bookservice) ؛ إرجاع BookBatchCommand ؛ } Override void mapresponsetoRequests (قائمة <book> batchresponse ، المجموعة <cloplapsedRequest <book ، long >> collapsedRequests) {system.out.println ("MapResponsetOrequests") ؛ عدد int = 0 ؛ لـ (cloplapsedRequest <book ، long> clollapsedRequest: clollapsedRequests) {book book = batchresponse.get (count ++) ؛ clollapsedRequest.setResponse (كتاب) ؛ }}}بخصوص هذا الفصل ، سأقول النقاط التالية:
1. أولاً وقبل كل شيء ، في طريقة البناء ، قمنا بتعيين نافذة وقت الطلب على 100 مللي ثانية ، أي أن الطلبات مع فاصل زمني للطلب خلال 100 مللي ثانية سيتم دمجها في طلب واحد.
2. يتم استخدام طريقة CreateCommand بشكل أساسي لدمج الطلبات ، والحصول على معرفات كل طلب واحد هنا ، ووضع هذه المعرفات الفردية في مجموعة ، ثم إنشاء كائن BookBatchCommand ، واستخدم هذا الكائن لبدء طلب الدُفعات.
3. يتم استخدام طريقة MapResPonsetOrequests بشكل أساسي لتعيين نتيجة الطلب لكل طلب. تمثل المعلمة الأولى من هذه الطريقة نتيجة طلب الدُفعات ، وتمثل المعلمة الثانية CllapsedRequests كل طلب مدمج. ثم قمنا بتعيين نتيجة الطلب لـ CllapsedRequests عن طريق اجتياز BatchResponse.
حسنًا ، بعد اكتمال كل هذه العمليات ، يمكننا أن نأتي واختبارها.
امتحان
نقوم بإنشاء واجهة وصول على جانب مستهلك الخدمة لاختبار طلب الدمج. واجهة الاختبار كما يلي:
requestmapping ("/test7")@reponsebodypublic void test7 () يلقي ExecutionException ، interruptedException {hystrixRequestContext context = hystrixRequestContext.initializeContext () ؛ BookCollapSecommand BC1 = New BookCollapSecommand (Bookservice ، 1L) ؛ BookCollapSecommand BC2 = New BookCollapSecommand (Bookservice ، 2L) ؛ BookCollapseCommand BC3 = New BookCollapSecommand (Bookservice ، 3L) ؛ BookCollapseCommand BC4 = New BookCollapSecommand (Bookservice ، 4L) ؛ المستقبل <book> Q1 = bc1.queue () ؛ المستقبل <book> Q2 = bc2.queue () ؛ المستقبل <book> Q3 = bc3.queue () ؛ Book Book1 = Q1.get () ؛ Book Book2 = Q2.get () ؛ Book Book3 = Q3.get () ؛ thread.sleep (3000) ؛ المستقبل <book> Q4 = bc4.queue () ؛ Book Book4 = Q4.get () ؛ System.out.println ("Book1 >>>"+book1) ؛ System.out.println ("Book2 >>>"+book2) ؛ System.out.println ("Book3 >>>"+book3) ؛ System.out.println ("Book4 >>>"+book4) ؛ context.close () ؛}بخصوص واجهة الاختبار هذه ، قلت النقطتين التاليتين:
1. أولاً ، تحتاج إلى تهيئة HystrixRequestContext
2. قم بإنشاء مثيل لفئة BookCollapSecommand لبدء طلب ، وإرسال 3 طلبات أولاً ، ثم النوم لمدة 3 ثوان ، ثم بدء طلب. وبهذه الطريقة ، سيتم دمج الطلبات الثلاثة الأولى في طلب واحد. لن يتم دمج الطلب الرابع لأن الفاصل الزمني بينهما طويل نسبيًا ، ولكنه سيقوم بإنشاء مؤشر ترابط لمعالجته بشكل منفصل.
حسنًا ، دعنا نلقي نظرة على نتائج التنفيذ ، على النحو التالي:
يتم تنفيذ دمج الطلب من خلال التعليق التوضيحي
حسنًا ، تعد طريقة دمج الطلب أعلاه مزعجة بعض الشيء ، يمكننا استخدام التعليقات التوضيحية لتنفيذ هذه الوظيفة بشكل أكثر أناقة. أولاً ، أضف طريقتين في Bookservice ، على النحو التالي:
hystrixCollapser (BatchMethod = "Test11" ، cloperProperties = {hystrixProperty (name = "TimerDelayInMillisEconds" ، value = "100")}) المستقبل العام <book> test10 (معرف طويل) {return null ؛ System.out.println ("Test9 ----------"+ids+"thread.currentThRead (). getName ():"+thread.currentThRead (). book [] books = restTemplate.getForObject ("http: // hello-service/getBook6؟ ids = {1}" ، book []. class ، stringutils.join (ids ، "،")) ؛ عودة صفائف. aslist (كتب) ؛}أضف @HystRixCollapser Eanotation لتنفيذ دمج الطلب على طريقة Test10 ، واستخدم سمة BatchMethod للإشارة إلى طريقة المعالجة بعد دمج الطلب ، وسمة ClarpserProperties لتحديد السمات الأخرى.
حسنًا ، بعد كتابتها في Bookservice ، فقط اتصل بها مباشرة ، على النحو التالي:
requestmapping ("/test8")@reponsebodypublic void test8 () يلقي ExecutionException ، interruptedException {hystrixRequestContext context = hystrixRequestContext.initializeContext () ؛ المستقبل <book> f1 = bookservice.test10 (1L) ؛ المستقبل <book> f2 = bookservice.test10 (2L) ؛ المستقبل <book> f3 = bookservice.test10 (3L) ؛ كتاب B1 = f1.get () ؛ Book B2 = f2.get () ؛ كتاب b3 = f3.get () ؛ thread.sleep (3000) ؛ المستقبل <book> f4 = bookservice.test10 (4L) ؛ Book B4 = f4.get () ؛ System.out.println ("B1 >>>"+B1) ؛ System.out.println ("B2 >>>"+B2) ؛ System.out.println ("B3 >>>"+B3) ؛ System.out.println ("B4 >>>"+B4) ؛ context.close () ؛}مثل السلطة السابقة ، سيتم دمج الطلبات الثلاثة الأولى ، وسيتم تنفيذ الطلب الرابع بشكل منفصل. حسنًا ، ونتيجة التنفيذ هي كما يلي:
لخص
مزايا اندماج الطلب ، رأى الأصدقاء أنه يتم دمج طلبات متعددة في طلب لمعالجة لمرة واحدة ، والتي يمكن أن توفر بشكل فعال موارد النطاق الترددي للشبكة وتجمع مؤشرات الترابط. ومع ذلك ، هناك مزايا وعيوب. بعد إعداد دمج الطلب ، قد يكون هناك طلب في 5 مللي ثانية ، ولكن عليك الآن انتظار 10 مللي ثانية أخرى لمعرفة ما إذا كانت هناك أي طلبات أخرى معًا. وبهذه الطريقة ، سيتم زيادة استهلاك الوقت للطلب من 5 مللي ثانية إلى 15 مللي ثانية. ومع ذلك ، إذا كان الأمر الذي سنبدأه هو أمر عالي التأخير ، فيمكنك استخدام دمج الطلب في هذا الوقت ، لأن استهلاك الوقت في نافذة الوقت غير مهم في هذا الوقت. بالإضافة إلى ذلك ، يعد التزامن العالي أيضًا سيناريو مهم للغاية لعمليات الدمج.
حسنًا ، هذا كل شيء لطلب الاندماج. إذا كان لديك أي أسئلة ، فيرجى ترك رسالة ومناقشة. آمل أن يكون ذلك مفيدًا لتعلم الجميع ، وآمل أن يدعم الجميع wulin.com أكثر.