Spring boot: Separate thread pool for specific endpoint

Viewed 600

Given a microservice in Spring Boot, it offers 2 end-points to be consumed from 2 separate system. One of this system is critical while the other one is not. I would like to prevent the "not critical" one to consume (due to unexpected problems) all the threads (or many) of the HTTP thread pool, so I would like to configure separated thread pools for each one of these end-points.

Is that possible?

2 Answers

There are multiple ways to do this. Using DeferredResult is probably the easiest way:

@RestController
public class Controller {

    private final Executor performancePool = Executors.newFixedThreadPool(128);
    private final Executor normalPool = Executors.newFixedThreadPool(16);

    @GetMapping("/performance")
    DeferredResult<String> performanceEndPoint() {
        DeferredResult<String> result = new DeferredResult<>();
        performancePool.execute(() -> {
            try {
                Thread.sleep(5000); //A long running task
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            result.setResult("Executed in performance pool");
        });
        return result;
    }

    @GetMapping("/normal")
    DeferredResult<String> normalEndPoint() {
        DeferredResult<String> result = new DeferredResult<>();
        normalPool.execute(() -> result.setResult("Executed in normal pool"));
        return result;
    }
}

You immediately release the Tomcat thread by returning a DeferredResult from a controller, allowing it to serve other requests. The actual response is written to the user when the .setResult method is called.

DeferredResult is one of the many ways you can perform asynchronous request processing in Spring. Check out this section of the docs to learn more about the other ways:

https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-ann-async

Related