I'm playing with the bootiful-microservice project by Josh Long. (Brixton subproject)
On the reservation-service I have added a simple status method that can sleep a configurable amount of time to simulate load:
@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";
}
The sleepTime
variable is pulled from the Spring Config Server
On the reservation-client I have added an entry point in the gateway:
@FeignClient("reservation-service")
interface ReservationReader {
@RequestMapping(method = RequestMethod.GET, value = "/reservations")
Resources<Reservation> readReservations();
@RequestMapping(method = RequestMethod.GET, value = "/status")
String status();
}
}
and I'm using an HystrixCommand
@HystrixCommand(fallbackMethod = "statusFallback")
@RequestMapping(method = RequestMethod.GET, value = "/status")
public String status(){
return reader.status();
}
public String statusFallback(){
return "Bad";
}
This all works well.
I set the sleeping time to 1500ms so that some request will be above the Hystrix default threshold (1000ms).
When I start hitting the API I get some failures due to timeout. If I hit long enough (50 times seems to work) the circuit breaker trigger and the circuit becomes open:
My understanding is that as the downstream service becomes healthy again Hystrix will try to route 1 call and use it as a health check. If the call is successful circuit should be closed again.
However this is not happening here. The circuit will remain open even after changing the sleeping time to a smaller value (let's say 500ms). None of my calls are routed towards the reservation-services and the fallback is used on every call. The only way I can get the circuit to close again is to restart the reservation-client service.
Did I miss something? Is it an issue with Hystrix? Or with the Spring Integration?
UPDATE
I did further testing and I can confirm that the circuit will remain close forever, even after the sleeping has been reduced.
However if I use a route in the Zuul configuration I get the expected behaviour. The circuit closes itself if it sees a request that doesn't time out.
I have noticed another difference between forwarding by route compare to manually doing it in Spring. If I create a filter my /status/ call on the client does not trigger the filter. When I setup a route (eg. /foos/status => /status) it will trigger the filter and Hystrix behaves properly.
Is that a bug in Spring?