tomcat優化之Http請求壓縮
HTTP 壓縮可以大大提高瀏覽網站的速度,它的原理是,在客戶端請求網頁後,從伺服器端將網頁檔案壓縮,再下載到客戶端,由客戶端的瀏覽器負責解壓縮並瀏覽。相對於普通的瀏覽過程HTML ,CSS,Javascript , Text ,它可以節省40%左右的流量。更為重要的是,它可以對動態生成的,包括CGI、PHP , JSP , ASP , Servlet,SHTML等輸出的網頁也能進行壓縮,壓縮效率驚人。
下面對同一個請求進行測試。
這是壓縮前的請求:
這是壓縮後的請求:
兩次請求都是在禁用快取的情況下訪問專案上的個人工作臺頁面,可以看到開啟壓縮之後,請求的資源被大幅減少了,提升非常明顯。
開啟Gzip
開啟tomcat的Gzip只需要找到 tomcat/conf 路徑下面的server.xml檔案,在Connector內新增如下紅色部分的4個引數:
<Connector port="80"protocol="HTTP/1.1" connectionTimeout="20000" minSpareThreads="100" maxThreads="1000" maxSpareThreads="500" acceptCount="700" keepAliveTimeout="0" redirectPort="8443"URIEncoding="UTF-8" compression="on"compressionMinSize="2048" noCompressionUserAgents="gozilla,traviata" compressableMimeType="text/html,text/xml,application/javascript,text/javascript,text/css,text/plain,text/json"/>
1. compression這個引數指定開啟Gzip壓縮,預設為off;
2. compressionMinSize,當被壓縮物件的大小>=該值時才會被壓縮,這裡預設為2KB,對資源壓縮時會消耗一定的cpu效能,對2KB以上的資源才進行壓縮是官方給出的建議,實際使用時可以根據需求在響應時間和cpu效能之間做取捨;
3. noCompressionUserAgents,指定以下瀏覽器不啟用壓縮;
4. compressableMimeType,指定對以下型別的資原始檔進行壓縮。
Gzip無法壓縮48k以上的資源?
提升Tomcat效能方法有很多種,使用NIO Connector和啟用gzip壓縮是其中兩種。
NIO:Java New IO,使用了多路複用的技術,無疑要比普通的IO socket要高效。
gzip:對需要傳輸到前臺的內容首先在記憶體中進行gzip壓縮,這樣可以大大的減少網路頻寬佔用。前提是前臺的Accept-Encoding允許gzip。
但是,當同時配置了這兩個時,會發現大於48KB的檔案並沒有進行壓縮。
經查Tomcat原始碼,發現org.apache.catalina.servlets.DefaultServlet中:
此處的sendfileSize = 48*1024,預設值為48KB,可以發現,當檔案大小大於48KB時,Tomcat並未馬上將內容寫回到output中,而是把檔案的路徑記錄下來。
並在Http11Processor的process方法的最後一部分,把檔案內容以FileChannel的形式寫回到前臺,不需要先把檔案內容先讀到使用者記憶體->壓縮->寫回socket核心記憶體。
這種NIO底層讀寫channel的形式避免了讀取到使用者記憶體的開銷,也可以提升效能。
目前,尚不清楚使用NIO快,還是gzip較快,有待測試。
如果在使用NIO的同時還一定要用gzip,可以關閉NIO Connector的useSendFile選項。
<Connector port="80"protocol="HTTP/1.1"
connectionTimeout="20000"
minSpareThreads="100"
maxThreads="1000"
maxSpareThreads="500"
acceptCount="700"
keepAliveTimeout="0"
redirectPort="8443"URIEncoding="UTF-8"
compression="on"compressionMinSize="2048" noCompressionUserAgents="gozilla,traviata" compressableMimeType="text/html,text/xml,application/javascript,text/javascript,text/css,text/plain,text/json"/>