当前位置: 代码迷 >> HTML/CSS >> 怎么实现基于filter的html静态化
  详细解决方案

怎么实现基于filter的html静态化

热度:263   发布时间:2012-08-27 21:21:57.0
如何实现基于filter的html静态化
AB测试数据,显示处理速度接近提升20倍(红色文字),并且在未开启时出现了大量的失败

引用


mysql连接为默认设置

ERROR [http-80-5] JDBCExceptionReporter.logExceptions(78) | Unable to connect to any hosts due to exception: java.net.SocketException: java.net.ConnectException: Connection refused: connect

** BEGIN NESTED EXCEPTION **

java.net.SocketException
MESSAGE: java.net.ConnectException: Connection refused: connect

STACKTRACE:

java.net.SocketException: java.net.ConnectException: Connection refused: connect





引用


启用缓存时测试数据,红字部分

C:\Documents and Settings\Administrator>ab -n 1000 -c 10 http://www.abc.com/
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking www.abc.com (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests


Server Software:        Apache-Coyote/1.1
Server Hostname:        www.abc.com
Server Port:            80

Document Path:          /
Document Length:        0 bytes

Concurrency Level:      10
Time taken for tests:   10.172 seconds
Complete requests:      1000
Failed requests:        0

Write errors:           0
Non-2xx responses:      1000
Total transferred:      109000 bytes
HTML transferred:       0 bytes
Requests per second:    98.31 [#/sec] (mean)
Time per request:       101.719 [ms] (mean)

Time per request:       10.172 [ms] (mean, across all concurrent requests)
Transfer rate:          10.46 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.9      0      16
Processing:    16  101  11.4    109     125
Waiting:        0   51  27.7     47     109
Total:         16  101  11.4    109     125

Percentage of the requests served within a certain time (ms)
  50%    109
  66%    109
  75%    109
  80%    109
  90%    109
  95%    109
  98%    109
  99%    109
100%    125 (longest request)

---------------------------------------------------------------

关闭缓存时测试数据,红字部分

C:\Documents and Settings\Administrator>ab -n 1000 -c 10 http://www.abc.com/?refresh=true
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking www.abc.com (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests


Server Software:        Apache-Coyote/1.1
Server Hostname:        www.abc.com
Server Port:            80

Document Path:          /?refresh=true
Document Length:        20385 bytes

Concurrency Level:      10
Time taken for tests:   193.406 seconds
Complete requests:      1000
Failed requests:        503
   (Connect: 0, Receive: 0, Length: 503, Exceptions: 0)

Write errors:           0
Non-2xx responses:      503
Total transferred:      10479297 bytes
HTML transferred:       10131345 bytes
Requests per second:    5.17 [#/sec] (mean)
Time per request:       1934.063 [ms] (mean)

Time per request:       193.406 [ms] (mean, across all concurrent requests)
Transfer rate:          52.91 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    1   4.3      0      31
Processing:    94 1906 1426.7   2000    8234
Waiting:       94 1893 1428.6   1984    8234
Total:         94 1907 1426.2   2000    8234

Percentage of the requests served within a certain time (ms)
  50%   2000
  66%   2031
  75%   3000
  80%   3016
  90%   4016
  95%   5016
  98%   6031
  99%   6063
100%   8234 (longest request)



-------------------------
实现思路

引用
以URL为key,ehcache为容器,如果容器中存在html结果,直接返回,如果没有,继续生成,返回后的结果放入容器,同时将结果返回给客户端,结束流程。


组成构建:

1.HtmlStaticFilter


public class HtmlStaticFilter implements Filter {

	private static final Log log = LogFactory.getLog(HtmlStaticFilter.class);

	private Xcache xcache;

	public Xcache getXcache() {
		return xcache;
	}

	public void setXcache(Xcache xcache) {
		this.xcache = xcache;
	}

	private static int counter = 0;

	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain filterChain) throws ServletException, IOException {

		String refresh = request.getParameter("refresh");
		if (StringUtils.isNotBlank(refresh) &&refresh.equals("true")) {
			filterChain.doFilter(request, response);
			return;
		}

		/**
		 * 获取请求url作为缓存的KEY
		 */
		String urlKey = request.getServerName()
				+ ((HttpServletRequest) request).getRequestURI();

		// 不缓存非html请求. js css img 跳过
		if (!urlKey.endsWith(".html") && !urlKey.endsWith("/")) {
			filterChain.doFilter(request, response);
			return;
		}
		log.error(++counter + ":url=====>" + urlKey);
		/**
		 * 查看缓存中是否有此文件,如果有,返回文件
		 */
		String content = (String) xcache.get(urlKey);
		if (content == null) {
			log.error("content=====>" + content);// 应该只出现一次
			// 使用我们自定义的响应包装器来包装原始的ServletResponse
			ResponseWrapper wrapper = new ResponseWrapper(
					(HttpServletResponse) response);
			/**
			 * 如果没有,继续请求,获取请求后返回的结果,放入缓存中。
			 */
			// 这句话非常重要,注意看到第二个参数是我们的包装器而不是response
			filterChain.doFilter(request, wrapper);
			// 处理截获的结果并进行处理,比如替换所有的“名称”为“铁木箱子”
			content = wrapper.getResult();
			xcache.set(urlKey, content);
		}

		/**
		 * 返回请求结果给客户端
		 */
		response.setCharacterEncoding("UTF-8");
		// 重置响应输出的内容长度
		response.setContentLength(-1);
		// 输出最终的结果
		PrintWriter out = response.getWriter();
		out.write(content);
		out.flush();
		out.close();
	}

	@Override
	public void destroy() {

	}

	@Override
	public void init(FilterConfig arg0) throws ServletException {

	}

}



构件2:ResponseWrapper




/**
 * 自定义一个响应结果包装器,将在这里提供一个基于内存的输出器来存储所有 返回给客户端的原始HTML代码。
 * 
 * @author 铁木箱子
 * 
 */
public class ResponseWrapper extends HttpServletResponseWrapper {
	private PrintWriter cachedWriter;
	private CharArrayWriter bufferedWriter;

	public ResponseWrapper(HttpServletResponse response) {
		super(response);
		// 这个是我们保存返回结果的地方
		bufferedWriter = new CharArrayWriter();
		// 这个是包装PrintWriter的,让所有结果通过这个PrintWriter写入到bufferedWriter中
		cachedWriter = new PrintWriter(bufferedWriter);
	}

	@Override
	public PrintWriter getWriter() {
		return cachedWriter;
	}

	/**
	 * 获取原始的HTML页面内容。
	 * 
	 * @return
	 */
	public String getResult() {
		return bufferedWriter.toString();
	}
}



3.Xcache实现类EhcacheXcache


public class EhcacheXcache implements Xcache {

	private Cache cache;

	public Cache getCache() {
		return cache;
	}

	public void setCache(Cache cache) {
		this.cache = cache;
	}

	public Object get(Object key) {
		Element e = (Element) cache.get(key);
		if (e != null) {
			return e.getValue();
		}
		return null;
	}

	public void set(String key, Object value) {
		Element e = new Element(key, value);
		cache.put(e);
	}

	@Override
	public String getName() {
		return cache.getName();
	}

}



4.基于spring管理的filter
引用


web.xml

<filter>
<filter-name>htmlStaticFilter</filter-name>
<filter-class>
org.springframework.web.filter.DelegatingFilterProxy
</filter-class>
</filter>

<filter-mapping>
<filter-name>htmlStaticFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>


spring配置文件

<bean id="htmlStaticFilter" class="com.webapp.filter.HtmlStaticFilter">
<property name="xcache">
<ref bean="xcache" />
</property>
</bean>

<bean id="cacheManager"
class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
</bean>

<bean id="htmlCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
<property name="cacheManager" ref="cacheManager"></property>
<property name="cacheName" value="htmlCache"></property>
</bean>

<bean id="xcache" class="com.cache.EhcacheXcache">
<property name="cache" ref="htmlCache"></property>
</bean>




完。

  相关解决方案