2014-06-26 19 views
1

在構建HTTP Web服務器的上下文中......我們理解,理論上,爲每個請求創建和銷燬線程相對昂貴,並且不能很好地擴展。這是常識(或者我希望是這樣)。線程池是這裏的解決方案......但我有點想在低層理解事情,而不是簡單地接受理論爲真。如何配置線程生命週期性能

當然,我們才能用JMeter看到一個應用程序可能如何負載下運行進行黑箱測試,但如果我想實際觀察爲什麼會發生什麼? Profiler工具可以告訴我爲什麼線程分配每個請求的成本高昂嗎?

謝謝!

回答

1

如果你想自己測量,你可以這樣做。

當這種智慧被發現時,很可能很久以前,創建線程要貴得多。例如在Linux上,每個線程都是一個新進程。

「昂貴」對不同的應用程序意味着不同的東西。如果系統中的每個請求都需要很長時間,那麼添加毫秒就不會有太大的區別。如果每個請求都需要幾毫秒,那麼爲啓動線程添加一個毫秒就非常糟糕。

import java.util.ArrayList; 
import java.util.List; 

public class ThreadRestarterMain { 
    public static void main(String... ignored) throws InterruptedException { 
     long start = System.currentTimeMillis(); 
     // time how long it takes to start a few threads and stop them again. 
     int threads = 2000; 
     List<Thread> threadList = new ArrayList<>(); 
     while (threadList.size() < threads) { 
      Thread e = new Thread(new Runnable() { 
       @Override 
       public void run() { 
        Thread.yield(); 
       } 
      }); 
      e.start(); 
      threadList.add(e); 
     } 
     for (Thread thread : threadList) { 
      thread.join(); 
     } 
     long time = System.currentTimeMillis() - start; 
     System.out.printf("Took %.3f ms on average to start/stop a thread%n", (double) time/threads); 
    } 
} 

這將打印像

Took 0.055 ms on average to start/stop a thread 

只有你知道這是一個很大的數字。

注意:如果你有線程本地資源,這可以使這個時間更長。這又取決於你在做什麼。

1

Web服務器彙集線程,這意味着稍後的請求可能使用完全相同的線程,這可以通過Thread.currentThread()。getId()獲取線程ID來觀察。不應該擔心太多,但如果您打算從servlet或過濾器創建自己的線程,請不要。這可能會導致DOS攻擊和服務器氾濫。你應該能夠通過一個servlet過濾器來添加監視功能,這將允許你在當前線程上獲取統計信息並做一些基本的性能統計。

1

前段時間我有一個類似的任務。我們決定堅持JMeter,但也添加了日誌到我們的代碼。我們簡單地記錄了處理我們代碼中懷疑瓶頸的特定部分花費的時間。然後我們運行JMeter讓我們的系統處於負載狀態。

這樣你就不能觀察你的所有代碼,但至少可以看到它的不同部分。

我不認爲這個解決方案很漂亮,但你可能有一個想法如何改善它。