有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

我正在使用servlet(版本7)测试一个用JavaEE编写的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请求的结束,但它通常不是最后一个完成的请求

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

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

==编辑===

更准确地说,以下是请求类实现:

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

这就是响应类:

public class Response {
  private InputStream body;

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

  public InputStream getBody() {
      return body;
  }
}

共 (2) 个答案

  1. # 1 楼答案

    使用执行器是可以的,不过您可能希望增加线程池的大小,以便有更多并发线程执行您的请求

    使用一个用numRequests初始化的CoutnDownLatch,它等待所有线程完成

    util.Request必须在其run方法中调用latch.countDown()

    代码如下所示(手写-未测试)

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

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

  2. # 2 楼答案

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

    为servlet编写测试应该take you less than 5 minutes。图形也很容易生成

    jmeter graph

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

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