2013-03-21 45 views
3

我正在測試使用servlet(版本7)在Java EE中編寫的Web應用程序。我發送了很多HTTP請求到我的servlet,並且我想知道所有請求何時完成。如何使用Java監視HTTP請求和從/到servlet的響應

發送請求我正在使用執行程序。此外,我不知道這是否是最有效的方法。

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。

===編輯===

更確切地說,這裏是請求類實現:

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

而這個IT Response類:

public class Response { 
    private InputStream body; 

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

    public InputStream getBody() { 
     return body; 
    } 
} 

回答

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

在countDown鎖定之前,您可能想要使用您的響應流,以驗證您獲得了您期望的服務器響應。

+0

謝謝!我讀了CountDownLatch javadoc,它聽起來很有用!我有一些問題:1)爲什麼應該util.Request調用countDown()?請求run()方法是否在servlet完成其執行後執行? (我使用Request和Response類編輯了我的原始問題)2)如果調用executor.submit()很多次而我沒有調用executor.shutdown(),則第一個submit()的調用會在繼續之前等待響應。也許我應該使用execute()來代替? – Bedo 2013-03-21 12:32:41

+0

請求是一個Callable,所以它應該是'countDown'鎖存器的'call'方法。計數到零時,鎖存器「await」將停止。看到我上面編輯的答案 – 2013-03-21 13:26:48

+0

好的非常感謝你!我會盡快嘗試! – Bedo 2013-03-22 07:28:36

0

如果您使用此程序來執行負載測試,或者甚至是其他情況,我強烈建議您使用Jmeter來代替。 Jmeter已經做了你正在嘗試做的事情,並且有許多插件可以讓你安排線程/時間段的負載/數量等。你也可以通過各種圖形監視所有的HTTP請求。

爲您的servlet編寫測試應該是take you less than 5 minutes。圖形也很容易生成。

jmeter graph

如果你仍然想使用自定義程序聯繫的servlet,你總是可以限制的請求數量,並將其備份與blocking queue through a threadpool executor

最後,不要修改該servlet。您應該能夠將其作爲黑匣子進行監控。