2

我正在玩 Josh Long 的bootiful-microservice 项目。(布里克斯顿子项目)

在预订服务上,我添加了一个简单的状态方法,它可以休眠一段可配置的时间来模拟负载:

@RequestMapping(method = RequestMethod.GET, value = "/status")
public String status(){
    System.out.println("Checking status");
    try {
        Thread.sleep((long) (rand.nextDouble()*sleepTime));
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    return "All is good";
}

sleepTime变量是从 Spring Config Server 中提取的

在预订客户端上,我在网关中添加了一个入口点:

@FeignClient("reservation-service")
interface ReservationReader {

    @RequestMapping(method = RequestMethod.GET, value = "/reservations")
    Resources<Reservation> readReservations();

    @RequestMapping(method = RequestMethod.GET, value = "/status")
        String status();
    }
}

我正在使用HystrixCommand

@HystrixCommand(fallbackMethod = "statusFallback")
@RequestMapping(method = RequestMethod.GET, value = "/status")
public String status(){
    return reader.status();
}

public String statusFallback(){
    return "Bad";
}

这一切都很好。

我将睡眠时间设置为 1500 毫秒,以便某些请求将高于 Hystrix 默认阈值(1000 毫秒)。

当我开始使用 API 时,由于超时,我遇到了一些失败。如果我击打的时间足够长(似乎可以工作 50 次),断路器触发并且电路打开:

Hystrix 仪表板

我的理解是,随着下游服务再次变得健康,Hystrix 将尝试路由 1 个呼叫并将其用作健康检查。如果调用成功,电路应再次关闭。

然而,这并没有发生在这里。即使将睡眠时间更改为较小的值(例如 500 毫秒),电路仍将保持打开状态。我的所有呼叫都没有路由到预订服务,并且每次呼叫都使用回退。我可以让电路再次关闭的唯一方法是重新启动预订客户端服务。

我错过了什么?Hystrix 有问题吗?还是与 Spring 集成?


更新

我做了进一步的测试,我可以确认电路将永远保持关闭,即使在睡眠减少之后也是如此。

但是,如果我在 Zuul 配置中使用路由,我会得到预期的行为。如果看到没有超时的请求,电路会自行关闭。

我注意到通过路由转发与在 Spring 中手动转发相比的另一个区别。如果我创建过滤器,我在客户端上的 /status/ 调用不会触发过滤器。当我设置路由时(例如 /foos/status => /status),它将触发过滤器并且 Hystrix 行为正常。

这是Spring中的错误吗?

4

0 回答 0