我编写了一个 servlet,但该 servlet 尚未进入生产阶段。
我在servlet的Filter中添加了一个计数器,这样当并发请求数达到限制时,就不能再接受更多的人了。我担心一些边缘情况,例如:假设系统已经达到 49 个并发请求(最大 50 个),并且在同步块(synchronized block)中,它使 boolean 变量“ok”变为 True,然后在下一个实例中,多个线程看到Servlet 可用,赶紧进入并突破限制。
请帮忙检查此代码是否有任何缺陷:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// TODO Auto-generated method stub
// place your code here
// pass the request along the filter chain
conditionalInfoLog(logEnabled, "Incoming request...");
conditionalInfoLog(logEnabled, "Number of concurrent request(s): " + count);
boolean ok;
synchronized (lock) {
ok = count < limit;
if(ok){
count++;
}
}
if (ok) {
try{
// let the request through and process as usual
conditionalInfoLog(logEnabled, "Request accepted and processing, number of concurrent request(s): " + count);
chain.doFilter(request, response);
}catch(Exception ex){
conditionalErrorLog(logEnabled, ex.getMessage());
String xmlStr = genXmlErrMsg(ex.getMessage());
response.setContentType("text/xml");
response.getWriter().print(xmlStr);
}finally{
synchronized (lock) {
count--;
}
conditionalInfoLog(logEnabled, "End of request. Number of concurrent request(s): " + count);
}
} else {
// handle limit case, e.g. return status code 503
conditionalInfoLog(logEnabled, busyMsg);
String xmlStr = genXmlErrMsg(busyMsg);
response.setContentType("text/xml");
response.getWriter().print(xmlStr);
}
}
最佳答案
我宁愿在 servletcontainer 级别配置它,也不愿尝试把一些东西放在一起。一个像样的 servlet 容器经过了彻底的测试,并且肯定可以用于生产。
例如,Tomcat 有 maxThreads
属性正是用于此目的。您可以在<Connector>
中设置它server.xml
中的元素.
<Connector maxThreads="50" ...>
这对同时请求的数量进行了限制(顺便说一下,默认为 200)。因此,当有第 51 个请求时,它会被放入队列中(顺便说一下,其长度可通过 acceptCounts
属性配置),直到第一个请求准备就绪。这也比 503 更加用户友好。
另请参阅:
关于java - 这段代码有什么缺陷吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6182953/