1. 程式人生 > >Nginx與Tomcat效能調優,前後端KeepAlive不同步引發的問題

Nginx與Tomcat效能調優,前後端KeepAlive不同步引發的問題

在http1.1中可以配置伺服器端開啟keepalive與客戶端保持長連線進行優化,這裡不過多解釋。

我們在nginx.conf配置

    upstream favtomcat {
       server 192.168.80.112:8080;
       keepalive 20;
    }
keepalive_timeout  65s;
keepalive_requests 100;

keepalive_timeout:65s ##設定nginx開啟keepalive,超時時間為65秒,也就是說:如果客戶端65秒內沒有後續的請求過來,nginx就會斷掉這個TCP連線,設定為0表示禁用keepalive。

keepalive_requests :100 ##設定長連線能夠處理請求的次數,100表示:一個長連線nginx最多處理100次請求就會關閉。

keepalive : 20 ##這個值必須設定,預設為0. 設定每個worker可以保持長連線空閒時的最大連線數。

這裡需要特別解釋一下,假設nginx有100個請求需要訪問Tomcat,那麼會建立100個連線,如果雙方都支援keepalive,那麼這100個連線都是長連線(可以複用那種的),當請求結束後,nginx會立馬銷燬 80個(100-20),只剩下20個長連線,這20個長連線在Tomcat的keepAliveTimeout時間到期後由Tomcat方關閉。

Tomcat的 keepAliveTimeout這個值可以設定大一些,效能會很好,比如設定個10分鐘,20分鐘的。

完事大吉,我們來測試。

192.168.80.110 Nginx

192.168.80.112 Tomcat

192.168.80.1  客戶端Chrome瀏覽器

我們在瀏覽器瘋狂重新整理Nginx ,為了讓瀏覽器啟動最多的連線,我放了一大推的圖片,並且圖片URL後面加隨機數,防止瀏覽器快取。

接下來我們通過命令 netstat -ntp | grep nginx 檢視伺服器TCP連線的情況,後面加了grep nginx是隻看nginx的tcp連線。

可以看到瀏覽器啟動了6個TCP連線來與載入資源,無論我們怎麼重新整理,連線數都不會變,這就是因為使用了Keeplive,所有的連線可以進行復用(請求多個資源),如果把nginx的keepalive設定為0,每次重新整理都會使用新的TCP連線,這裡會出現大量TIME-WAIT的連線。

上圖可以看到,客戶端已經與nginx啟動了keepalive,複用TCP連線,起到了很大優化,看起來似乎很完美,但是讓我們在tomcat的伺服器上看看tcp連線情況。 我們使用命令 netstat -ntp  

192.168.80.112 tomcat伺服器上的截圖,我只截取了一部分,實際出現大量的TIME_WAIT的tcp連線。也就是說 客戶端與nginx連線時確實是用了keeplive,但是nginx與tomcat的連線卻沒有啟動keeplive,每一次請求都新建一個tcp,用完一次就關閉沒有複用,所以出現了大量的TIME_WAIT的TCP連線,如果流量稍微大一些tomcat伺服器會因為tcp資源耗盡而宕機。

問題已經發現了,那麼如何去解決這個問題呢~,首選要找出問題出現的原因。

1、為什麼nginx與tomcat的連線是短連線而不是keepalive長連線?

下圖是nginx官網上的一段話,說需要設定proxy_http_version為1.1 並且 Connection 頭需要清空,也就是說nginx與tomcat之間是使用http1.0的短連線模式進行通訊的。

讓我們通過抓包工具來分析一下nginx與tomcat到底是不是使用http1.0短連線模式通訊的。

可以看到80.1瀏覽器請求80.110nginx使用的是http1.1,而nginx請求tomcat使用的是1.0.

我們看192.168.80.1 到 192.168.80.110的包,使用http1.1,並且設定了keepalive頭。

我們再來看192.168.80.110 到 192.168.80.112的包,使用的是http1.0  並且connection 設定了close,告訴tomcat 連線只用一次,用完即關。

通過上述分析,我們知道了 nginx代理tomcat預設使用http1.0短連線模式,挺坑啊,為什麼不直接使用1.1呢。

接下來我們把配置檔案加上,在看看效果,記得重啟nginx,可以看到通訊已經使用了http1.1 的keeplive模式了。

我們在重新測試瘋狂重新整理我們的頁面,每個幾秒重新整理1次,重新整理5次試試看。

我們在nginx上檢視tcp連線情況,一共12個tcp連線,其中6個是客戶端與nginx的,另外6個是nginx與tomcat的。

我們在tomcat上檢視tcp的連線情況。可以看到一共6個與nginx的tcp連線。這樣我們nginx與tomcat也是keepalive長連線了。

netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'

通過shell統計tcp各種狀態的數量