varnish如何建立高效的缓存规则

网站一般都会分为计算机站(俗称PC站)、移动站,并且使用不同的域名来为不同的设备类型提供服务。例如 :计算机访问使用域名: www.xytong.cc,移动设备访问使用域名:m.xytong.cc.如果有移动设备访问www域名(或计算机设备访问m域名),则用http 301跳转至m(或www)域名保证访问的一致性。

这种情况比较多见,例如京东,淘宝都是这样处理的。

varnish处理缓存也比较方便,只需要根据url进行缓存就可以了。

default.vcl可以这样处理:

sub vcl_hash {
    hash_data(req.url);
    if (req.http.host) {
        hash_data(req.http.host);
    } else {
        hash_data(server.ip);
    }
    return (lookup);
}

 

上述是比较常见的.可以处理大多数情况但如果有网站使用代码适配方式来区分计算机设备以及移动设备,即:无论访问用户设备类型都使用同一个url,仅根据用户设备user-agent  在后端处理加载不同的模板,那么上述配置显然就不起作用了。

既然后端根据用户设备user-agent提供不同内容,那么varnish也要根据用户设备user-agent缓存即可以了,沿此思路可以在vcl_hash里面加一句:

sub vcl_hash {
    hash_data(req.url);
    hash_data(req.http.user-agent);#不同的 user-agent缓存多份
    if (req.http.host) {
        hash_data(req.http.host);
    } else {
        hash_data(server.ip);
    }
    return (lookup);
}

因访问者的user-agent千差万别,一个url地址  varnish可能缓存了多份。所以这种方式虽然可行但是缓存命中会很低、且极为耗费内存

其实代码适配的网站,我们一个url地址只需要缓存2份即可 ,一份给计算机(PC)服务,一份给移动端服务.那么default.vcl可以这样写 :

sub vcl_hash {
	hash_data(req.url);
	if (req.http.host) 
	{
    hash_data(req.http.host);
  } 
  else 
  {
  	hash_data(server.ip);
  }
  if (req.url !~ "\.(bmp|png|gif|jpg|jpeg|ico|gz|tgz|bz2|tbz|zip|rar|mp3|mp4|ogg|swf|flv|js|css)") #针对非资源文件有效
	{
		call device_detect;# X-UA-Device变量仅仅为 'pc'或 'mobile'	
		hash_data (req.http.X-UA-Device);
	}
  return (lookup);
}

#根据用户设备user-agent来给req.http.X-UA-Device赋不同的值'pc'或'mobile'
sub device_detect {
    unset req.http.X-UA-Device;
    set req.http.X-UA-Device = "pc";
    if (req.http.User-Agent ~ "(?i)ip(hone|od)") { set req.http.X-UA-Device = "mobile"; }
    elsif (req.http.User-Agent ~ "(?i)ipad") { set req.http.X-UA-Device = "mobile"; }
    elsif (req.http.User-Agent ~ "(?i)android") { set req.http.X-UA-Device = "mobile"; } 
    elsif (
 req.http.User-Agent ~ "(?i)^sonyericsson" ||
 req.http.User-Agent ~ "(?i)^nokia" ||
 req.http.User-Agent ~ "(?i)^samsung" ||
 req.http.User-Agent ~ "(?i)^lg" ||
 req.http.User-Agent ~ "(?i)bada" ||
 req.http.User-Agent ~ "(?i)blazer" ||
 req.http.User-Agent ~ "(?i)cellphone" ||
 req.http.User-Agent ~ "(?i)iemobile" ||
 req.http.User-Agent ~ "(?i)midp-2.0" ||
 req.http.User-Agent ~ "(?i)u990" ||
 req.http.User-Agent ~ "(?i)netfront" ||
 req.http.User-Agent ~ "(?i)opera mini" ||
 req.http.User-Agent ~ "(?i)palm" ||
 req.http.User-Agent ~ "(?i)nintendo wii" ||
 req.http.User-Agent ~ "(?i)playstation portable" ||
 req.http.User-Agent ~ "(?i)portalmmm" ||
 req.http.User-Agent ~ "(?i)proxinet" ||
 req.http.User-Agent ~ "(?i)sonyericsson" ||
 req.http.User-Agent ~ "(?i)symbian" ||
 req.http.User-Agent ~ "(?i)windows\ ?ce" ||
 req.http.User-Agent ~ "(?i)winwap" ||
 req.http.User-Agent ~ "(?i)eudoraweb" ||
 req.http.User-Agent ~ "(?i)htc" ||
 req.http.User-Agent ~ "(?i)240x320" ||
 req.http.User-Agent ~ "(?i)avantgo"||
 req.http.User-Agent ~ "(?i)mobile"
 ) { 
 set req.http.X-UA-Device = "mobile";
 } 
}

这样就配置,就可以使varnish 同一个url仅缓存了2份缓存,进而可以提供来访用户的缓存命中几率、减少内存占用.

 

 

 

作者: 白金马桶

天道酬勤...

发表评论