關注此主題。 Streaming large files in a java servlet。通過Java查找服務器的互聯網帶寬流式傳輸
是否有可能通過java找到當前機器可用的總互聯網帶寬?
我想要做的是通過servlet傳輸大文件,基於並行請求的數量和總帶寬,我試圖減少每個請求的流的BUFFER_SIZE。合理?
有沒有純java的方法? (沒有JNI)
關注此主題。 Streaming large files in a java servlet。通過Java查找服務器的互聯網帶寬流式傳輸
是否有可能通過java找到當前機器可用的總互聯網帶寬?
我想要做的是通過servlet傳輸大文件,基於並行請求的數量和總帶寬,我試圖減少每個請求的流的BUFFER_SIZE。合理?
有沒有純java的方法? (沒有JNI)
也許你可以花時間多久應用程序需要發送一個包(緩衝區)。如果這大於x毫秒,則使緩衝區更小。您可以使用原始bufferSize
和if (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();
找到可用帶寬的唯一方法是監視/測量它。在Windows上,您可以訪問Net.exe並獲得每個NIC上的吞吐量。
如果您通過servlet提供內容,那麼您可以計算每個servlet輸出流的運行速度。爲用戶/會話收集所有數據流的數據,並且至少可以確定當前的帶寬使用情況。
計算速率的一種可能方式可能不是通過servlet output stream寫入大文件,而是寫入新的FilterOutputStream,以便記錄下載速率。
「當前機器上可用的全部互聯網帶寬」的概念很難定義。但是,調整本地緩衝區大小不會影響您可以推送到單個客戶端的數據量。
給定客戶端可以從服務器獲取數據的速率會隨客戶端和時間而變化。對於任何給定的連接,您可能受到本地上行連接到Internet的限制(例如,DSL上的服務器),或者您可能受限於核心(不太可能)或遠程端(例如數據中心中的服務器,客戶端在撥號線上)。當你有很多連接時,每個連接可能會有不同的瓶頸。衡量這個可用帶寬是一個難題;請參閱關於此主題的此列表research and tools。一般來說,TCP將公平地使用所有可用的帶寬來處理任何給定的連接(儘管有時它可能會對可用帶寬的變化作出反應,而不是你喜歡的)。如果客戶端無法處理更多數據,寫入呼叫將被阻止。
如果您發現您看到低帶寬並且導致數據緩衝寫入網絡的原因不足,則只需調整鏈接問題中的buffersize即可。您可能會調整緩衝區大小的另一個原因是,如果您有太多的活動連接,並且內存不足。
在任何情況下,真正的答案可能不是緩衝,而是將您的靜態文件放在單獨的服務器上,並使用類似thttpd的東西來爲它們服務(使用系統調用如sendfile)而不是servlet。這有助於確保瓶頸不在您的服務器上,而是在互聯網中的某個地方,不受您的控制。
編輯:重新閱讀這個,它有點混亂,因爲它在這裏遲到了。基本上,你不應該從頭開始做這件事;使用現有的高度可擴展的Java服務器之一,因爲他們會做得更好,更容易。
你不會喜歡這一點,但它實際上沒有意義,這裏的原因:
的幫助這個是我,我就開始看/使用NIOØ復我。你幾乎可以肯定找到一個圖書館來爲你做這件事。 IBM的文章here可能是一個有用的起點。
我認爲聰明的錢給你一個網絡I/O線程和一個磁盤I/O線程,多路複用。每個連接都會從池中請求緩衝區,並使用數據(來自共享網絡或磁盤流或通道)填充數據,對其進行處理,然後將緩衝區返回到池以供重用。不需要調整緩衝區大小,只需要等待每個數據塊。如果您希望延遲保持不變,那麼請限制一次可以激活多少次傳輸,並排隊其他傳輸。
基於純Java的方式 – Madhu 2009-09-29 05:14:48
**這**是一個正確的答案,請回答。沒有純粹的Java方法! – 2010-07-01 11:48:40