2009-08-04 46 views

回答

6

也許你可以花時間多久應用程序需要發送一個包(緩衝區)。如果這大於x毫秒,則使緩衝區更小。您可以使用原始bufferSizeif (stop - start > 700)的其他值。

這是基於你注意到線程:

ServletOutputStream out = response.getOutputStream(); 
InputStream in = [ code to get source input stream ]; 
String mimeType = [ code to get mimetype of data to be served ]; 
int bufferSize = 1024 * 4; 
byte[] bytes = new byte[bufferSize]; 
int bytesRead; 

response.setContentType(mimeType); 

while ((bytesRead = in.read(bytes)) != -1) { 
    long start = System.currentTimeMillis(); 
    out.write(bytes, 0, bytesRead); 
    long stop = System.currentTimeMillis(); 
    if (stop - start > 700) 
    { 
     bufferSize /= 2; 
     bytes = new byte[bufferSize]; 
    } 
} 

// do the following in a finally block: 
in.close(); 
out.close(); 
0

找到可用帶寬的唯一方法是監視/測量它。在Windows上,您可以訪問Net.exe並獲得每個NIC上的吞吐量。

+0

基於純Java的方式 – Madhu 2009-09-29 05:14:48

+2

**這**是一個正確的答案,請回答。沒有純粹的Java方法! – 2010-07-01 11:48:40

0

如果您通過servlet提供內容,那麼您可以計算每個servlet輸出流的運行速度。爲用戶/會話收集所有數據流的數據,並且至少可以確定當前的帶寬使用情況。

計算速率的一種可能方式可能不是通過servlet output stream寫入大文件,而是寫入新的FilterOutputStream,以便記錄下載速率。

0

「當前機器上可用的全部互聯網帶寬」的概念很難定義。但是,調整本地緩衝區大小不會影響您可以推送到單個客戶端的數據量。

給定客戶端可以從服務器獲取數據的速率會隨客戶端和時間而變化。對於任何給定的連接,您可能受到本地上行連接到Internet的限制(例如,DSL上的服務器),或者您可能受限於核心(不太可能)或遠程端(例如數據中心中的服務器,客戶端在撥號線上)。當你有很多連接時,每個連接可能會有不同的瓶頸。衡量這個可用帶寬是一個難題;請參閱關於此主題的此列表research and tools。一般來說,TCP將公平地使用所有可用的帶寬來處理任何給定的連接(儘管有時它可能會對可用帶寬的變化作出反應,而不是你喜歡的)。如果客戶端無法處理更多數據,寫入呼叫將被阻止。

如果您發現您看到低帶寬並且導致數據緩衝寫入網絡的原因不足,則只需調整鏈接問題中的buffersize即可。您可能會調整緩衝區大小的另一個原因是,如果您有太多的活動連接,並且內存不足。

在任何情況下,真正的答案可能不是緩衝,而是將您的靜態文件放在單獨的服務器上,並使用類似thttpd的東西來爲它們服務(使用系統調用如sendfile)而不是servlet。這有助於確保瓶頸不在您的服務器上,而是在互聯網中的某個地方,不受您的控制。

0

編輯:重新閱讀這個,它有點混亂,因爲它在這裏遲到了。基本上,你不應該從頭開始做這件事;使用現有的高度可擴展的Java服務器之一,因爲他們會做得更好,更容易。

你不會喜歡這一點,但它實際上沒有意義,這裏的原因:

  • 總帶寬是獨立的連接數(雖然有一些小的開銷),所以與緩衝區大小混合將無濟於事
  • 無論如何,你的數據塊被分解爲可變大小的數據包。您的網卡和協議將比您的servlet更好地處理此問題
  • 定期調整緩衝區的大小非常昂貴 - 遠遠好於從固定大小的池中重新使用常量緩衝區,並且所有連接都爲I/O權限排隊等待
  • 有一個十億半庫,用這種服務器

的幫助這個是我,我就開始看/使用NIOØ復我。你幾乎可以肯定找到一個圖書館來爲你做這件事。 IBM的文章here可能是一個有用的起點。

我認爲聰明的錢給你一個網絡I/O線程和一個磁盤I/O線程,多路複用。每個連接都會從池中請求緩衝區,並使用數據(來自共享網絡或磁盤流或通道)填充數據,對其進行處理,然後將緩衝區返回到池以供重用。不需要調整緩衝區大小,只需要等待每個數據塊。如果您希望延遲保持不變,那麼請限制一次可以激活多少次傳輸,並排隊其他傳輸。

相關問題