Zuul / Ribbon / Hystrix不会在不同的实例上重试

背景

我正在使用Spring云Brixton.RC2,与Zuul和Eureka合作。

我有一个使用@EnableZuulProxy网关服务和一个使用status方法的book-service 。 通过配置,我可以通过睡眠定义的时间模拟status方法的工作。

祖鲁的路线很简单

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

我运行了book-service两个实例。 当我将睡眠时间设置在Hystrix超时阈值(1000毫秒)以下时,我可以看到请求转到两个图书服务的实例。 这很好。

问题

我知道如果Hystrix命令失败,Ribbon可能会在不同的服务器上重试该命令。 这应该会让客户失败。

我阅读功能区配置并在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没有在其他实例上重试呼叫?

我在这里错过了什么吗?


参考

  • 有关这个问题(未解决)
  • 功能区配置
  • 根据这个承诺,Zuul应该支持Ribbon的重试

  • 默认情况下,Zuul使用SEMAPHORE隔离策略,该策略不允许设置超时。 我无法在这种策略中使用负载平衡。 对我有用的是(以你为例):

    1)将Zuul的隔离改为THREAD:

    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秒服务在Ribbon中超时后,将使用500毫秒服务重试

    下面你有我的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=[org.springframework.web.servlet.resource.PathResourceResolver@a0d875d]]] 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
    
    链接地址: http://www.djcxy.com/p/34259.html

    上一篇: Zuul/Ribbon/Hystrix not retrying on different instance

    下一篇: Adding load balancer to a wordpress multisite installation