2

currently I'm exploring approaches to implement 'request timeout management in an AOP way in Spring Boot' with several restrictions. The requirements/restrictions are stated as below:

  • The original purpose is that if the processing time of an api request exceeds 5 seconds, then directly return timeout result instead of continue processing
  • The rest api to be monitored is implemented by standard spring mvc rest controller. All apis inside are returning json strings like this:

    @RestController
    public class xxxxxx {
        @RequestMapping(value = "xxxxxxx")
        public String xxxxxx(@RequestParam(value = "xxxx", required = true) String xxxx) {
            ....
            return json.toString();
        }
    }
    
  • The timeout logic is required to be implemented by AOP
  • (The real mean part) No changes should be made to the controllers, which means: Request generation approach should not be changed; Return type should not be changed(No 'Callable<...>' allowed)

I have already found 1 answer(Async approach) which can perfectly resolve the problem itself with spring async, and the timeout return result is very pretty, but it's changing the return type, and also touching the code in controller. I also found one solution(AOP approach) which is using AOP, but the scenario is quite different from mine. It's already moving some business logic into AOP class, but I'm not allowed to touch the controller code. I would be grateful if anyone can provide a solution. Solutions that can't meet all the restrictions but are minimizing the differences are also admitted.

1 Answers1

2

Since there is still no response to this question, I will put my own temporary solution here.

I'm using Hystrix dependency.

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-hystrix</artifactId>
        <version>1.4.0.RELEASE</version>
    </dependency>

It's well integrated with springboot, so the configuration is easy. Once properly configured, need to append an annotation on the request method that requires timeout handling. e.g.

@HystrixCommand(fallbackMethod="fallback")
@RequestMapping(value = "xxxxxxx")
public String xxxxxx(@RequestParam(value = "xxxx", required = true) String xxxx) {
    ....
    return json.toString();
}

And need to add a fallback method with the name mapped to the value of 'fallbackMethod' inside annotation:

public String fallback() {
   ...
}

The timeout time value can be globally configured inside application.properties

hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=3000
hystrix.command.default.circuitBreaker.sleepWindowInMilliseconds=3000

This is still not concise in these points:

  • Need to copy/paste this annotation for every method
  • Need to copy/paste the fallback method in every place hystrix is used
  • For hystrix fallback method itself, the parameter type and number need to be exactly same with the hystrix marked method. Currently I'm using several overloading method called 'fallback' for this, in each controller

But at least it's not changing method return types and code inside methods anymore and is the best solution I can think of currently. Will perform update once I find better solutions.