【问题标题】:Limit Spring Webservice concurrent calls限制 Spring Webservice 并发调用
【发布时间】:2016-12-16 17:53:29
【问题描述】:

我想优化和减少我的服务滥用 REST-API。

那么,是否有任何“开箱即用”的方式来限制对 java spring 上 web 服务的并发调用量?

例如,如果我下面有这个方法

@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 个并发用户怎么样?

谢谢:)

【问题讨论】:

  • 你找到解决办法了吗?我有同样的问题。

标签: java spring web-services concurrency


【解决方案1】:

截至目前,没有开箱即用的 rate limiting support 用于 Spring。

但是,如果您有/可以使用 Google Guava,那么有 RateLimiter 类形式的支持,其中有详细说明 here

如果 Google Gauva 不是一个选项,请考虑通过 Token Bucket 算法实现速率限制器。

示例实现应具有以下组件 -

  • 一个 bucket 来保存令牌(最好是内存缓存
  • servlet 过滤器 来拦截请求(最好只配置那些在web.xml 中进行速率限制的 URL,避免使用/* 模式
  • 一个定时服务定期补充桶

Bucket - 在最简单的形式中,可以将存储桶创建为缓存条目,其中键名作为 URL,值作为可用令牌,如下例所示

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

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

过滤器 - 这里简单地尝试从桶中获取令牌(即读取缓存并查找令牌的正值;每次请求将令牌值减一直到为零)。 仅在获取令牌时继续请求,否则使用HTTP status code 429 阻止请求

调度程序 - 一个基于 cron 的调度服务(参见 Spring @Scheduled),以每单位时间允许的最大请求数重置缓存。

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

【讨论】:

  • 好方法,但是,我想限制我的服务使用固定数量的并发调用(比如说 4 个)。这是因为,我不确定调用此服务需要多长时间。并且并发调用越多,服务越慢。
  • 在这种情况下,您仍然可以使用这种方法,因为调度程序会在每次运行中将存储桶补充到固定数量(在您的情况下为 4)。另外,允许调用的最大数量可以保持可配置(在属性文件/数据库中
  • 不,我认为@Bond-JavaBond 所说的在这种情况下是不可能的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-24
  • 2012-09-23
  • 2018-04-07
  • 2020-03-28
  • 2017-07-29
  • 2012-02-20
  • 2016-06-07
相关资源
最近更新 更多