Spring boot Ограничение числа одновременных вызовов определенного API в контроллере. - PullRequest
0 голосов
/ 03 декабря 2018

У меня есть приложение Restful, основанное на загрузке спринта (v1.5.15), которое предоставляет услуги, основанные на пользователях, в частности, вход в систему и получение сведений о пользователе.

Активность при входе в систему немного тяжелая, хотя api для получения сведений о пользователе довольно хорошлегкий вес.

У меня есть контроллер, похожий на этот

@RestController
public class UserController{

    @PostMapping("/login")
    public LoginResponse userLogin(@RequestBody LoginRequest loginRequest){
        ...
    }

    @GetMapping("/users/{id}")
    public LoginResponse userIdGet(@PathVariable("id") String id){
        ...
    }

}

Есть ли способ ограничить количество одновременных вызовов API /login.По сути, я хочу ограничить это словами x, поскольку /users/{id} может обрабатывать в тех же ресурсах примерно в 10 раз больше вызовов.

Приложение использует встроенный сервер Tomcat, и я знаю, что server.tomcat.max-connections, server.tomcat.max-threadsи server.tomcat.min-spare-threads однако они ограничивают вызовы на уровне приложения, а не на API.

1 Ответ

0 голосов
/ 10 июня 2019

Существуют решения, которые ограничивают количество активных соединений, см., Например, https://dzone.com/articles/how-to-limit-number-of-concurrent-user-session-in.

Однако, на самом деле, такие решения просто отклоняют дальнейший запрос.

Если вы это сделаетене хотелось бы отклонять запрос, вы можете ограничить параллельную работу, выполняемую с помощью фиксированного пула потоков приложения ExecutorService (https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html#newFixedThreadPool(int)), и отправить свое тело запроса в этот пул потоков и немедленно вызвать get для возвращенного Future.

Таким образом, вы можете заменить

@PostMapping("/api/xyzMethod")
public Response xyzMethod(@RequestBody Request request) {
    return handleXyzMethod(request); });
}

на

@PostMapping("/api/xyzMethod")
public Response xyzMethod(@RequestBody Request request) throws InterruptedException, ExecutionException {
    return xyzMethodExecutor.submit(() -> { return handleXyzMethod(request); }).get();
}

некоторым

private static ExecutorService xyzMethodExecutor = Executors.newFixedThreadPool(10);

Недостатком является то, что пользователю, возможно, придется ждатьответ и / или этот множественный запрос будут заполнять очередь пула потоков, пока служба не станет (тоже) не отвечающей.Поэтому, возможно, вам придется наделить это решение каким-то тайм-аутом для заданий FutureTasks или объединить два решения (которые также имеют больший лимит на количество одновременных сеансов).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...