当前位置:首页 > 开发 > 系统架构 > 架构 > 正文

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

发表于: 2015-01-27   作者:annan211   来源:转载   浏览次数:
摘要:    整体机制:多个业务tomcat 多个图片tomcat 通过nginx 实现负载均衡,服务器部分缓存已经完成。现在需要实现客户端缓存。    1 设置nginx 缓存机制    location ~ /photoserver/.*\.(gif|jpg|png|htm|jpeg|bmp|html|flv|ico|sw
   整体机制:多个业务tomcat 多个图片tomcat 通过nginx 实现负载均衡,服务器部分缓存已经完成。现在需要实现客户端缓存。
   1 设置nginx 缓存机制
  
     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了,去玩吧。

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

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
Tomcat集群方案 window环境Nginx+Tomcat集群配置 nginx负载均衡多台tomcat,session共享,session丢
Tomcat集群方案 window环境Nginx+Tomcat集群配置 nginx负载均衡多台tomcat,session共享,session丢
作者:niumd Blog:http://ari.iteye.com 转载请注明出处,谢谢 开发的应用采用F5负载均衡交换机,F5
1. rpm -ivh jdk-7u51-linux-i586.rpm 2.JDK 环境变量配置 vi /etc/profile 最后增加 #set environm
标签: 读写分离 URL重写 页面缓存 Nginx 反向代理 原创作品,允许转载,转载时请务必以超链接形式
关于nginx的安装和基本配置请参考 nginx,本文在原基础上完成以下几个功能: 结合proxy和upstream模
大纲 一、前言 二、环境准备 三、安装与配置Nginx 四、Nginx之反向代理 五、Nginx之负载均衡 六、Ng
转:http://freeloda.blog.51cto.com/2033581/1288553 大纲 一、前言 二、环境准备 三、安装与配置N
转:http://freeloda.blog.51cto.com/2033581/1288553 大纲 一、前言 二、环境准备 三、安装与配置N
大纲 一、前言 二、环境准备 三、安装与配置Nginx 四、Nginx之反向代理 五、Nginx之负载均衡 六、Ng
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号