В архитектуре микросервиса мы разделили проект на многие независимые модули, которые работают вместе с помощью удаленных вызовов. Тем не менее, в случае высокой параллели, увеличение количества связи приведет к увеличению общего времени общения. В то же время ресурсы пула потоков также ограничены. Среда высокой параллелистики приведет к тому, что большое количество потоков находится в состоянии ожидания, что приведет к задержкам ответов. Чтобы решить эти проблемы, мы должны понять слияние запроса Hystrix.
Запрос слияния в Hystrix - это использование процессора слияния для объединения последовательных запросов, инициированных одним и тем же службой в один запрос на обработку (временное окно для этих непрерывных запросов по умолчанию составляет 10 мс). Одним из основных классов, участвующих в этом процессе, является Hystrixcollapser, OK. Затем давайте посмотрим, как реализовать слияние запроса Hystrix.
Интерфейс поставщика услуг
Мне нужно предоставить два интерфейса в поставщике услуг для потребителей услуг, чтобы позвонить следующему:
@Requestmapping ("/getBook6") публичный список <book> book6 (String Ids) { System.out.println("ids>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 33, "Hu Shi", "нет"); Литература издательство 2 "); возвращается книга;}Первый интерфейс - это пакетный интерфейс, а второй интерфейс - это интерфейс, который обрабатывает один запрос. В пакетном интерфейсе формат параметров IDS, отправленный потребителем службы, составляет 1, 2, 3, 4 ... этот формат. При нормальных обстоятельствах нам нужно запросить соответствующие данные на основе идентификаторов, а затем собрать их в набор для возврата. Для легкой обработки я верну тот же набор данных, независимо от того, какой запрос; Интерфейс для обработки одного запроса относительно прост, поэтому я не буду повторять его.
Обслуживание потребителей
Хорошо, после того, как поставщик услуг справился с этим, давайте посмотрим, как потребители услуги должны справиться с этим.
Bookservice
Во -первых, добавьте два метода в Bookservice, чтобы вызвать интерфейс, предоставленный поставщиком услуг, следующим образом:
Public Book Test8 (Long Id) {return resttemplate.getForObject ("http: // hello-service/getbook6/{1}", book.class, id);} public list <book> test9 (list> ids) {System.out.println ("test9 -------------"+Ids+". Thread.currentThread (). GetName ()); Book [] books = resttemplate.getForObject ("http: // hello-service/getBook6? Ids = {1}", book []. Class, stringUtils.join (ids, ",")); return arrays.aslist (books);}Test8 используется для вызова интерфейса, который обеспечивает один идентификатор, Test9 используется для вызова интерфейса, которая обработка партии. В Test9 я распечатаю поток, где выполняется Test9, чтобы облегчить нам наблюдение за результатами выполнения. Кроме того, в Resttemplate, если возвратная стоимость является коллекцией, мы должны получить ее сначала с массивом, а затем преобразовать в коллекцию (возможно, есть другие методы, у друзей есть лучшие предложения, которые нужно сделать).
BookBatchCommand
Хорошо, после того, как метод в Bookservice готов, мы можем создать BookBatchCommand, которая является командой партии, следующим образом:
Public Class BookBatchCommand расширяет HystrixCommand <List <Book >> {Private List <Long> IDS; Частный книжный сервис Bookservice; public bookbatchcommand (список <long> ids, bookservice bookservice) {super (setter.withgroupkey (hystrixcommandgroupkey.factory.askey ("collapsinggroup"))). и Коммандки (hystrixcommandkey.factory.achkey ("collapskekey"))); this.ids = ids; this.bookservice = bookservice; } @Override Protected List <book> run () бросает исключение {return bookservice.test9 (ids); }}Этот класс на самом деле похож на класс, который мы представили в предыдущем блоге. Они оба унаследованы от HystrixCommand и используются для обработки объединенных запросов и вызовы метода Test9 в Bookservice в методе прогона.
BookCollApseCommand
Затем нам нужно создать BookCollApseCommand, унаследованную от HystrixCollApser для реализации Merge запроса. следующее:
Public Class BookCollApseCommand расширяет HystrixCollapseer <List <book>, книга, Long> {Private Bookservice Bookservice; частный длинный идентификатор; Public BookCollApseCommand (Bookservice Bookservice, Long Id) {Super (setter.withcollapserkey (hystrixcollapserkey.factory.askey ("bookCollApseCommand")). andCollApserPropertiesDefaults (hystrixcollapserPerties.setterSemonDseCOLLAPSERPerties.SetterSemonDseCOLLAPSERPERTIES. this.bookservice = bookservice; this.id = id; } @Override public long getRequestargument () {return id; } @Override защищен HystrixCommand <list <book >> createCommand (Collection <collapsedRequest <book, long >> collapsedRequests) {list <long> ids = new ArrayList <> (collapsedRequests.size ()); ids.addall (collapsedrequests.stream (). map (collapsedrequest :: getargument) .collect (collectors.tolist ())); BookBatchCommand BookBatchCommand = new BookBatchCommand (ids, bookervice); вернуть BookBatchCommand; } @Override Protected void mapResponsetOrequests (list <book> batchresponse, collection <collapsedRequest <book, long >> collapsedRequests) {system.out.println ("mapResponsetorequests"); int count = 0; для (collapsedRequest <book, long> collapsedRequest: collapsedRequests) {book book = batchresponse.get (count ++); collapsedRequest.setResponse (книга); }}}Что касается этого класса, я скажу следующие моменты:
1. Прежде всего, в методе строительства мы установили окно запроса на 100 мс, то есть запросы с интервалом времени запроса в течение 100 мс будут объединены в один запрос.
2. Метод CreateCommand используется в основном для объединения запросов, получения идентификаторов каждого отдельного запроса здесь, помещайте эти отдельные идентификаторы в коллекцию, а затем создайте объект BookBatchCommand и используйте этот объект, чтобы инициировать пакетный запрос.
3. Метод MapReSponsetORequests в основном используется для установки результата запроса для каждого запроса. Первый параметр этого метода представляет собой результат запроса на пакетный, а второй параметр CollapsedRequests представляет каждый объединенный запрос. Затем мы установили результат запроса для CollapsedRequests, пройдя BatchResponse.
Хорошо, после того, как все эти операции завершены, мы можем прийти и проверить его.
тест
Мы создаем интерфейс доступа на стороне потребителя Service, чтобы проверить запрос на слияние. Тестовый интерфейс заключается в следующем:
@Requestmapping ("/test7")@responsebodypublic void test7 () throws executionException, прерывание Exception {hystrixRequestContext context = hystrixRequestContext.initializeContext (); BookCollApseCommand BC1 = новый BookCollApseCommand (Bookervice, 1L); BookCollApseCommand BC2 = новый BookCollApseCommand (Bookservice, 2L); BookCollApseCommand BC3 = новый BookCollApseCommand (Bookservice, 3L); BookCollApseCommand BC4 = новый BookCollApseCommand (Bookervice, 4L); Будущее <book> Q1 = bc1.queue (); Future <book> Q2 = bc2.queue (); Future <book> Q3 = bc3.queue (); Book Book1 = Q1.get (); Book Book2 = Q2.get (); Book Book3 = Q3.get (); Thread.sleep (3000); Future <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 секунды, а затем инициируйте запрос. Таким образом, первые 3 запроса будут объединены в один запрос. Четвертый запрос не будет объединен, потому что интервал между ними относительно длинный, но создаст поток для его обработки отдельно.
Хорошо, давайте посмотрим на результаты исполнения следующим образом:
Запрос Merge реализуется посредством аннотации
ОК, приведенный выше метод слияния запроса немного трудно писать, мы можем использовать аннотации для более элегантной реализации этой функции. Сначала добавьте два метода в Bookservice следующим образом:
@HystrixCollApser (batchmethod = "test11", collapserProperties = {@hystrixproperty (name = "timerdelayinmilliseconds", value = "100")}) Public Future <book> test10 (long id) {return null;}@hystrixcommandpuplic <book> test11 (long> null;}@hystrixcommandpublic <book> test11 (long> test11 (long>} System.out.println ("test9 ----------"+ids+"thread.currentThread (). GetName ():"+thread.currentThread (). GetName ()); Book [] books = resttemplate.getForObject ("http: // hello-service/getBook6? Ids = {1}", book []. Class, stringUtils.join (ids, ",")); return arrays.aslist (books);}Добавьте аннотацию @HystrixCollApser, чтобы реализовать слияние запроса в методе TEST10, используйте атрибут BatchMethod, чтобы указать метод обработки после слияния запроса и атрибут collapserProperties для указания других атрибутов.
Хорошо, после написания в Bookservice, просто называйте это напрямую, следующим образом:
@Requestmapping ("/test8")@responsebodypublic void test8 () throws executionException, прерывание {hystrixRequestContext context = hystrixRequestContext.ItializeContext (); Будущее <book> f1 = bookservice.test10 (1L); Будущее <book> f2 = bookservice.test10 (2L); Будущее <book> f3 = bookservice.test10 (3L); Книга B1 = f1.get (); Книга B2 = f2.get (); Книга B3 = f3.get (); Thread.sleep (3000); Будущее <book> f4 = bookservice.test10 (4L); Книга 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 больше.