3

我正在使用 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;
  }
}
4

2 回答 2

1

使用执行器很好,您可能希望增加 ThreadPool 的大小,尽管让更多并发线程执行您的请求。

使用初始化的CoutnDownLatchnumRequests等待所有线程完成。

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();
       }
  }
}

您可能希望在对闩锁进行倒计时之前使用您的响应流,以验证您是否从服务器获得了您期望的响应。

于 2013-03-21T12:04:49.433 回答
0

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

为您的 servlet 编写测试将花费您不到 5 分钟的时间。图表也很容易生成。

jmeter图

如果您仍想使用您的自定义程序来联系 servlet,您始终可以限制请求的数量并通过线程池执行程序使用阻塞队列备份它们。

最后,不要修改 servlet。您应该能够将其作为黑匣子进行监控。

于 2013-03-21T12:32:24.060 回答