Nginx 效能優化

WBOY
發布: 2016-07-30 13:29:46
原創
1044 人瀏覽過

Nginx作為一個非常流行和成熟的Web Server和Reserve Proxy Server,網上有大量的性能優化教程,但是不同的業務場景千差萬別,什麼配置是最適合自己的,需要大量的測試和實踐以及不斷的優化改進。最近用戶呼叫量突破百萬大關之後,就遇到了一些問題,雖然不算太複雜,但也折騰了挺長時間才搞定,累積了不少經驗。

碰到的這個問題其實已經有一段時間了,有客戶給我們反饋調用超時,但是我們自己從系統監控上看都是正常的,只有幾十毫秒肯定不會超時,懷疑是不是網絡的原因,但是出現幾次後,就隱隱感覺這個問題可能不是偶發性的,應該還有深層的原因。

因為我們服務面向企業客戶的,雖然每家客戶的呼叫量可能會非常大,但每家企業客戶就那麼幾個公網IP,即使以後有上千家客戶,Nginx也可以輕鬆支撐這些並發連接。因此,首先從網路上對Nginx長連接作了優化,將長連接從原來配置的5秒鐘改成5分鐘,將每次建立連接請求的數目從預設的100調整到1000。

<code>keepalive_timeout  300;
keepalive_requests 1000;</code>
登入後複製

調整完畢後,透過netstat -anp指令可以看到,新連線請求會減少,說明長連線已發揮作用。但過了一段時間,仍然發現有客戶呼叫超時的情況發生,從Nginx日誌中可以看到請求時間還是有超過1s的,甚至有長達20s左右的,如下所示:


並且從Zabbix上的監控發現一個現象,當connection writing或active數突然增高時,請求時間就相應的出現較多超時:


查看應用的日誌,發現執行時間並不長:


應用程式裡統計的時間,只是從業務開始執行到執行結果的時間,這個還沒有算Tomcat容器的執行時間,外部請求的執行路徑如下:

<code>client --> Nginx -->  Tomcat --> App</code>
登入後複製

會不會是Tomcat容器本身執行有問題呢,把Tomcat請求的日誌呼叫出來,發現這個時間點前後的執行也是正常的:


從請求路徑上分析,肯定是Nginx到Tomcat這層存在一些問題。在排查這個問題的時候,突然發現有大量30s左右的超時,從Zabbix上也觀察到connection writing非常高,如下所示:


同時,發現TIME_WAIT的連接特別多,從現象及抓包分析結果來看,應該是有客戶沒有開啟長連接,而我們在服務端又設置了keepalive_timeout為5分鐘,導致大量使用過的連接等待超時,當時有接近2000個,編輯/etc/sysctl.conf文件,增加如下兩個參數重用連接:

<code>net.ipv4.tcp_tw_reuse = 1 #表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;
net.ipv4.tcp_tw_recycle = 1 #表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。</code>
登入後複製

生效之後很快下降到200以下,從Zabbix監控也看到,connection writing和connection active`都有明顯下降,但並沒有完全解決問題,還得找其它方面的原因。


Nginx的reqeust_time指的是從客戶端接收到第一個位元組算起,到呼叫後端的upstream server完成業務邏輯處理,並將傳回結果全部寫回客戶端為止的時間,那麼呼叫upstream server的時間如果能夠列印出來的話,就更容易將問題範圍縮小,幸運的是Nginx有兩個參數可以列印後端伺服器請求的時間和IP位址,在nginx.conf檔案中修改日誌的格式如下:

<code># $upstream_response_time 后端应用服务器响应时间
# $upstream_addr 后端服务器IP和端口号
log_format  main  '$remote_addr - [$time_local] "$request" '
                      '$status $body_bytes_sent '
                      '"$request_time" "$upstream_response_time" "$upstream_addr" "$request_body "';</code>
登入後複製

再觀察日誌,非常明顯地發現,大部分特別長的呼叫都來自同一台機器:


查看這台機器發現,雖然Java進程還在,但應用實際上已經當掉了,沒有真實的請求進來,將之從負載勻衡中摘掉,問題馬上得到緩解:


這台機器其實已經掛掉了,但為何Nginx沒有辨識到呢?進一步研究發現,Nginx在呼叫upstream server時,超時時間預設是60s,我們這些應用程式對回應時間要求非常高,超過1s已沒有意義,因此在nginx.conf檔案中修改預設的逾時時間,超過1s就返回:

<code># time out settings  
proxy_connect_timeout 1s;  
proxy_send_timeout   1s;  
proxy_read_timeout   1s;</code>
登入後複製
运行一段时间后,问题已基本得到解决,不过还是会发现request_time超过1s达到5s的,但upstream_response_time都没有超时了,说明上面的参数已起作用。

版权声明:本文为博主原创文章,未经博主允许不得转载。

以上就介绍了Nginx 性能优化,包括了方面的内容,希望对PHP教程有兴趣的朋友有所帮助。

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!