我们有一项服务,该服务具有一个端点,该端点需要一次只能处理2个请求。这两个请求可能需要一段时间才能完成。
当前,我们使用tomcat属性来执行此操作。 现在我们面临的问题是-当这2个线程用完该端点时,我们的运行状况检查将不再起作用。
因此,我们想限制对该特定端点的请求数量。 我们考虑了一会儿,一个想法是通过过滤器来做,但这对我来说似乎很棘手...
所以我希望有人有另一个主意?
答案 0 :(得分:3)
这是一个示例,说明如何实现异步REST控制器,该控制器将同时处理不超过2个同时发生的请求。在处理请求时,此实现不会阻止您的任何Tomcat Servlet线程。
如果在进行中的同时又有另一个到达,则调用者将获得HTTP 429(请求太多)。
此示例立即拒绝无法使用429处理的请求。相反,如果您希望将待处理的请求排队,直到2个处理线程之一可用,则将SynchronousQueue
替换为{{1}的另一种实现}。
您可能想整理一下这个示例,我故意在此处嵌入了所有适合它的类:
BlockingQueue
答案 1 :(得分:1)
默认情况下,RequestMappingHandlerAdapter
处理@Controller
的{{1}}方法。因此,最简单的方法是创建自己的@RequestMapping
并覆盖其RequestMappingHandlerAdapter
以添加控制逻辑。
下面是伪代码:
handleInternal
假设您使用的是Spring Boot MVC自动配置,则可以通过创建public static class MyRequestMappingHandlerAdapter extends RequestMappingHandlerAdapter {
//counter to keep track number of concurrent request for each HandlerMethod
//HandlerMethod represent a @RequestMapping method
private Map<HandlerMethod, Integer> requestCounterMap = new ConcurrentHashMap<>();
@Override
protected ModelAndView handleInternal(HttpServletRequest request, HttpServletResponse response,
HandlerMethod handlerMethod) throws Exception {
//Increase the counter for this handlerMethod by 1.
//Throw exception if the counter is more than 2 request
ModelAndView mv = super.handleInternal(request, response, handlerMethod);
//Method finish , decrease the counter by 1
return mv;
}
}
bean并覆盖其RequestMappingHandlerAdapter
方法,将WebMvcRegistrations
替换为您的自定义变量:
getRequestMappingHandlerAdapter()