如何设置servlet中并发请求数的限制?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何设置servlet中并发请求数的限制?相关的知识,希望对你有一定的参考价值。

我得到了这个servlet,它将pdf文件返回给客户端Web浏览器。我们不想冒任何风险,当请求数量过多时,服务器就会瘫痪。

我们希望以应用程序级别(程序)方式设置并发请求数量的限制,并在达到限制时向浏览器返回错误消息。我们需要在应用程序级别执行它,因为我们在开发级别(tomcat)和生产级别(websphere)中有不同的servlet容器。

我必须强调,我想控制最大请求数而不是会话数。用户可以使用相同的会话通过服务器发送多个请求。

任何的想法?我曾考虑使用静态计数器来跟踪请求的数量,但这会引发竞争条件的问题。

答案

我建议写一个简单的servlet Filter。在web.xml中配置它以应用于要限制并发请求数的路径。代码看起来像这样:

public class LimitFilter implements Filter {
    private int limit = 5;
    private int count;
    private Object lock = new Object();

    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        try {
            boolean ok;
            synchronized (lock) {
                ok = count++ < limit;
            }
            if (ok) {
                // let the request through and process as usual
                chain.doFilter(request, response);
            } else {
                // handle limit case, e.g. return status code 429 (Too Many Requests)
                // see http://tools.ietf.org/html/rfc6585#page-3
            }
        } finally {
            synchronized (lock) {
                count--;
            }           
        }
    }
}

或者你可以把这个逻辑放入你的HttpServlet。作为Filter,它只是更清洁,更可重复使用。您可能希望通过web.xml配置限制,而不是对其进行硬编码。

参考: 检查HTTP status code 429的定义。

另一答案

你可能想看看Semaphore

信号量通常用于限制线程数,而不是访问某些(物理或逻辑)资源。

或者甚至更好地尝试使用服务器设置来解决它。那当然是服务器依赖的。

另一答案

我曾考虑使用静态计数器来跟踪请求的数量,但这会引发竞争条件的问题。

如果您使用AtomicInteger作为计数器,您将不会遇到竞争条件问题。

另一种方法是使用Java Executor Framework(Java 1.5附带)。在那里,您可以限制正在运行的线程数,并阻止新的一次,直到有一个新的空闲线程。

但我认为计数器可行并且是最简单的解决方案。

注意:把计数器放在最后一块!

//psydo code
final AtomicInteger counter;
...
while(true) {
  int v = counter.getValue()
  if (v > max) return FAILURE;
  if(counter.compareAndSet(v, v+1)) break;  
}
try{
  doStuff();
} finally{
  counter.decrementAndGet();
}
另一答案

您可以使用RateLimiter。有关解释,请参阅this文章。

另一答案

如果您正在提供静态文件,则服务器不太可能崩溃。瓶颈将是网络吞吐量,并且它会优雅地降级 - 当有更多请求进入时,每个请求仍会得到服务,只是稍微慢一点。

如果您对总请求设置了硬限制,请记住设置每个IP请求的限制。否则,一个坏人很容易发出N个请求,故意非常慢地阅读响应,并完全阻塞你的服务。即使他在拨号上并且您的服务器网络具有巨大的吞吐量,这也可以工作。

以上是关于如何设置servlet中并发请求数的限制?的主要内容,如果未能解决你的问题,请参考以下文章

如何从设置中获取数据并发送到此片段

如何突破浏览器加载并发数的限制

nginx 限制并发访问及请求频率

如何限制并发的 异步IO 请求数量?

如何在底部导航中使用设置屏幕外页面限制

故障分析 一次因为超过最大连接数的登陆限制