限制Spring Webservice并发调用

3
我希望您能为我的服务优化和减少REST-API的使用滥用。
因此,是否有“开箱即用”的方法来限制对Java Spring上的webserivce的并发调用次数?
例如,如果我有以下方法:
@RequestMapping(value="demo",method=RequestMethod.GET)
    public synchronized @ResponseBody ObjectNode getDemo()
    {
        logger.info("started.. demo ");
        ObjectNode node = om.createObjectNode().put("test", true);
        logger.info("end.. demo");
        return node;
    }

我将把这项服务限制在同时只有1个用户使用。但是,如果要将其限制为4或10个并发用户呢?
谢谢 :)

2
你找到任何解决方案了吗?我也遇到了同样的问题。 - Vishal Patel
1个回答

1

截至目前为止,Spring 没有开箱即用的 限流支持

但是如果您使用 Google Guava,那么可以通过 RateLimiter 类提供支持,详细说明请参见此处

如果无法使用 Google Guava,请考虑通过 令牌桶 算法实现速率限制。

示例实现应包括以下组件 -

  • 一个用于保存令牌的(最好是内存缓存)
  • 一个用于拦截请求的Servlet 过滤器(最好在 web.xml 中仅配置要限制速率的 URL,并避免使用 /* 模式)
  • 一个定时服务,定期补充桶中的令牌

Bucket - 简单来说,可以将Bucket创建为一个缓存条目,其键名为URL,值为可用令牌,如下例所示:

key = '/test/demo' value = 5
key = '/test/otherDemo' value = 10

最好使用AtomicInteger来保存令牌计数,以避免任何并发访问问题

Filter - 在这里,只需从Bucket中获取一个令牌(即读取缓存并查找令牌的正值;对于每个请求,将令牌值减少一直到为零)。 仅当获取到令牌时才进行请求,否则使用HTTP状态码429阻止请求。

Scheduler - 基于cron的定时服务(参见Spring @Scheduled)用于重置缓存,以达到每单位时间允许的最大请求数。

如果需要更多信息,请在评论中告诉我。


不错的方法,但是我想限制我的服务只使用固定数量的并发调用(比如说4个)。这是因为我不确定调用此服务需要多长时间。并且并发调用越多,服务就会越慢。 - dsncode
在这种情况下,您仍然可以使用此方法,因为调度程序将在每次运行中将桶补充到固定数量(在您的情况下为4)。另外,允许的最大调用次数可以保持可配置(在属性文件/数据库中*)。 - Bond - Java Bond
不,我认为在这种情况下@Bond-JavaBond所说的不可能。 - Vishal Patel

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