Spring Boot控制器中限制特定API的并发调用次数

4

我有一个基于Sprint Boot (v1.5.15) 的Restful应用程序,提供基于用户的服务,特别是登录和获取用户详细信息。

登录活动稍微有点繁重,而获取用户详细信息的api非常轻量级。

我有一个类似于这样的控制器:

@RestController
public class UserController{

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

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

}

有没有办法限制对 /login api 的并发调用次数呢?基本上,我想将其限制为 x 次,而 /users/{id} 可以在相同的资源上处理大约 10 倍于那些调用的数量。
该应用程序使用嵌入式 Tomcat 服务器,我知道有 server.tomcat.max-connectionsserver.tomcat.max-threadsserver.tomcat.min-spare-threads 这些设置,但这些设置只能在应用程序级别上限制调用,而不能在 API 级别上实现。

也许通过节流来实现:https://github.com/weddini/spring-boot-throttling/blob/master/README.md - PeterMmm
您可以使用Spring AOP拦截登录调用,同时使用自定义计数器,并在counter > MaxAllowed时返回HTTP错误代码。 - user10639668
@EugenCovaci - 那是一种我想检查是否有任何帮助我的开箱即用的东西的方式。 - Yogesh_D
@PeterMmm - 谢谢,我会去看看的。 - Yogesh_D
1个回答

4
有一些解决方案可以限制活动连接的数量,例如见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))来限制并发工作,并将请求体提交到该线程池,立即调用返回的Future上的get方法。
因此,您可以替换掉原有的方法。
@PostMapping("/api/xyzMethod")
public Response xyzMethod(@RequestBody Request request) {
    return handleXyzMethod(request); });
}

by

@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上加入某种超时机制或者将两种解决方案结合起来(即设置更大的并发会话限制)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接