【问题标题】:How to monitoring HTTP requests and responses from/to servlets using Java如何使用 Java 监视来自 / 到 servlet 的 HTTP 请求和响应
【发布时间】:2013-03-10 21:29:52
【问题描述】:

我正在测试一个使用 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());
  }
}

这是响应类:

public class Response {
  private InputStream body;

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

  public InputStream getBody() {
      return body;
  }
}

【问题讨论】:

    标签: java multithreading jakarta-ee servlets executor


    【解决方案1】:

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

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

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

    【讨论】:

    • 谢谢!我阅读了 CountDownLatch javadoc,它听起来很有用!我有一些问题: 1) 为什么 util.Request 应该调用 countDown()? request run() 方法是否在 servlet 完成执行后执行? (我用 Request 和 Response 类编辑了我的原始问题) 2)如果多次调用 executor.submit() 而我没有调用 executor.shutdown(),则第一个 submit() 的调用会在继续之前等待响应.也许我应该使用 execute() 代替?
    • 请求是可调用的,所以它是 call 方法应该 countDown 锁存器。当计数达到零时,锁存器await 将停止阻塞。请参阅上面我编辑的答案
    • 它对我有用。在安装在 OS X 10.8、Ubuntu 12.10 和 Windows XP 上的 Apache Tomcat 上进行了测试。然而实际上执行程序并没有在 Windows 7 上创建新线程,我们无法理解为什么。我们试图以管理员身份执行它,并更改权限但没有任何运气。
    【解决方案2】:

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

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

    如果您仍想使用您的自定义程序来联系 servlet,您可以随时限制请求的数量并使用blocking queue through a threadpool executor 备份它们。

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

    【讨论】:

      猜你喜欢
      • 2014-07-24
      • 2018-07-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-27
      • 1970-01-01
      • 2012-12-09
      相关资源
      最近更新 更多