`
annan211
  • 浏览: 445644 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

nginx + tomcat 负载均衡实现客户端缓存

 
阅读更多

   整体机制:多个业务tomcat 多个图片tomcat 通过nginx 实现负载均衡,服务器部分缓存已经完成。现在需要实现客户端缓存。
   1 设置nginx 缓存机制

 

  请尊重知识,请尊重原创 更多资料参考请见  http://www.cezuwang.com/listFilm?page=1&areaId=906&filmTypeId=1
  

     location ~ /photoserver/.*\.(gif|jpg|png|htm|jpeg|bmp|html|flv|ico|swf|doc)(.*) {
		      #root nginx_cache/cache;
			  if (!-f $request_filename) {
					proxy_pass http://img.dahongwa.com;  #图片服务器
				}
              proxy_cache_use_stale error timeout invalid_header http_500 http_502 http_503 http_504 http_404;
			  proxy_cache_methods GET HEAD POST;  
              proxy_cache_min_uses 1;			  
			  expires max;
			  access_log logs/img.dahongwa.com.log;
        }
   



  2 配置图片tomcat过滤器
  

     public class ResponseHeaderFilter implements Filter {

	/** The fc. */
	FilterConfig fc;

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest,
	 * javax.servlet.ServletResponse, javax.servlet.FilterChain)
	 */
	public void 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.setHeader(headerName, fc.getInitParameter(headerName));
		}
		// pass the request/response on
		chain.doFilter(req, response);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
	 */
	public void init(FilterConfig filterConfig) {
		this.fc = filterConfig;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.servlet.Filter#destroy()
	 */
	public void destroy() {
		this.fc = null;
	}
   



  配置图片tomcat web.xml文件

  

     <filter>
		<filter-name>ResponseHeaderFilter</filter-name>
		<filter-class>com.legendshop.core.photo.ResponseHeaderFilter</filter-class>
		<init-param>
			<param-name>Cache-Control</param-name>
			<param-value>max-age=315360000</param-value>
		</init-param>
		<init-param>
		     <param-name>Access-Control-Max-Age</param-name>
		     <param-value>315360000</param-value>
		</init-param>
		<init-param>
			<param-name>Expires</param-name>
			<param-value>315360000</param-value>
		</init-param>
	</filter>

	<filter-mapping>
		<filter-name>ResponseHeaderFilter</filter-name>
		<url-pattern>/photoserver/photo/*</url-pattern>
	</filter-mapping>

	<filter-mapping>
		<filter-name>ResponseHeaderFilter</filter-name>
		<url-pattern>/photoserver/images/*</url-pattern>
	</filter-mapping>
   



  3 在图片tmcat配置 过滤器 ETagContentFilter

  

     <filter>
		<filter-name>ETagContentFilter</filter-name>
		<filter-class>com.legendshop.core.photo.ETagContentFilter</filter-class>
		<init-param>
			<param-name>Cache-Control</param-name>
			<param-value>max-age=315360000</param-value>
		</init-param>
		<init-param>
		     <param-name>Access-Control-Max-Age</param-name>
		     <param-value>315360000</param-value>
		</init-param>
		<init-param>
			<param-name>Expires</param-name>
			<param-value>315360000</param-value>
		</init-param>
	</filter>

	<filter-mapping>
		<filter-name>ETagContentFilter</filter-name>
		<url-pattern>/photoserver/photo/*</url-pattern>
	</filter-mapping>

	<filter-mapping>
		<filter-name>ETagContentFilter</filter-name>
		<url-pattern>/photoserver/images/*</url-pattern>
	</filter-mapping>
  



  

      public class ETagContentFilter implements Filter {
	
	private static Logger logger = LoggerFactory.getLogger(ETagContentFilter.class);
	
	@Override
	public void destroy() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void doFilter(ServletRequest req, ServletResponse res,FilterChain chain) throws IOException, ServletException {
		// TODO Auto-generated method stub
			HttpServletRequest servletRequest  =  (HttpServletRequest) req;
		    HttpServletResponse servletResponse  =  (HttpServletResponse) res;
		 
		     ByteArrayOutputStream baos  =   new  ByteArrayOutputStream();
		     ETagResponseWrapper wrappedResponse  =   new  ETagResponseWrapper(servletResponse, baos);
		     chain.doFilter(servletRequest, wrappedResponse);
		 
		     byte [] bytes  =  baos.toByteArray();
	
		    String token  =   '"'   +  ETagComputeUtils.getMd5Digest(bytes)  +   '"' ;
		    servletResponse.setHeader( "ETag" , token);  //  always store the ETag in the header
	
		    String previousToken  =  servletRequest.getHeader("If-None-Match");
	    if  (previousToken  !=   null   &&  previousToken.equals(token))  {  //  compare previous token with current one
		    logger.debug("ETag match: returning 304 Not Modified");
		    servletResponse.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
		     //  use the same date we sent when we created the ETag the first time through
		    servletResponse.setHeader("Last-Modified",servletRequest.getHeader("If-Modified-Since"));
//		    servletResponse.setHeader("Cache-Control",315360000);
		    //Cache-Control: max-age=0 + Last-Modified(ETag)
	   }else{    //  first time through - set last modified time to now 
		    Calendar cal  =  Calendar.getInstance();
		    cal.set(Calendar.MILLISECOND,  0 );
		    Date lastModified  =  cal.getTime();
		    servletResponse.setDateHeader("Last-Modified", lastModified.getTime());
		     logger.debug( " Writing body content " );
		    servletResponse.setContentLength(bytes.length);
		    ServletOutputStream sos  =  servletResponse.getOutputStream();
		    sos.write(bytes);
		    sos.flush();
		    sos.close();
	   }
	}

	@Override
	public void init(FilterConfig arg0) throws ServletException {
		// TODO Auto-generated method stub
		
	}
   



  

    public class ETagResponseWrapper extends HttpServletResponseWrapper
{
   private HttpServletResponse response = null;
   private ServletOutputStream stream   = null;
   private PrintWriter         writer   = null;
   private OutputStream        buffer   = null;

   public ETagResponseWrapper( HttpServletResponse response, OutputStream buffer )
   {
      super( response );
      this.response = response;
      this.buffer = buffer;
   }

   public ServletOutputStream getOutputStream() throws IOException
   {
      if( stream == null )
         stream = new ETagResponseStream( response, buffer );

      return stream;
   }

   public PrintWriter getWriter() throws IOException
   {
      if( writer == null )
         writer = new PrintWriter( new OutputStreamWriter( getOutputStream(), "UTF-8" ) );

      return writer;
   }

   public void flushBuffer() throws IOException
   {
      stream.flush();
   }



   

public class ETagResponseStream extends ServletOutputStream{

    public ETagResponseStream(HttpServletResponse response,OutputStream outputstream)throws IOException
    {
        closed = false;
        stream = null;
        stream = outputstream;
    }

    public void close()
        throws IOException
    {
        if(!closed)
        {
            stream.close();
            closed = true;
        }
    }

    public void flush()
        throws IOException
    {
        if(!closed)
            stream.flush();
    }

    public void write(int i)
        throws IOException
    {
        if(!closed)
            stream.write((byte)i);
    }

    public void write(byte abyte0[], int i, int j)
        throws IOException
    {
        if(!closed)
            stream.write(abyte0, i, j);
    }

    public void write(byte abyte0[])
        throws IOException
    {
        write(abyte0, 0, abyte0.length);
    }

    public boolean closed()
    {
        return closed;
    }

    public void reset()
    {
    }

    private boolean closed;
    private OutputStream stream;
}



   好了 下面你刷新就是一堆的304了,去玩吧。

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics