Spring Cloud Zuul Support – Configuring Timeouts
Spring Cloud provides support for Netflix Zuul – a toolkit for creating edge services with routing and filtering capabilities.
Zuul Proxy support is very comprehensively documented at the Spring Cloud site. My objective here is to focus on a small set of attributes relating to handling timeouts when dealing with the proxied services.
Target Service and Gateway
To study timeouts better I have created a sample service(code available here) which takes in a configurable “delay” parameter as part of the request body and a sample request/response looks something like this:
A sample request with a 5 second delay:
{ "id": "1", "payload": "Hello", "delay_by": 5000, "throw_exception": false }
and an expected response:
{ "id": "1", "received": "Hello", "payload": "Hello!" }
This service is registered with an id of “sample-svc” in Eureka, a Spring Cloud Zuul proxy on top of this service has the following configuration:
zuul: ignoredServices: '*' routes: samplesvc: path: /samplesvc/** stripPrefix: true serviceId: sample-svc
Essentially forward all requests to /samplesvc/ uri to a service disambiguated with the name “sample-svc” via Eureka.
I also have a UI on top of the gateway to make testing with different delay’s easier:
Service Delay Tests
The Gateway behaves without any timeout related issues when a low “delay” parameter is added to the service call, however if the delay parameter is changed as low as say 1 to 1.5 seconds the gateway would time out.
The reason is that if the Gateway is set up to use Eureka, then the Gateway uses Netflix Ribbon component to make the actual call. Further, the ribbon call is wrapped within Hystrix to ensure that the call remains fault tolerant. The first timeout that we are hitting is because Hystrix has a very low delay tolerance threshold and tweaking the hystrix settings should get us past the first timeout.
hystrix: command: sample-svc: execution: isolation: thread: timeoutInMilliseconds: 15000
Note that the Hystrix “Command Key” used for configuration is the name of the service as registered in Eureka.
This may be a little too fine grained for this specific Zuul call, if you are okay about tweaking it across the board then configuration along these lines should do the job:
hystrix: command: default: execution: isolation: thread: timeoutInMilliseconds: 15000
With this change the request to the service via the gateway with a delay of upto 5 seconds will now go through without any issues. If we were to go above 5 seconds though we would get another timeout. We are now hitting Ribbons timeout setting which again can be configured in a fine grained way for the specific service call by tweaking configuration which looks like this:
sample-svc: ribbon: ReadTimeout: 15000
With both these timeout tweaks in place the gateway based call should now go through
Conclusion
The purpose was not to show ways of setting arbitrarily high timeout values but just to show how to set values that may be more appropriate for your applications. Sensible timeouts are very important to ensure that bad service behaviors don’t cascade upto the users. One thing to note is that if the gateway is configured without Ribbon and Eureka by specifying a direct url to a service then these timeout settings are not relevant at all.
If you are interested in exploring this further, the samples are available here.
Reference: | Spring Cloud Zuul Support – Configuring Timeouts from our JCG partner Biju Kunjummen at the all and sundry blog. |