6

фон

Я использую Spring облако Brixton.RC2, с Zuul и Eureka.Zuul/Лента/Hystrix не на повторение другого экземпляра

У меня есть один шлюз с @EnableZuulProxy и book-service с методом status. Через конфигурацию я могу эмулировать работу по методу status, спящий определенное количество времени.

Маршрут по Zuul просто

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

Я бегу два экземпляра book-service. Когда я устанавливаю время сна ниже порога тайм-аута Hystrix (1000 мс), я могу видеть запросы, идущие как к экземпляру книжных услуг. Это хорошо работает.

Проблема

Я понимаю, что если команда Hystrix выходит из строя, оно должно быть возможным для ленты повторить команду на другом сервере. Это должно сделать провал прозрачным для клиента.

Я прочитал конфигурацию ленты и добавили следующую конфигурацию в 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 

Теперь я обновить конфигурацию, так что только одна служба спит более 1 сек, а это значит, что у меня есть одно медицинское обслуживание, и один плохой.

Когда я называю шлюзы звонков получают отправить обоих случаи, и половину вызовов возвращает 500. В шлюзе я вижу таймаут 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 

Почему не Ribbon повторной попытки вызвать другой экземпляр?

Я что-то пропустил?


Ссылки

  • Касается этого question (не решен)
  • Ribbon configuration
  • Согласно этому commit Zuul должны поддерживать повторные попытки для ленты

ответ

3

По умолчанию Zuul использование SEMAPHORE, которая не позволяет установить тайм-аут. Я не смог использовать балансировку нагрузки с этой стражей. То, что работало для меня (после вашего примера):

1) Изменение изоляции Zuul к НИТИ:

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

ВАЖНЫЕ: timeoutInMilliseconds = 100000, как не говоря не HystrixTimeout. Зачем?Потому что, если Hystrix таймаут не будет балансировать любой нагрузки (я просто тестировал играть с timeoutInMilliseconds)

Затем настройте ReadTimeOut ленточку на желаемое значение:

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

В этом случае после службы 1 сек раз в ленте это будет повторить с 500ms службы

Ниже у вас есть журнал я получил в моем 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

я добавил 'ре заповедный-service.ribbon.ConnectTimeout = 250 резервирование service.ribbon.OkToRetryOnAllOperations = верно резервирование service.ribbon.MaxAutoRetriesNextServer = 2 резервирование service.ribbon.MaxAutoRetries = 0' к моей конфигурации, но я боюсь, что это не устраняет проблему. – phoenix7360

+0

Отлично! Я не понял, что повторения лент происходят в одной и той же системе Хистрикс. Я думал, что у каждой попытки будет своя команда Hystrix. Это имеет гораздо большее значение. – phoenix7360