線上上環境中我們是採用了tomcat作為Web伺服器,它的處理效能直接關係到使用者體驗,在平時的工作和學習中,歸納出以下七種調優經驗。
1. 伺服器資源
伺服器所能提供CPU、記憶體、硬碟的效能對處理能力有決定性影響。
(1) 對於高並發情況下會有大量的運算,那麼CPU的速度會直接影響到處理速度。
(2) 記憶體在大量資料處理的情況下,將會有較大的記憶體容量需求,可以用-Xmx -Xms -XX:MaxPermSize等參數對記憶體不同功能塊進行劃分。我們之前就遇到過記憶體配置不足,導致虛擬機器一直處於full GC,從而導致處理能力嚴重下降。
(3) 硬碟主要問題就是讀寫效能,當大量檔案進行讀寫時,磁碟極容易成為效能瓶頸。最好的辦法還是利用下面提到的緩衝。
2. 利用緩衝和壓縮
對於靜態頁面最好是能夠緩衝起來,這樣就不必每次從磁碟上讀。這裡我們採用了Nginx作為快取服務器,將圖片、css、js檔案都進行了緩衝,有效減少了後端tomcat的訪問。
另外,為了能加快網路傳輸速度,開啟gzip壓縮也是必不可少的。但考慮到tomcat已經需要處理很多東西了,所以把這個壓縮的工作就交給前端的Nginx來完成。可以參考之前寫的《利用nginx加速web訪問》。
除了文本可以用gzip壓縮,其實很多圖片也可以用影像處理工具預先進行壓縮,找到一個平衡點可以讓畫質損失很小而檔案可以減小很多。曾經我就見過一個圖片從300多kb壓縮到幾十kb,自己幾乎看不出來區別。
3. 採用叢集
單個伺服器效能總是有限的,最好的辦法自然是實現橫向擴充,那麼組建tomcat叢集是有效提升效能的手段。我們還是採用了Nginx來作為請求分流的伺服器,後端多個tomcat共用session來協同工作。可以參考之前寫的《利用nginx+tomcat+memcached組建web伺服器負載平衡》。
4. 最佳化tomcat參數
這裡以tomcat7的參數配置為例,需要修改conf/server.xml檔案,主要是最佳化串連配置,關閉用戶端dns查詢。
- <Connector port="8080"
- protocol="org.apache.coyote.http11.Http11NioProtocol"
- connectionTimeout="20000"
- redirectPort="8443"
- maxThreads="500"
- minSpareThreads="20"
- acceptCount="100"
- disableUploadTimeout="true"
- enableLookups="false"
- URIEncoding="UTF-8" />
5. 改用APR庫
tomcat預設採用的BIO模型,在幾百並發下效能會有很嚴重的下降。tomcat內建還有NIO的模型,另外也可以調用APR的庫來實現作業系統層級控制。
NIO模型是內建的,調用很方便,只需要將上面設定檔中protocol修改成org.apache.coyote.http11.Http11NioProtocol,重啟即可生效。上面配置我已經改過了,預設的是HTTP/1.1。
APR則需要安裝第三方庫,在高並發下會讓效能有明顯提升。具體安裝辦法可以參考http://www.cnblogs.com/huangjingzhou/articles/2097241.html。安裝完成後重啟即可生效。如使用預設protocal就是apr,但最好把將protocol修改成org.apache.coyote.http11.Http11AprProtocol,會更加明確。
在官方找到一個表格詳細說明了這三種方式的區別:
- Java Blocking Connector Java Nio Blocking Connector APR/native Connector
- BIO NIO APR
- Classname AjpProtocol AjpNioProtocol AjpAprProtocol
- Tomcat Version 3.x onwards 7.x onwards 5.5.x onwards
- Support Polling NO YES YES
- Polling Size N/A maxConnections maxConnections
- Read Request Headers Blocking Sim Blocking Blocking
- Read Request Body Blocking Sim Blocking Blocking
- Write Response Blocking Sim Blocking Blocking
- Wait for next Request Blocking Non Blocking Non Blocking
- Max Connections maxConnections maxConnections maxConnections
6. 最佳化網路
Joel也明確提出了最佳化網卡驅動可以有效提升效能,這個對於叢集環境工作的時候尤為重要。由於我們採用了linux伺服器,所以最佳化核心參數也是一個非常重要的工作。給一個參考的最佳化參數:
- 1. 修改/etc/sysctl.cnf檔案,在最後追加如下內容:
-
- net.core.netdev_max_backlog = 32768
- net.core.somaxconn = 32768
- net.core.wmem_default = 8388608
- net.core.rmem_default = 8388608
- net.core.rmem_max = 16777216
- net.core.wmem_max = 16777216
- net.ipv4.ip_local_port_range = 1024 65000
- net.ipv4.route.gc_timeout = 100
- net.ipv4.tcp_fin_timeout = 30
- net.ipv4.tcp_keepalive_time = 1200
- net.ipv4.tcp_timestamps = 0
- net.ipv4.tcp_synack_retries = 2
- net.ipv4.tcp_syn_retries = 2
- net.ipv4.tcp_tw_recycle = 1
- net.ipv4.tcp_tw_reuse = 1
- net.ipv4.tcp_mem = 94500000 915000000 927000000
- net.ipv4.tcp_max_orphans = 3276800
- net.ipv4.tcp_max_syn_backlog = 65536
-
- 2. 儲存退出,執行sysctl -p生效
7. 讓測試說話
最佳化系統最忌諱的就是只調優不測試,有時不適當的最佳化反而會讓效能更低。以上所有的最佳化方法都要在本地進行效能測試過後再不斷調整參數,這樣最終才能達到最佳的最佳化效果。
補充Bio、Nio、Apr模式的測試結果:
對於這幾種模式,我用ab命令類比1000並發測試10000詞,測試結果比較意外,為了確認結果,我每種方式反覆測試了10多次,並且在兩個伺服器上都測試了一遍。結果發現Bio和Nio效能差別非常微弱,難怪預設居然還是Bio。但是採用apr,串連建立的速度會有50%~100%的提升。直接叫用作業系統層果然神速啊,這裡強烈推薦apr方式!
參考資料:
http://16.199.geisvps.com/bbs/2836/24238.html