Java

Java胖客戶端連接到本地主機時速度慢,遠端速度快

  • November 16, 2010

我在連接到自定義數據庫伺服器的(通常)延遲綁定桌面 Java 應用程序時遇到問題。

雖然它在遠端主機(Windows XP)上工作,但速度很快(大窗體在 2 秒內打開)。當它在同一主機上執行時,數據庫處於打開狀態(使用 X11vnc 和 NX),它非常慢(相同的表單在大約 20 秒內打開)。伺服器正在執行 SuSE Linux Enterprise Server 10。

我檢查了什麼:

  • iptables是乾淨的(ACCEPT 上的所有表filterraw沒有mangle規則)nat
  • 路由正常(只是預設路由和本地網路)
  • 甚至沒有安裝 brtables
  • tc很乾淨
  • 對於 64 字節和 1500 字節數據包,到本地主機的 ping 延遲約為 0.007 毫秒,到遠端主機的延遲約為 0.8 毫秒
  • 環回吞吐量約為 500MiB/s(經測試netcat
  • 不同的 Java VM(1.5 和 1.6)

雖然看atop那裡似乎沒有任何瓶頸:

  • Java 和數據庫程序的 CPU 使用率非常低(Java:~20%,數據庫 <5%),遠端訪問時 CPU 使用率適中(數據庫約為 30%) 伺服器是四核 2.66Ghz,客戶端是一個 Core 2 Duo 2.33Ghz,除此之外的系統是空閒的
  • 在長查詢期間幾乎沒有任何磁碟讀取/寫入(總共大約 5-10 次讀取)

遠端和本地執行之間唯一不同的是網路使用率,而本地程序以大約 1200kbps 的速度提取數據,遠端以大約 15Mbps 的速度進行。

我目前正在用我的硬體複製問題,所以也歡迎任何關於這些行的提示。

編輯:將lo介面 MTU 從預設的 16k 更改為 1500 可以解決此問題。該問題已在 Debain lenny 64bit 上重複出現。

我為您提供的只是更多的調試想法,沒有特定的順序……

  • 真的是環回問題嗎?您是否嘗試連接到伺服器的網路 IP 地址而不是 127.0.0.1?(這使用了我係統上的環回介面,但它應該排除奇怪的 DNS 問題)
  • 在此期間系統負載是否很高(io 問題可能導致系統負載高於所有單個程序的總和)?
  • 檢查每個程序的 netstat 資訊,如果客戶端的 Recv-Q 很高,則客戶端程序沒有定期從其套接字讀取。
  • 嘗試觀察tcpdump -i lo,它可能有助於確定正在傳輸的數據包是否存在明顯的模式。
  • “vmstat 1”是否顯示遠端訪問與本地訪問版本截然不同的行為(即在數據庫伺服器和 java 客戶端中將數據集保存在 RAM 中,迫使您進行交換)?
  • 嘗試增加環回設備上的 MTU,我的預設值為 16436。如果您執行大量小數據包,這將無濟於事。小包似乎有自己的問題。我不是 Java 程序員,所以我不知道怎麼做,但嘗試在連接上設置 TCP_NODELAY(setsockopt 系統呼叫)。這個似乎有一個貨物狂熱追隨者,但據說如果通信是單向的,客戶端將更頻繁地響應 TCP ACK 並保持數據流動。
  • 嘗試調整的另一件事:echo 1 &gt; /proc/sys/net/ipv4/tcp_low_latency
  • 在玩 setsockopt 時,看看如果增加客戶端的發送和接收緩衝區會發生什麼?
  • 你不是在使用某種古老的 2.2 核心嗎?根據 2.4 TODO,顯然在 2.3.x 中修復了某種巨大的環回錯誤
  • 也許客戶端(或Java)中存在錯誤,您是否在具有相同Java執行時的單獨Linux系統上執行完全相同的客戶端?

這聽起來很奇怪,但它在不久前對我有用。
檢查 /etc/hosts 文件以使您的主機名與 localhost 一致,或者添加一個指向 127.0.0.1 或偵聽的主機名。

引用自:https://serverfault.com/questions/189784