我已经编写了一个servlet程序,该程序正在调用java类来生成随机字符串。我还写了一个HTML文件,其中有1000个IFRAME指向Servlet地址。如果有多个请求发送到Servlet,则每个请求将在单独的线程中处理。因此,在这种情况下,将创建1000个线程(1000个请求)。问题是,如果请求数量超过1000,则需要花费大量时间来处理,并且无法处理等等。如果我在后端进行复杂的计算,速度会变慢。为了快速响应,需要在servlet级别(多线程)或tomcat级别(如果可能)进行哪些更改。有什么建议吗?
@WebServlet("/test")
public class MyServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private static PrintWriter out=null;
private UserOperation operation=null;
private static int counter=0;
public MyServlet() {
super();
operation=new UserOperation();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
counter++;
out=response.getWriter();
String output=operation.getResult();
System.out.println(counter+":"+output);
out.print(output);
return;
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
import java.util.Random;
public class UserOperation {
private Random rand=null;
private int max=9;
private int min=0;
private static final String [] RESULT= {"ONE","TWO","THREE","FOUR","FIVE","SIX","SEVEN","EIGHT","NINE","TEN"};
public UserOperation() {
rand=new Random();
}
public String getResult() {
int randNum=rand.nextInt((max-min)+1)+min;
return RESULT[randNum];
}
}
1000次IFRAME调用。下面一行已在HTML文件中复制粘贴了1000次。
<IFRAME src="http://localhost:8080/MultipleRequest/test" width="30px" height="30px"></IFRAME>
答案 0 :(得分:0)
尝试在您的UserOperation类中实现java.lang.Runnable接口或扩展java.lang.Thread类以实现多线程。 还可以尝试通过添加具有适当限制的-Xmx参数来增加Java的堆大小。
答案 1 :(得分:0)
您可以在Servlet 3.0中使用异步Servlet;这里有一个例子:
仍然存在需要服务器上的端口进行持续连接的问题。发出的请求将占用一个端口,无论它是否占用一个线程,您都可以使用异步servlet减轻事件代码的影响,但是无论如何,端口部分都将保留。缓解端口短缺的唯一方法是将应用程序扩展到多台服务器
答案 2 :(得分:0)
首先,您的servlet很危险,而且不是线程安全的。首先解决。
@WebServlet("/test")
public class MyServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private final AtomicInteger counter = new AtomicInteger(0);
private final UserOperation operation=null;
public MyServlet() {
super();
operation=new UserOperation();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
int count = this.counter.incrementAndGet();
PrintWriter out=response.getWriter();
String output=operation.getResult();
System.out.println(count + ":" + output);
out.print(output);
return;
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
现在这是线程安全的,您认为创建1000个线程的事实是错误的。 Tomcat的默认请求处理线程池大小为200。因此,它将同时处理200个请求,而不是您想象的1000。
此外,您不应使用1000个iframe进行测试,因为您的浏览器通常只能向服务器发送6个并发请求。因此,我实际上怀疑您是否会收到1000个并发请求,但是一次只能从浏览器接收6个请求。 Chrome浏览器甚至可以一次看到它限制为1,因为它看到相同的URL并尝试将结果一乘一地缓存。
简而言之,我怀疑您的servlet速度很慢,但是您的测试方法使它看起来很慢!使用Apache JMeter之类的适当工具将1000个请求发送到您的服务器,然后测试性能。
答案 3 :(得分:0)
尝试在您的UserOperation类中实现java.lang.Runnable接口或扩展java.lang.Thread类以实现多线程。 还可以尝试通过添加具有适当限制的-Xmx参数来增加Java的堆大小。
@WebServlet(urlPatterns={"/AsyncServlet"}, asyncSupported=true)
public class AsyncServlet extends HttpServlet {
private static PrintWriter out=null;
private UserOperation operation=null;
private static int counter=0;
public AsyncServlet() {
super();
operation=new UserOperation();
}
@Override
public void doGet(HttpServletRequest request,
HttpServletResponse response) {
response.setContentType("text/html;charset=UTF-8");
final AsyncContext acontext = request.startAsync();
acontext.start(new Runnable() {
public void run() {
counter++;
try {
HttpServletResponse response = (HttpServletResponse) acontext.getResponse();
out=response.getWriter();
String param = acontext.getRequest().getParameter("param");
String output = operation.getResult();
System.out.println(counter + ":"+output);
out.print(output);
acontext.complete();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
public class UserOperation {
private Random rand=null;
private int max=9;
private int min=0;
private final String [] RESULT= {"ONE","TWO","THREE","FOUR","FIVE","SIX","SEVEN","EIGHT","NINE","TEN"};
public UserOperation() {
rand=new Random();
}
public String getResult() {
int randNum=rand.nextInt((max-min)+1)+min;
return RESULT[randNum];
}
}
}