使用Cache-Control和gzip提升tomcat應用效能(整理)
這個其實應該是常識,只不過以前做的J2EE應用大部分是內網裡跑的東西,所以效能上沒什麼問題。這次APIS由於有在外面用的可能,加上使用了一些比較大的javascript框架(Ext),所以效能問題瞬間竄了上來。
以前做的J2EE應用沒有使用上達500K的框架,最多就是幾十K的Prototype,所以沒什麼問題。一個頁面一般也就幾十K最多了。但這次還在開發中的APIS,由於還在用debug版本的庫,所以單單Ext就膨脹到了一個多M,加上不知道是Struts還是Tomcat預設寫入Response的cache-control:
no cache,在遠端用起來就很慢,一般一個頁面需要十多秒種甚至更久,實在無法忍受。前幾天集中解決了問題。
首先是Cache-Control的問題,Google了好一陣,沒有什麼直接配置的方法,只好自己抄了一個一個Filter,通過和web.xml裡配置的配合勉強湊合著用。一般就是對*.do實施no-cache政策,其他需要快取的img,
js檔案,統統加上長達兩週的快取期限。ETag實在不會用,就先用這個快取策略吧。
Filter的程式碼:
- publicclass ResponseHeaderFilter implements Filter {
- FilterConfig fc;
- publicvoid doFilter(ServletRequest req, ServletResponse res,
- FilterChain chain) throws IOException, ServletException {
- HttpServletResponse response = (HttpServletResponse) res;
- // set the provided HTTP response parameters
- for (Enumeration e = fc.getInitParameterNames(); e.hasMoreElements();) {
- String headerName = (String) e.nextElement();
- response.addHeader(headerName, fc.getInitParameter(headerName));
- }
- // pass the request/response on
- chain.doFilter(req, response);
- }
- publicvoid init(FilterConfig filterConfig) {
- this.fc = filterConfig;
- }
- publicvoid destroy() {
- this.fc = null;
- }
- }
web.xml裡的巧妙配置:
- <filter>
- <filter-name>NoCache</filter-name>
- <filter-class>apis.server.common.util.ResponseHeaderFilter</filter-class>
- <init-param>
- <param-name>Cache-Control</param-name>
- <param-value>no-cache, must-revalidate</param-value>
- </init-param>
- </filter>
- <filter>
- <filter-name>CacheForWeek</filter-name>
- <filter-class>apis.server.common.util.ResponseHeaderFilter</filter-class>
- <init-param>
- <param-name>Cache-Control</param-name>
- <param-value>max-age=604800, public</param-value>
- </init-param>
- </filter>
- <filter-mapping>
- <filter-name>NoCache</filter-name>
- <url-pattern>*.do</url-pattern>
- </filter-mapping>
- <filter-mapping>
- <filter-name>CacheForWeek</filter-name>
- <url-pattern>/images/*</url-pattern>
- </filter-mapping>
- <filter-mapping>
- <filter-name>CacheForWeek</filter-name>
- <url-pattern>/img/*</url-pattern>
- </filter-mapping>
- <filter-mapping>
- <filter-name>CacheForWeek</filter-name>
- <url-pattern>/icons/*</url-pattern>
- </filter-mapping>
- <filter-mapping>
- <filter-name>CacheForWeek</filter-name>
- <url-pattern>/ext/*</url-pattern>
- </filter-mapping>
- <filter-mapping>
- <filter-name>CacheForWeek</filter-name>
- <url-pattern>*.js</url-pattern>
- </filter-mapping>
- <filter-mapping>
- <filter-name>CacheForWeek</filter-name>
- <url-pattern>*.css</url-pattern>
- </filter-mapping>
(插入一段:在探測這些效能問題的時候,我使用的是一個Firebug的外掛,也就是Firefox外掛的外掛-YSlow,好像是Yahoo的,結合Firebug裡XHR的Net這塊做Profiling,效果很不錯,很容易就知道瓶頸)
還有一個gzip的辦法,就是在伺服器壓縮內容,再傳給瀏覽器。現在主流的瀏覽器都支援gzip壓縮,而且這些html和js文字壓縮起來很厲害,基本上可以有40%的壓縮率。辦法在servel.xml的註釋裡也有寫,就是在Connector元素里加上
compression="on"
compressionMinSize="2048"
noCompressionUserAgents="gozilla,traviata"
compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain"
以上的內容大部分都是Google得來,我自己做了一下整理