網站資源偶爾延遲:頻寬上限導致丟包?
我的網站載入速度比我想像的要慢,因為一些資產需要很長時間才能從伺服器下載。我一直在努力追查造成這種情況的原因。由於我所做的測試(見下文),我大約 95% 確定這是網路問題,而不是 Apache 問題。
這是Firefox 網路檢查器的螢幕截圖。請注意,卡住的資產通常是其中一些圖像,但它也發生在其他資產上,如 Javascript 文件等。
假設和問題
我目前的理論是,當瀏覽器並行下載資源時,我們的 colo 的頻寬限制會導致封包遺失,可能會暫時超過頻寬限制。這是一個合理的理論嗎?除了請求更多頻寬之外,我們還有什麼可以改變的,即使我們大部分時間都沒有使用大部分頻寬?
或者,我還需要研究其他途徑嗎?
配置
- Fedora 18 上的 Apache 2.4.3,具有大量可用容量的 CPU 和記憶體。
- 通過託管設施將千兆乙太網連接到 4 或 5 Mbps 上行鏈路的交換機。
- 這不是一個流量很高的網站。一次很少有超過幾個訪客。
我做過的測試
traceroute
到伺服器就好了。traceroute
從伺服器到,比如說,我們的辦公室確實在 8 次左右跳後停止。我假設這是由於traceroute
流量在某處被阻塞(因為類似wget
——見下文——並且ssh
似乎在很大程度上工作正常),但如果這是相關的,我可以提供更多細節。strace
on Apache 表明伺服器立即提供整個圖像,沒有延遲。tcpdump
/wireshark
表示圖像數據立即發送,但隨後,一些數據包被重新傳輸。特別是一條痕跡表明,該資產的最終數據包被伺服器立即傳輸,重新傳輸了幾次,但原始數據包是瀏覽器最終收到的數據包。- 雖然我有時可以通過 重現下載頁面的問題
wget
,但它並沒有像在瀏覽器中那樣經常發生。我的假設是,這是因為wget
沒有並行下載。- 測試
iperf
很有趣。使用iperf
的 UDP 模式,我發現在高達 4 Mbps 的速度下我幾乎沒有丟包。除此之外,我開始看到約 10% 的封包遺失。類似地,在 TCP 模式下,少量並行連接在它們之間合理地分配頻寬。另一方面,6 個或更多並行連接開始獲得“鋸齒”頻寬模式,其中一個連接有時會具有頻寬,而其他時候則沒有。我很樂意提供有關其中任何一個的更多詳細資訊,但我不想在這篇文章中加入無關緊要的細節。我幾乎沒有足夠的網路知識來了解哪些資訊有用,哪些資訊沒有用。:-D 任何指向其他優秀網路故障排除工具的指針都會膨脹。
**編輯 1:**澄清了我幾乎可以肯定 Apache 不是罪魁禍首,而是網路某些東西或其他東西。
**編輯 2:**我在同一個千兆交換機上嘗試
iperf
了這台伺服器和我們的另一台伺服器,並獲得了相當一致的 940+ Mbits/s。我認為這排除了我們端的大多數硬體問題或雙工不匹配,也許除了上行鏈路。**編輯 3:**雖然細節非常不同,但這篇關於 TCP incast問題的文章聽起來非常相似,因為高頻寬流量在小突發中順著窄管道移動並失去數據包。我需要更詳細地閱讀它,看看是否有任何細節適用於我們的情況。
終於找到了罪魁禍首。我們的 colo 正在對我們的連接進行流量整形——當他們關閉它時,問題就完全消失了。我希望我們會做進一步的工作來縮小他們的配置範圍,但令人高興的是,這不是我們的配置。
您是否嘗試過在 Apache 前面放置一個代理來記憶體數據?一個流行的解決方案是 Nginx,它將在埠 80 上進行監聽(這意味著如果 Apache 也使用 80,您必須更改其監聽埠)。
只需將其設置為 Nginx 提供靜態內容,如 JS、CSS、圖像等……並通過代理將其他所有內容傳遞給 Apache。
我注意到當我為我的網站執行此操作時,它提高了相當多的性能,因為 Nginx 被建構為代理或獨立伺服器 IIRC,而當代理不是很流行時,Apache 更像是以前的 Web 伺服器的一個分支(如果甚至想到)。