【編者的話】本文是「nginx應用效能優化指南」系列文章的第五篇,主要介紹了如何從吞吐量方面實現nginx應用效能優化。\
\ nginx反向**配置設定了兩個網路路徑:客戶端到**和**到伺服器。這兩個路徑不僅「http跨度(http spans)」不同,tcp網路傳輸域也不同。\
\ 尤其是提供大資源時,我們的目標是確保tcp充分利用了端到端連線。理論上講,如果tcp流同http資料緊密打包在一起,而且資料盡可能快地傳送出去,那麼我們就會獲得最大的吞吐量。\
\ tcp採用兩個基本原則決定何時傳送以及傳送多少資料:\
流量控制是為了確保接收者可以接收資料; \
擁塞控制是為了管理網路頻寬。
流量控制是通過接收者指定的接收視窗實現的,後者會規定接收者一次希望接收和儲存的最大資料量。這個視窗可能會變大——從幾個kb到若干mb——這取決於測得的連線頻寬延遲乘積(bdp,對此下文會有更多介紹)。\
擁塞控制是由傳送者實現為rwnd大小的乙個約束函式。傳送者會將它傳輸的資料量限制為cwnd和rwnd的最小值。可以將此看作是遵從「網路公平性」的一種自我約束。視窗大小(cwnd)會隨著時間增長,或者隨著傳送者接收到先前傳輸的資料的確認而增長。如果檢測到網路擁塞,那麼它也會縮小視窗。\
\ 同時,傳送者和接收者在決定最大可用tcp吞吐量時各自扮演乙個重要的角色。如果接收者的rwnd太小,或者傳送者對網路擁塞過於敏感或者對網路擁塞減退反應太慢,那麼tcp吞吐量都不會是最理想的。\
\ 網路連線通常以管道為模型。傳送者在一端幫浦入資料,接收者在另一端抽取資料。\
bdp(以kb或mb為單位)是位元率同rtt的乘積,是乙個表示需要多少資料填充管道的指標。例如,如果你在使用乙個100mbps的端到端連線,而rtt為80毫秒,那麼bdp就為1mb(100 mbps * 0.080 sec = 1 mb)。\
\ tcp會設法填充管道,並保證沒有管道洩露或破裂,因此,bdp是rwnd的理想值:tcp可以發出的最大動態(還沒有收到接收者的確認)資料量。\
假設有足夠的資料待傳送(大檔案),而且沒有什麼阻止傳送應用程式(nginx)以管道能夠接受的速度向管道幫浦入資料,rwnd和cwnd可能會成為實現最大吞吐量的限制因素。\
大多數現代tcp棧會使用tcp時間戳以及視窗縮放選項自動優化這些引數。但是舊系統不會,有些應用程式會出現異常行為。因此,有兩個明顯的問題:\
我如何檢查? \
我如何修復?
我們下面會處理第乙個問題,但是修復tcp涉及學習如何優化tcp棧——這本身就是一項全職工作。更可行的方案是tcp加速軟體或硬體。而且,這類**商非常多,包括我每天都在研究的產品supertcp。\
\ 設法確認rwnd或cwnd是否是限制因素,包括將它們同bdp進行比較。\
為此,我們會嗅探在(無頭)nginx**上使用tcpdump
工具進行大資源http(s)傳輸的資料報,並將捕獲的檔案載入到帶有圖形介面的機器上的wireshark中。然後,我們可以繪製乙個有意義的圖形,從而對這些基本變數是否得到了正確設定有一些了解。
如果你使用了乙個不同的捕獲過濾器,那麼只要確保它捕獲了tcp http對話的雙向資料。另外,還要確保是在傳送裝置上進行捕獲,因為我們需要使用wireshark正確地計算動態資料量。(在接收者一端進行捕獲會使wireshark相信rtt接近為0,因為接收者ack可能會在資料進來後立即傳送出去)。\
將http_get.pcap
檔案載入到wireshark中,找到感興趣的http流,然後仔細看下它的tcp.stream
索引:\
\ 開啟statistics-\u0026gt;io graph,並進行如下配置:\
graph 4 (blue)\
接下來,務必按下(啟用)graph 4和graph 5按鈕,根據那些結果進行繪圖。下面的例子可能是你期望看到的:\
\ 我使用乙個100mbps的連線從乙個80毫秒遠的nginx**上get乙個128mb的檔案(從aws奧勒岡州到我們在加拿大渥太華的辦公室)。相應的bdp為1mb。\
注意看下rwnd(粉色)的變化,開始時很小,數個往返後增長到稍稍超過1mb。這證明接收者能夠調整rwnd,並且可以察覺bdp(好極了)。或者,如果我們看到rwnd變小了(又稱為關閉中),那表明接收應用程式讀取資料的速度不夠快——也許沒有獲得足夠的cpu時間。\
對於傳送者的效能——cwnd(藍色)——我們想要乙個指徵,就是動態資料量會受到rwnd限制。我們看到,在3秒到6秒這個時間段裡,nginx**能夠發出的動態資料量是rwnd允許的最大資料量。這證明傳送者能夠推送足夠的資料以滿足bdp。\
不過,在快到6秒時,似乎有東西出現了大問題。傳送者發出的動態資料量顯著減少。自我約束行為通常是由傳送者檢測到擁塞引起的。回想一下,get響應從西海岸傳送到東海岸,遇到網路擁塞還是很可能的。\
\ 當傳送者檢測到擁塞,它會縮小cwnd,以便減少它對網路擁塞的貢獻。但是,我們如何才能知道?\
通常,tcp棧可以使用兩類指示器檢測或度量網路擁塞:資料報丟失和延遲變化(bufferbloat)。\
在同乙個wireshark io graph視窗中加入下列內容:\
另外將scale改為logarithmic
\ 瞧!證據有了,接收者傳送了重複ack,表明實際上有資料報丟失。這解釋了為什麼傳送者縮小了cwnd,即動態資料量。\
你可能還想尋找tcp.analysis.retransmission
出現的證據,當出現資料報丟失報告,資料報必須重發時,或者當傳送者等待來自接收者的ack超時時(假設資料報丟失或者ack丟失)。在後一種情況下,查下tcp.analysis.rto
。\
對於上述兩種情況,務必將filter設定為tcp.srcport=*\u0026lt;80|443\u0026gt;*,因為重傳源於傳送者。\
檢視英文原文:感謝郭蕾對本文的策劃和審校。
\
Android應用效能優化
記憶體,ui,電量 1.記憶體 首先簡單介紹一下android系統記憶體管理機制.記憶體共享 預設情況 string vmheapsize systemproperties.get dalvik.vm.heapsize 16m 只有16m.可以通過在device.mk檔案中設定 product pr...
Android應用效能優化
1 anr 2 listview 卡頓,不流暢 3 activity啟動慢 4 動畫不流暢,啟動前卡頓 5 自定義view啟動慢 6 oom 7 資料庫大量操作 8 長時間執行後,程式變慢 1 語言層解決問題,語法上提高效能 2 合理的資料結構和演算法 3 布局優化,布局深度控制 4 工作執行緒與u...
Web應用效能優化思路
瓶頸是什麼?一條4車道的公路,執行非常順暢,突然出了點事故,事故車導致某個地方只剩下1車道,然後就開始堵車,因為四輛車同時塞向乙個車道裡。把這個事故清除了,故障車拖走了,道路會開始恢復了通暢。這個道理誰都懂,但偏偏有些傻瓜交警去把4車道變成8車道,但卻不清理事故路段。乙個web應用,不管是何種語言開...