6

Tle

mi stosując wiosna mętnienia Brixton.RC2 z Zuul i Eureka.Zuul/taśmy/Hystrix nie Ponowna próba na inny przykład

Mam jedną usługę gateway z @EnableZuulProxy i book-service metodą status. Poprzez konfigurację mogę emulować pracę na metodzie status, śpiąc określoną ilość czasu.

route Zuul jest prosta

zuul.routes.foos.path=/foos/** 
zuul.routes.foos.serviceId=reservation-service 

uruchomić dwóch wystąpień book-service. Kiedy ustawiam czas spoczynku poniżej progu limitu czasu Hystrix (1000ms), widzę, że żądania są wysyłane do obu instancji usług książki. To działa dobrze.

Problem

Rozumiem, że jeśli komenda Hystrix zawiedzie, powinno być możliwe do wstążki, aby ponowić próbę polecenia na innym serwerze. To powinno uczynić niepowodzenie przejrzystym dla klienta.

czytam konfigurację wstążki i dodaje następującą konfigurację w Zuul:

zuul.routes.reservation-service.retryable=true //not sure which one to try 
zuul.routes.foos.retryable=true //not sure which one to try 

ribbon.MaxAutoRetries=0 // I don't want to retry on the same host, I also tried with 1 it doesn't work either 
ribbon.MaxAutoRetriesNextServer=2 
ribbon.OkToRetryOnAllOperations=true 

Teraz zaktualizować konfigurację tak, że tylko jedna usługa śpi dłużej niż 1s, co oznacza, że ​​mam jedną służbę zdrowia, a jeden zły.

Kiedy wzywam bram wywołania uzyskać wysłać do obu instancji, a połowa połączeń zwraca 500. W bramie widzę timeout hystrix:

com.netflix.zuul.exception.ZuulException: Forwarding error 
    [...] 
Caused by: com.netflix.hystrix.exception.HystrixRuntimeException: reservation-service timed-out and no fallback available. 
    [...] 
Caused by: java.util.concurrent.TimeoutException: null 

Dlaczego nie jest ponawianie wstążka zadzwonić na drugą instancję?

Czy brakuje czegoś tutaj?


Odniesienia

Odpowiedz

3

Domyślnie Zuul posługiwać się s Strategia izolacji SEMAPHORE, która nie pozwala ustawić limitu czasu. Nie byłem w stanie korzystać z równoważenia obciążenia za pomocą tej strategii. Co pracował dla mnie było (po swoim przykładzie):

1) Zmiana izolację Zuul do wątku:

hystrix: 
    command: 
    reservation-service: 
     execution: 
     isolation: 
      strategy: THREAD 
      thread: 
      timeoutInMilliseconds: 100000 

WAŻNE: timeoutInMilliseconds = 100000 jest jak powiedzenie nie HystrixTimeout. Czemu?Bo jeśli hystrix razy tam nie będzie równoważenie dowolnego obciążenia (I tylko przetestowane to gry z timeoutInMilliseconds)

Następnie należy skonfigurować ReadTimeout wstążka do żądanej wartości:

reservation-service: 
    ribbon: 
    ReadTimeout: 800 
    ConnectTimeout: 250 
    OkToRetryOnAllOperations: true 
    MaxAutoRetriesNextServer: 2 
    MaxAutoRetries: 0 

W tym przypadku po służbie 1 s czasy w Wstęgę będzie ona ponownie z usług 500ms

Poniżej masz dziennik mam w Zuul przykład:

o.s.web.servlet.DispatcherServlet  : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/api/stories] 
o.s.web.servlet.DispatcherServlet  : Last-Modified value for [/api/stories] is: -1 
c.n.zuul.http.HttpServletRequestWrapper : Path = null 
c.n.zuul.http.HttpServletRequestWrapper : Transfer-Encoding = null 
c.n.zuul.http.HttpServletRequestWrapper : Content-Encoding = null 
c.n.zuul.http.HttpServletRequestWrapper : Content-Length header = -1 
c.n.loadbalancer.ZoneAwareLoadBalancer : Zone aware logic disabled or there is only one zone 
c.n.loadbalancer.LoadBalancerContext  : storyteller-api using LB returned Server: localhost:7799 for request /api/stories 

---> ATTEMPTING THE SLOW SERVICE 

com.netflix.niws.client.http.RestClient : RestClient sending new Request(GET:) http://localhost:7799/api/stories 
c.n.http4.MonitoredConnectionManager  : Get connection: {}->http://localhost:7799, timeout = 250 
com.netflix.http4.NamedConnectionPool : [{}->http://localhost:7799] total kept alive: 1, total issued: 0, total allocated: 1 out of 200 
com.netflix.http4.NamedConnectionPool : No free connections [{}->http://localhost:7799][null] 
com.netflix.http4.NamedConnectionPool : Available capacity: 50 out of 50 [{}->http://localhost:7799][null] 
com.netflix.http4.NamedConnectionPool : Creating new connection [{}->http://localhost:7799] 
com.netflix.http4.NFHttpClient   : Attempt 1 to execute request 
com.netflix.http4.NFHttpClient   : Closing the connection. 
c.n.http4.MonitoredConnectionManager  : Released connection is not reusable. 
com.netflix.http4.NamedConnectionPool : Releasing connection [{}->http://localhost:7799][null] 
com.netflix.http4.NamedConnectionPool : Notifying no-one, there are no waiting threads 

--- HERE'S RIBBON'S TIMEOUT 

c.n.l.reactive.LoadBalancerCommand  : Got error com.sun.jersey.api.client.ClientHandlerException: java.net.SocketTimeoutException: Read timed out when executed on server localhost:7799 
c.n.loadbalancer.ZoneAwareLoadBalancer : Zone aware logic disabled or there is only one zone 
c.n.loadbalancer.LoadBalancerContext  : storyteller-api using LB returned Server: localhost:9977 for request /api/stories 

---> HERE IT RETRIES 

com.netflix.niws.client.http.RestClient : RestClient sending new Request(GET:) http://localhost:9977/api/stories 
c.n.http4.MonitoredConnectionManager  : Get connection: {}->http://localhost:9977, timeout = 250 
com.netflix.http4.NamedConnectionPool : [{}->http://localhost:9977] total kept alive: 1, total issued: 0, total allocated: 1 out of 200 
com.netflix.http4.NamedConnectionPool : Getting free connection [{}->http://localhost:9977][null] 
com.netflix.http4.NFHttpClient   : Stale connection check 
com.netflix.http4.NFHttpClient   : Attempt 1 to execute request 
com.netflix.http4.NFHttpClient   : Connection can be kept alive indefinitely 
c.n.http4.MonitoredConnectionManager  : Released connection is reusable. 
com.netflix.http4.NamedConnectionPool : Releasing connection [{}->http://localhost:9977][null] 
com.netflix.http4.NamedConnectionPool : Pooling connection [{}->http://localhost:9977][null]; keep alive indefinitely 
com.netflix.http4.NamedConnectionPool : Notifying no-one, there are no waiting threads 
o.s.web.servlet.DispatcherServlet  : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling 
o.s.web.servlet.DispatcherServlet  : Successfully completed request 
o.s.web.servlet.DispatcherServlet  : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/favicon.ico] 
o.s.w.s.handler.SimpleUrlHandlerMapping : Matching patterns for request [/favicon.ico] are [/**/favicon.ico] 
o.s.w.s.handler.SimpleUrlHandlerMapping : URI Template variables for request [/favicon.ico] are {} 
o.s.w.s.handler.SimpleUrlHandlerMapping : Mapping [/favicon.ico] to HandlerExecutionChain with handler [ResourceHttpRequestHandler [locations=[ServletContext resource [/], class path resource [META-INF/resources/], class path resource [resources/], class path resource [static/], class path resource [public/], class path resource []], resolvers=[[email protected]d875d]]] and 1 interceptor 
o.s.web.servlet.DispatcherServlet  : Last-Modified value for [/favicon.ico] is: -1 
o.s.web.servlet.DispatcherServlet  : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling 
o.s.web.servlet.DispatcherServlet  : Successfully completed request 
+0

Dodałem 're Konserwacji-service.ribbon.ConnectTimeout = 250 rezerwacja-service.ribbon.OkToRetryOnAllOperations = true rezerwacja-service.ribbon.MaxAutoRetriesNextServer = 2 rezerwacja-service.ribbon.MaxAutoRetries = 0' do mojej konfiguracji, ale obawiam się, że nie rozwiązuje problemu. – phoenix7360

+0

Świetnie działało! Nie zdawałem sobie sprawy, że próba wstęgi odbywa się w ramach tego samego polecenia Hystrix. Myślałem, że każda próba będzie miała własne polecenie Hystrixa. Ma to o wiele większy sens. – phoenix7360