HystrixCommand 이전에 요청 합병 ( HystrixCollapser 는 추상 부모 클래스)을 사용하여 여러 요청을 하나로 병합 한 다음 백엔드 종속성 시스템으로 호출을 시작할 수 있습니다.
아래 그림은 두 가지 경우의 스레드 수와 네트워크 연결 수를 보여줍니다. 첫 번째는 합병을 사용하지 않는 것이며, 두 번째는 요청 합병을 사용하는 것입니다 (모든 링크가 10ms 내의 짧은 시간 창에서 평행 한 것으로 가정).
요청 병합을 사용하는 이유는 무엇입니까?
요청 병합은 동시 HystrixCommand 실행을 수행하는 데 필요한 스레드 수와 네트워크 연결을 줄이는 데 사용됩니다. 요청 병합은 자동으로 수행되며 개발자가 배치 요청을 수동으로 조정하도록 강요하지 않습니다.
글로벌 컨텍스트 - 글로벌 컨텍스트 (모든 Tomcat 스레드에 걸친)
이 병합 유형은 글로벌 응용 프로그램 수준에서 수행되므로 Tomcat 스레드에 대한 사용자의 요청은 함께 병합 될 수 있습니다.
예를 들어, 동일한 JVM의 사용자 스레드가 그러한 요청을 할 때 HystrixCommand 구성하여 동일한 JVM의 사용자 스레드가 그러한 요청을 할 때 동일한 붕괴 된 네트워크 호출에 다른 요청과 함께 요청을 추가합니다.
사용자 요청 컨텍스트 - 요청 컨텍스트 (단일 Tomcat 스레드)
단일 사용자에 대해서만 배치 요청을 처리하도록 HystrixCommand 구성하면 Hystrix는 Tomcat 스레드 (요청)에 요청을 병합 할 수 있습니다.
예를 들어, 사용자가 300 개의 네트워크 요청을 실행하는 대신 300 개의 비디오 객체의 북마크를로드하려면 Hystrix가 하나로 병합 할 수 있습니다.
Hystrix는 기본적으로 요청 스코프입니다. 요청 캐시 함수 (요청 캐싱, 요청 붕괴, 요청 로그)를 사용하려면 HystrixRequestContext 의 수명주기를 관리해야합니다 (또는 대체 HystrixConcurrencyStrategy 구현).
즉, 요청을 실행하기 전에 다음 코드를 실행해야합니다.
코드 사본은 다음과 같습니다. hystrixrequestContext context = hystrixRequestContext.initializeContext ();
요청이 끝날 때 실행하십시오.
context.shutdown ();
표준 Javaweb 응용 프로그램에서는 서블릿 필터를 사용 하여이 수명주기를 초기화 할 수도 있습니다.
공개 클래스 hystrixRequestContexTervletFilter는 필터 {public void dofilter (servletrequest 요청, ServletResponse 응답, FilterChain Chain)를 IOException, servleTeXception {hyStrixRequestConcept Context = hystrixrequestContext.initializextext (); try {chain.dofilter (요청, 응답); } 마침내 {context.shutdown (); }}}그런 다음 web.xml로 구성하십시오
<filter> <display-name> hystrixRequestContexTervletFilter </display-name> <filter-name> hyStrixRequestContContexTervletFilter </filter-name> <filter-class> com.netflix.hystrix.contrib.requestservlet.hystrixrequestcontextservletfilter </filterclass> <filter-mapping> <filter-name> hystrixrequestcontextervletfilter </filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
SpringBoot를 개발하는 경우 코드는 다음과 같습니다.
@WebFilter (filtername = "hystrixRequestContContContexTERVletFilter", urlPatterns = "/*") public class hystrixRequestContexTServletFilter Filter {@override public void init (filterConfig FiLterConfig) servletrequest void void void void void public void init (@override public void intr. ServletRequest, ServletResponse ServletResponse, FilterChain FilterChain)는 ioException, ServleTeXception {hyStrixRequestContext Context = hyStrixRequestContext.initializeContext (); try {filterchain.dofilter (servletrequest, servletresponse); } 마침내 {context.shutdown (); }} @override public void destroy () {}} @springbootApplication@enablediscoveryclient@enablefeignclients@enableHyStrix // 필터가 필요합니다. 그렇지 않으면 필터가 유효하지 않아 @ServletCanpOblic Class Application {public static void main (String [] args) {new SpringApplicationBuilder (Application.run). }}병합 요청 비용은 얼마입니까?
요청 병합을 활성화하는 비용은 실제 명령이 실행되기 전에 지연입니다. 가장 큰 비용은 기본적으로 10ms 인 배치 창의 크기입니다.
실행하는 데 5ms가 걸리고 배치 창이 10ms 인 명령이있는 경우 최악의 실행 시간은 15ms입니다. 일반적으로 배치 창이 방금 열면 요청이 발생하지 않으므로 시간 창의 중간 값은 시간 창의 절반 이므로이 경우 5ms입니다.
이 비용이 가치가 있는지 여부는 실행되는 명령에 따라 다르며, 고도의 명령은 소량의 추가 평균 지연의 영향을받지 않습니다. 또한, 주어진 명령의 동시성 금액도 핵심입니다. 1 또는 2 개의 요청이 결합되면 비용은 그만한 가치가 없습니다. 실제로, 순차적 반복 요청 병합 단일 스레드는 주요 성능 병목 현상이 될 것이며 각 반복은 10ms 창 대기 시간을 기다립니다.
그러나 특정 명령이 동시에 대량으로 사용되어 동시에 배치로 수십 또는 수백 건의 호출을 만들 수 있다면, Hystrix가 필요한 스레드 수, 종속성을 줄이기 때문에 비용은 일반적으로 달성되는 처리량의 증가보다 훨씬 더 많습니다. (이 구절은 이해하기 쉽지 않습니다. 실제로 동시성이 상대적으로 높으면 Hystrix가 많은 스레드와 연결 리소스를 절약 할 수 있기 때문에 비용이 가치가 있습니다).
병합 요청 과정 (아래 그림과 같이)
이론적 지식이 설명되었습니다. 아래 예제를 살펴 보겠습니다. 아래의 예는 Eureka+Feign+Hystrix를 통합합니다. 완전한 예는 https://github.com/jingangwang/micro-service를 확인하십시오
엔티티 클래스
공개 클래스 사용자 {개인 정수 ID; 개인 문자열 사용자 이름; 개인 정수 시대; public user () {} public user (정수 ID, 문자열 사용자 이름, 정수 에이지) {this.id = id; this.username = username; this.age = age; } public Integer getId () {return id; } public void setId (정수 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 (username) .append ('/''); sb.append ( ", age ="). Append (Age); sb.append ( '}'); 반환 sb.toString (); }}서비스 제공 업체 코드
@restController @requestMapping ( "사용자") 공개 클래스 userController {@requestmapping ( "getUser") 공개 사용자 getUser (Integer ID) {return new user (id, "test", 29); } @RequestMapping ( "getAllUser") 공개 목록 <사용자> 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) public 인터페이스 userfeignclient {/** * id * @param id user id * @return user */@requestmapping (value = "user/getUser.json", method = requestger by us us us us us us us us us us us us us us us us us us us us us us us us us us us us us us us us us us us us us us us us userfeignclient {/** *. /*** 사용자 목록을 초과* @param ids id list* @return 사용자 수집*/@requestmapping (value = "user/getalluser.json", method = requestmethod.get) list <user> findalluser (@requestparam ( "ids") 문자열 IDS);}uservice (글로벌 컨텍스트로 설정)
@ServicePublic Class UserserVice {@autowired private userfeignclient userfeignclient; / ** * MAXREQUESTSINBATCH이 속성은 배치 처리 요청의 최대 수를 설정합니다. 기본값은 정수입니다 .MAX_VALUE * TIMERDELAYINMILLISECONDS이 속성은 배치 프로세싱을 계산하는 데 걸리는 시간을 설정합니다. com.netflix.hystrix.hystrixcollapser.scope.global, batchmethod = "findalluser", collapserProperties = {@hystrixproperty (name = "timerdelayinmilliseconds", value = "5000"), @hystrixproperty (name = value = ") insinbatchessinbatch" Future <user> 찾기 (정수 ID) {return null; } @HyStrixCommand (commandKey = "findAllUser") public list <user> findAllUser (list <integer> ids) {return userfeignclient.findalluser (stringUtils.join (ids, ",)); }}Feigncollapsercontroller
@requestmapping ( "사용자") @restControllerPublic Class FeignCollApserController {@autowired private userervice userervice; @requestmapping ( "findUser") 공개 사용자 getUser (Integer ID)는 executionException, InterruptedException {return userervice.find (id) .get (); } 위의 코드에서, 우리는 글로벌 컨텍스트 (Tomcat 스레드의 모든 요청이 병합 될 수 있음), 병합 시간 창은 5s (요청이 시작되기 전에 모든 요청이 5s를 기다려야한다)이며, 최대 병합 수는 5입니다. 우체부에서는 5 초 내에 두 요청을 시작하지만 사용자 ID는 다릅니다.
LocalHost : 8082/user/finduser.json? id = 123189891
LocalHost : 8082/user/finduser.json? id = 222222
결과는 아래 그림에 나와 있으며 두 요청은 하나의 요청 배치 요청으로 병합됩니다.
요청 컨텍스트 (요청-스코프)를 테스트하고, 위에서 언급 한 HystrixRequestContextServletFilter 추가하고, uservice를 수정합시다.
hystrixrequestcontextservletfilter
/** * @Author WJG * @Date 2017/12/22 15:15 */ @webfilter (filtername = "hystrixrequestContexTservleTfilter", urlpatterns = "/ *") public class hystrixRequestContexTervleTfilter 필터 {@overrider init init (filterconfig) servletexception {} @override public void dofilter (servletrequest servletrequest, servletreponse servletreponse, filterchain filterchain)는 ioexception, servletexception {hystrixrequestConcept Context = hystrixrequestContext.initializextext (); try {filterchain.dofilter (servletrequest, servletresponse); } 마침내 {context.shutdown (); }} @override public void destroy () {}}userVice (요청 컨텍스트로 설정)
@ServicePublic Class UserserVice {@autowired private userfeignclient userfeignclient; / ** * MaxRequestSinbatch이 속성은 배치 처리에 대한 최대 요청 수를 설정합니다. 기본값은 정수입니다. Max_Value * TimerDelayInmilliseconds이 속성은 배치 처리를 계산하는 데 걸리는 시간을 설정합니다. com.netflix.hystrix.hystrixcollapser.scope.request, batchmethod = "findalluser", collapserProperties = {@hystrixProperty (name = "timerdelayinmilliseconds", value = "5000"), @HyStrixProperty (name = value = ") in MaxRequestsinbatchessinbatchessinbatchs,"5000 "). Future <user> 찾기 (정수 ID) {return null; } @HyStrixCommand (commandKey = "findAllUser") public list <user> findAllUser (list <integer> ids) {return userfeignclient.findalluser (stringUtils.join (ids, ",)); }}Feigncollapser2Controller
@requestmapping ( "사용자") @restcontrollerpublic class feigncollapser2controller {@autowired private userervice userervice; @requestmapping ( "findUser2") public list <user> getUser ()는 executionException, InterruptedException {future <user> user1 = userervice.find (1989); Future <user> user2 = userervice.find (1990); List <user> user = new ArrayList <> (); user.add (user1.get ()); user.add (user2.get ()); 반환 사용자; }} Postman : 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을 더 지원하기를 바랍니다.