Перед HystrixCommand вы можете использовать слияние запроса ( HystrixCollapser - это абстрактный родительский класс) для объединения нескольких запросов в один, а затем инициировать вызовы в систему зависимостей бэкэнд.
На рисунке ниже показано количество потоков и количество сетевых подключений в двух случаях: первое - не использовать слияние, а второе - использовать слияние запроса (при условии, что все ссылки параллельны в короткое время, например, в течение 10 мс).
Зачем использовать запрос слияния?
Merge Merge используется для уменьшения количества потоков и сетевых подключений, необходимых для выполнения одновременных выполнений HystrixCommand . Запросные слияния выполняются автоматически и не заставляют разработчиков вручную координировать пакетные запросы.
Глобальный контекст - глобальный контекст (охватывает все потоки Tomcat)
Этот тип слияния выполняется на глобальном уровне приложения, поэтому запрос любого пользователя в любом потоке Tomcat может быть объединен вместе.
Например, если вы настраиваете HystrixCommand для поддержки любых зависимостей для запросов пользователя для получения рейтингов фильмов, когда любой пользовательский поток в том же JVM делает такой запрос, Hystrix добавляет свой запрос вместе с любым другим запросом к тому же обрушенному сетевому вызову.
Контекст запроса пользователя - контекст запроса (отдельный поток Tomcat)
Если вы настраиваете HystrixCommand для обработки пакетных запросов только для одного пользователя, Hystrix может объединять запросы в потоке Tomcat (запрос).
Например, если пользователь хочет загрузить закладку из 300 видеообъектов, вместо того, чтобы выполнять 300 сетевых запросов, Hystrix может объединить их в один.
Hystrix является запросом по умолчанию. Чтобы использовать функцию с запросом (кэширование запроса, коллапс запроса, журнал запроса), вы должны управлять жизненным циклом HystrixRequestContext (или реализовать альтернативный HystrixConcurrencyStrategy )
Это означает, что вам нужно выполнить следующий код перед выполнением запроса:
Копия кода следующим образом: hystrixrequestcontext context = hystrixrequestcontext.initializecontext ();
И выполнить в конце запроса:
context.shutdown ();
В стандартных приложениях Javaweb вы также можете использовать сервочный фильтр для инициализации этого жизненного цикла
Общедоступный класс hystrixrequestcontextservletfilter реализует фильтр {public void dofilter (запрос ServletRequest, ответ Servletresponse, FilterChain) Throws IoException, ServletException {hystrixRequestContext context = hystrixRequestContext.InitializeContext (); try {chain.dofilter (запрос, ответ); } наконец {context.shutdown (); }}}Затем настройте его в web.xml
<Filter> <Slame-name> hystrixRequestContextServletfilter </display-name> <filter-name> hystrixrequestcontextservletfilter </filter-name> <filter-class> com.netflix.hystrix.contrib.requestservlet.hystrixtrextxtservelter.contrib.requestservlet.hystrixerxtxtserxerservelter.contrib.RequestServlet.HyStrixERVEXTSerfiltfilTfiltfilTfiltfilfilter.com <Filter-Mapping> <Filter-name> HystrixRequestContextServletfilter </filter-name> <url-pattern>/*</url-pattern> </filter-картирование>
Если вы разрабатываете Springboot, код выглядит следующим образом:
@Webfilter (filtername = "hystrixrequestcontextservletfilter", urlpatterns = "/*") public class hystrixrequestcontextservletfilter inements {@override public void init (filterConfigConfig) Throwes uertexception voidRide ofilter ofilter ofilter ovletter ovletter ovletter ServletRequest, ServletResponse Servletresponse, FilterChain FilterChain), Throws IoException, ServletException {hystrixRequestContext context = hystrixRequestContext.initializeContext (); try {filterchain.dofilter (ServletRequest, Servletresponse); } наконец {context.shutdown (); }} @Override public void destress () {}} @SpringBootApplication@EnabledIscoveryClient@EnableFeignClients@enableHystrix // Это требуется, в противном случае фильтр недействителен @servletcomponentscanpublic Class Application {public static void main (string [] args) {new SpringapplicationBuilder (Application.class). }}Какова стоимость запроса слияния?
Стоимость включения слияния запроса - это задержка до выполнения фактической команды. Самая большая стоимость - размер пакетного окна, который по умолчанию составляет 10 мс.
Если у вас есть команда, которая занимает 5 мс для выполнения и имеет окно партии 10 мс, худший случай выполнения составляет 15 мс. Как правило, запрос не будет возникнуть, когда открытое окно партии просто открывается, поэтому промежуточное значение временного окна составляет половину временного окна, в этом случае это 5 мс.
Стоит ли эта стоимость, зависит от выполнения команды, и команды с высокой задержкой не влияют небольшая сумма дополнительной средней задержки. Более того, сумма параллелизма данной команды также является ключевым: если комбинируется менее 1 или 2 запросов, то стоимость того не стоит. Фактически, слияние последовательного итерационного запроса в одном потоке будет основным узким местом производительности, и каждая итерация будет ждать время ожидания окна в 10 мс.
Однако, если конкретная команда используется в больших количествах одновременно и может одновременно делать десятки или даже сотни вызовов одновременно, стоимость обычно гораздо больше, чем увеличение пропускной способности, поскольку Hystrix уменьшает количество потоков, которые она требует, зависимости. (Этот отрывок нелегко понять.
Процесс запроса слияния (как показано ниже)
Теоретическое знание было объяснено. Давайте посмотрим на примеры ниже. Примеры ниже интегрируют Eureka+Feign+Hystrix. На получение полного примера, пожалуйста, проверьте: https://github.com/jingangwang/micro-service
Класс сущности
Пользователь открытого класса {Private Integer ID; частное имя пользователя; частный целый возраст; public user () {} public user (INTEGER ID, String пользователя, Integer Age) {this.id = id; this.username = имя пользователя; this.age = возраст; } public integer getId () {return id; } public void setId (Integer id) {this.id = id; } public String getUsername () {return username; } public void setUsername (string username) {this.username = username; } public integer getage () {return Age; } public void setage (целый возраст) {this.age = age; } @Override public String toString () {final StringBuffer sb = new StringBuffer ("user {"); sb.append ("id ="). Append (id); sb.append (", username = '"). Append (имя пользователя) .append ('/''); SB.Append (", age ="). Append (AGE); sb.append ('}'); вернуть sb.toString (); }}Код поставщика услуг
@Restcontroller @requestmapping ("user") public class usercontroller {@requestmapping ("getuser") public user getUser (integer id) {return new user (id, "test", 29); } @RequestMapping ("getAlluser") public list <user> getalluser (String Ids) {String [] split = ids.split (","); return arrays.aslist (split) .stream () .map (id -> новый пользователь (integer.valueof (id), "test"+id, 30)) .collect (collectors.tolist ()); }}Потребительский код
Userfeignclient
@Feignclient (name = "eureka-provider", configuration = feignconfiguration.class) Общедоступный интерфейс userfeignclient {/** * Найти пользователя по идентификатору идентификатора @param id * @return user */@requestmapping (value = "user/getUser.json", method = requestmethod.getmet) (@RearetSpar (@ReequeSpar (@Requestar (@Requestar (@Requestar (@Requestar) /*** Превышение списка пользователей* @param ids list* @return пользователей коллекция*/@requestmapping (value = "user/getalluser.json", method = requestmethod.get) list <user> findalluser (@requestparam ("ids") String Ids);};};};};};};};};Userservice (устанавливается в глобальный контекст)
@Servicepublic class userservice {@autowired private userfeignclient userfeignclient; / ** * MaxRequestSinBatch Это свойство устанавливает максимальное количество запросов на обработку пакетов, по умолчанию это integer.max_value * timerdelayinmilliseconds Это свойство устанавливает, сколько времени требуется для обработки count pactoraps, collapsprosekey eclosposeLeykey). com.netflix.hystrix.hystrixcollapser.scope.global, batchmethod = "findalluser", collapserproperties = {@hystrixproperty (name = "timerdelayinmilliseconds", value = "5000"), @hystrixproperty (name = "maxrececonds", value = "5000"), @hystrixpropert Будущее <user> find (integer id) {return null; } @Hystrixcommand (commandkey = "findalluser") public list <user> findalluser (list <integer> ids) {return userfeignclient.findalluser (stringutils.join (ids, ",")); }}Feigncollapsercontroller
@Requestmapping ("user") @restcontrollerpublic class feigncollapsercontroller {@autowired private userservice userservice; @Requestmapping ("finduster") public user getUser (INTEGER ID) THROHS excripationException, прерывание {return userservice.find (id) .get (); } В приведенном выше коде мы находимся в глобальном контексте (все запросы из потоков Tomcat могут быть объединены), окно времени слияния составляет 5 с (каждый запрос должен ждать 5 с до начала запроса), а максимальное количество слияний составляет 5. В почтальце мы инициируем два запроса в пределах 5S, но идентификаторы пользователей различны.
Localhost: 8082/user/finduster.json? ID = 123189891
Localhost: 8082/user/finduster.json? ID = 222222
Результат показан на рисунке ниже, и эти два запроса объединены в один запрос на партию запроса.
Давайте протестируем контекст запроса (запрос-scope), добавьте HystrixRequestContextServletFilter упомянутое выше, и изменить пользовательский сервис
Hystrixrequestcontextservletfilter
/** * @author wjg * @date 2017/12/22 15:15 */ @webfilter (filtername = "hystrixrequestcontextservletfilter", urlpatterns = "/ *" ServletException {} @Override public void dofilter (ServletRequest servletRequest, ServletResponse Servletresponse, FilterChain FilterChain) Throws IoException, ServletException {hystrixRequestContext context = hystrixRequestContext.InitializeContext (); try {filterchain.dofilter (ServletRequest, Servletresponse); } наконец {context.shutdown (); }} @Override public void destress () {}}Userservice (установить как контекст запроса)
@Servicepublic class userservice {@autowired private userfeignclient userfeignclient; /** * maxRequestsInBatch This property sets the maximum number of requests for batch processing, the default value is Integer.MAX_VALUE * timerDelayInMilliseconds This property sets how long it takes to count batch processing, the default is 10ms * @param id * @return */ @HystrixCollapses(collapserKey = "findCollapserKey",scope = com.netflix.hystrix.hystrixcollapser.scope.request, batchmethod = "findalluser", collapserproperties = {@hystrixproperty (name = "timerdelayinmilliseconds", value = "5000"), @hystrixproperty (name = "maxrececonds", value = "5000"), @hystrixpropert Будущее <user> find (integer id) {return null; } @Hystrixcommand (commandkey = "findalluser") public list <user> findalluser (list <integer> ids) {return userfeignclient.findalluser (stringutils.join (ids, ",")); }}Feigncollapser2controller
@Requestmapping ("user") @restcontrollerpublic class feigncollapser2controller {@autowired private userservice userservice; @RequestMapping ("finduSer2") public list <user> getUser () бросает выполнение ExectionException, прерывание {будущее <user> user1 = userservice.find (1989); Будущее <user> user2 = userservice.find (1990); Список <user> users = new ArrayList <> (); users.add (user1.get ()); users.add (user2.get ()); вернуть пользователей; }} Мы вводим почтальон: Localhost: 8082/user/finduser2.json
Вы можете видеть, что два последовательных звонка в рамках запроса объединены. Обратите внимание, что это невозможно использовать userserver.find (1989) .get () напрямую, в противном случае обработка будет выполняться напрямую в соответствии с синхронизацией и не будет объединена. Если две страницы вкладок вызывают вышеуказанный адрес одновременно, обнаруживается, что были инициированы два пакетных запроса, что означает, что область применения является применением запроса.
Ссылки следующие:
https://github.com/netflix/hystrix/wiki/how-to-use
//www.vevb.com/article/140530.htm
Выше всего содержание этой статьи. Я надеюсь, что это будет полезно для каждого обучения, и я надеюсь, что все будут поддерживать Wulin.com больше.