Nginx性能優化

jopen 9年前發布 | 13K 次閱讀 Nginx Web服務器

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

</blockquote>

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

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

keepalive_timeout  300;
keepalive_requests 1000;

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

Nginx性能優化

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

Nginx性能優化

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

Nginx性能優化

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

client --> Nginx -->  Tomcat --> App

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

Nginx性能優化

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

Nginx性能優化

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

net.ipv4.tcp_tw_reuse = 1 #表示開啟重用。允許將TIME-WAIT sockets重新用于新的TCP連接,默認為0,表示關閉;
net.ipv4.tcp_tw_recycle = 1 #表示開啟TCP連接中TIME-WAIT sockets的快速回收,默認為0,表示關閉。

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

Nginx性能優化

Nginx的reqeust_time指的是從客戶端接收到第一個字節算起,到調用后端的upstream server完成業務邏輯處理,并將返回結果全部寫回到客戶端為止的時間,那么調用upstream server的時間如果能夠打印出來的話,就更容易將問題范圍縮小,幸運的是Nginx有兩個參數可以打印后端服務器請求的時間和IP地址,在 nginx.conf文件中修改日志的格式如下:

# $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 "';</pre></div>

再觀察日志,非常明顯地發現,大部分特別長的調用都來自同一臺機器:

Nginx性能優化

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

Nginx性能優化

這臺機器其實已經掛掉了,但為何Nginx沒有識別到呢?進一步研究發現,Nginx在調用upstream server時,超時時間默認是60s,我們這些應用對響應時間要求非常高,超過1s已沒有意義,因此在nginx.conf文件中修改默認的超時時間, 超過1s就返回:

# time out settings  
proxy_connect_timeout 1s;  
proxy_send_timeout   1s;  
proxy_read_timeout   1s;

運行一段時間后,問題已基本得到解決,不過還是會發現request_time超過1s達到5s的,但upstream_response_time都沒有超時了,說明上面的參數已起作用,根據我的理解,request_time比較長的原因可能跟客戶那邊接收慢有關系,不過這個問題最終還需要下周等客戶改為長連接才能確認。

yikebocai /2014-10-25

來自:http://yikebocai.com/2014/10/nginx-performance-tunning/

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!