6

Sfondo

sto usando primavera nuvola Brixton.RC2, con Zuul e Eureka.Zuul/nastro/Hystrix non riprovare su diversi esempio

Ho un servizio gateway con @EnableZuulProxy e un book-service con un metodo status. Tramite la configurazione posso emulare il lavoro sul metodo status dormendo un intervallo di tempo definito.

percorso Lo Zuul è semplice

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

corro due istanze della book-service. Quando imposto il tempo di sospensione al di sotto della soglia di timeout Hystrix (1000 ms), posso vedere le richieste che vanno ad entrambe le istanze dei servizi di libro. Funziona bene

Problema

ho capito che se il comando non riesce Hystrix, dovrebbe essere possibile per il nastro per ritentare il comando su un server diverso. Questo dovrebbe rendere l'errore trasparente per il cliente.

ho letto la configurazione del nastro e ha aggiunto la seguente configurazione in 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 

Ora aggiornare la configurazione in modo che un solo servizio dorme per più di 1 s, il che significa che ho un servizio sanitario, e uno cattivo.

Quando chiamo i gateway delle chiamate ottengono segnala ad entrambe le istanze, e la metà delle chiamate restituisce una 500. Nel gateway vedo il 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 

Perché non è riprovare nastro della chiamare l'altra istanza?

Mi manca qualcosa qui?


Riferimenti

risposta

3

Per default Zuul uso s Strategia di isolamento SEMAPHORE che non consente di impostare un timeout. Non sono stato in grado di utilizzare il bilanciamento del carico con questo stragegy. Che cosa ha funzionato per me è stato (seguendo il tuo esempio):

1) Modifica l'isolamento di Zuul alla discussione:

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

IMPORTANTI: timeoutInMilliseconds = 100000 è come dire di no HystrixTimeout. Perché?Perché se Hystrix volte fuori non ci sarà il bilanciamento qualsiasi carico (ho appena provato a giocare con timeoutInMilliseconds)

Quindi, configurare ReadTimeout del nastro al valore desiderato:

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

In questo caso dopo il servizio 1sec volte nel nastro che sarà ritentare con il servizio di 500ms

di seguito si ha il registro ho ottenuto nel mio caso Zuul:

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

ho aggiunto 're servation-service.ribbon.ConnectTimeout = 250 prenotazione-service.ribbon.OkToRetryOnAllOperations = true prenotazione-service.ribbon.MaxAutoRetriesNextServer = 2 prenotazione-service.ribbon.MaxAutoRetries = 0 ' per la mia configurazione, ma ho paura che non risolve il problema – phoenix7360

+0

Ottimo ha funzionato! Non mi ero reso conto che i tentativi del nastro si verificano all'interno dello stesso comando Hystrix. Ho pensato che ogni nuovo tentativo avrebbe il proprio comando Hystrix. Ha molto più senso. – phoenix7360