如何使用Java监视来自/到servlet的HTTP请求和响应

时间:2013-03-21 11:33:50

标签: java multithreading java-ee servlets executor

我正在使用servlet(版本7)测试用Java EE编写的Web应用程序。我正在向我的servlet发送大量HTTP请求,并且我想知道所有请求何时完成。

发送请求我正在使用执行程序。此外,我不知道这是否是最有效的方法。

 for (int i=0; i < numRequests; i++) {
     ExecutorService executor = Executors.newFixedThreadPool(1); 
     Future<util.Response> responseFromServlet = null;
        responseFromServlet = executor.submit(new util.Request(new URL(url)));
     if ( i !=  numRequests -1 ) {
        executor.shutdown();
     } else {
        responseFromServlet.get().getBody(); // suspensive call for last invocation
        executor.shutdown();
     }
  }

实际上,执行程序等待上次调用的HTTP请求的结束,但它通常不是最后一个完成的。

我认为创建一个等待每个HTTP servlet响应的新线程是疯狂的。我不能生成100-200-300个线程,每个请求一个!

那么有没有办法了解所有servlet何时结束执行?如果需要,我可以修改我的servlet。

===编辑===

更确切地说,这是Request类的实现:

public class Request implements Callable<Response> {
  private URL url;

  public Request(URL url) {
      this.url = url;
  }

  @Override
  public Response call() throws Exception {
      return new Response(url.openStream());
  }
}

这就是Response类:

public class Response {
  private InputStream body;

  public Response(InputStream body) {
      this.body = body;
  }

  public InputStream getBody() {
      return body;
  }
}

2 个答案:

答案 0 :(得分:1)

使用执行程序很好,你可能希望增加ThreadPool的大小,但要有更多的并发线程来执行你的请求。

使用CoutnDownLatch初始化numRequests,等待所有线程完成。

util.Request必须在latch.countDown()方法

中调用run

代码看起来像这样(手写 - 未经测试)

ExecutorService executor = Executors.newFixedThreadPool(n);
final CountDownLatch latch = new CountDownLatch(numRequests); 
for (int i=0; i < numRequests; i++) {

     executor.submit(new util.Request(new URL(url), latch));
}
latch.await(someValue, TimeUnit.SECONDS)

` 的修改

重新执行util.Request做类似

的事情
 public class Request implements Callable<Response> {
  final private URL url;
  final private CountDownLatch latch;

  public Request(URL url, CountDownLatch latch) {
      this.url = url;
      this.latch = latch;
  }

  @Override
  public Response call() throws Exception {

       try {
          return new Response(url.openStream());
       } 
       catch (Exception e) {

          //do something useful
       }
       finally {
          latch.countDown();
       }
  }
}

您可能希望在计算掉锁定之前使用您的响应流,以验证您是否从服务器获得了所期望的响应。

答案 1 :(得分:0)

如果您使用此程序执行负载测试,或者甚至是其他方式,我强烈建议您改用Jmeter。 Jmeter已经完成了你想要做的事情,并且有许多插件可以让你安排线程/时间段等的负载/数量。你还可以通过各种图表监控所有HTTP请求。

为您的servlet编写测试take you less than 5 minutes。图表也很容易生成。

jmeter graph

如果您仍希望使用自定义程序与servlet联系,则可以始终限制请求数量并使用blocking queue through a threadpool executor进行备份。

最后,不要修改servlet。您应该能够将其监视为黑盒子。