varnish与squid缓存效率对比实例

Posted dannylinux

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了varnish与squid缓存效率对比实例相关的知识,希望对你有一定的参考价值。

前提:安装varnish、squid、webbench(压测工具)

 注:varnish和squid机都未安装其他多余服务,服务器绑定域名为www.dannylinux.top  (为同一台服务器,测试其中一个时,另一个服务停掉)

varnish和squid监听端口都为80,方便测试时不用防火墙端口转发配置

1.varnish配置

#使用varnish版本4的格式.
vcl 4.0;
# 加载后端轮询模块
import directors;
#######################健康检查策略区域###########################
# 名为www_probe的健康检查策略
probe www_probe {
.request =
"GET /html/test.html HTTP/1.1"    # 健康检查url为/html/test.html 协议为http1.1
"Host: www.xxxxx.com"        # 访问的域名为www.xxxxx.com
"Connection: close";        # 检查完关闭连接
#其他参数 如 超时时间 检查间隔 等 均使用默认
}

##################################################################
#######################配置后端区域################################
backend backend_16 {
.host = "111.111.111.16";
.port = "80";
.probe = www_probe; # 使用名为www_probe的健康检查策略
}
backend backend_17 {
.host = "111.111.111.17";
.port = "80";
.probe = www_probe; # 使用名为www_probe的健康检查策略
}
#默认后端
backend default {
.host = "测试web服务器IP";   #此处实验没用集群,只用了这个
.port = "80";
}

###################################################################
# 配置后端集群事件
sub vcl_init {
# 后端集群有4种模式 random, round-robin, fallback, hash
# random         随机
# round-robin    轮询
# fallback        后备
# hash        固定后端 根据url(req.http.url) 或 用户cookie(req.http.cookie) 或 用户session(req.http.sticky)(这个还有其他要配合)
# 把backend_16 和 backend_17配置为轮询集群 取名为www_round_robin
new www_round_robin = directors.round_robin();
www_round_robin.add_backend(backend_16);
www_round_robin.add_backend(backend_17);
# 把backend_16 和 backend_17配置为随机选择集群 取名为www_random
new www_random = directors.random();
www_random.add_backend(backend_16,10);  # 设置backend_16后端的权重为10
www_random.add_backend(backend_17,5);   # 设置backend_17后端的权重为5
# 把backend_16 和 backend_17配置为固定后端集群 取名为www_hash 在recv调用时还需要添加东西 看recv例子
new www_hash = directors.hash();
www_hash.add_backend(backend_16,1);        # 设置backend_16后端的权重为1
www_hash.add_backend(backend_17,1);        # 设置backend_17后端的权重为1
}

#定义允许清理缓存的IP
acl purge {
# For now, Ill only allow purges coming from localhost
"127.0.0.1";
"localhost";
}

# 请求入口 这里一般用作路由处理 判断是否读取缓存 和 指定该请求使用哪个后端
sub vcl_recv {
##############################指定后端区域###########################
# 域名为 www.xxxxx.com 的请求 指定使用名为www_round_robin的后端集群  在集群名后加上 .backend() 如只使用单独后端 直接写后端名字即可 如 = backend_16;
if (req.http.host ~ "www.xxxxx.com") {
set req.backend_hint = www_round_robin.backend();
}
# 使用固定后端集群例子 使用名为www_hash的集群
if (req.http.host ~ "3g.xxxxx.com") {
set req.backend_hint = www_hash.backend(req.http.cookie);  # 根据用户的cookie来分配固定后端 可以指定其他分配规则
}
# 其他将使用default默认后端
#####################################################################
# 把真实客户端IP传递给后端服务器 后端服务器日志使用X-Forwarded-For来接收
if (req.restarts == 0) {
if (req.http.X-Forwarded-For) {
set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip;
} else {
set req.http.X-Forwarded-For = client.ip;
}
}
# 匹配清理缓存的请求
if (req.method == "PURGE") {
# 如果发起请求的客户端IP 不是在acl purge里面定义的 就拒绝
if (!client.ip ~ purge) {
return (synth(405, "This IP is not allowed to send PURGE requests."));
}
# 是的话就执行清理
return (purge);
}
# 如果不是正常请求 就直接穿透没商量
if (req.method != "GET" &&
req.method != "HEAD" &&
req.method != "PUT" &&
req.method != "POST" &&
req.method != "TRACE" &&
req.method != "OPTIONS" &&
req.method != "PATCH" &&
req.method != "DELETE") {
/* Non-RFC2616 or CONNECT which is weird. */
return (pipe);
}
# 如果不是GET和HEAD就跳到pass 再确定是缓存还是穿透
if (req.method != "GET" && req.method != "HEAD") {
return (pass);
}
# 缓存通过上面所有判断的请求 (只剩下GET和HEAD了)
return (hash);
}

# pass事件
sub vcl_pass {
# 有fetch,synth or restart 3种模式. fetch模式下 全部都不会缓存
return (fetch);
}

# hash事件(缓存事件)
sub vcl_hash {
# 根据以下特征来判断请求的唯一性 并根据此特征来缓存请求的内容 特征为&关系
# 1. 请求的url
# 2. 请求的servername 如没有 就记录请求的服务器IP地址
# 3. 请求的cookie
hash_data(req.url);
if (req.http.host) {
hash_data(req.http.host);
} else {
hash_data(server.ip);
}
# 返回lookup , lookup不是一个事件(就是 并非指跳去sub vcl_lookup) 他是一个操作 他会检查有没有缓存 如没有 就会创建缓存
return (lookup);
}

# 缓存命中事件 在lookup操作后自动调用 官网文档说 如没必要 一般不需要修改
sub vcl_hit {
# 可以在这里添加判断事件(if) 可以返回 deliver restart synth 3个事件
# deliver  表示把缓存内容直接返回给用户
# restart  重新启动请求 不建议使用 超过重试次数会报错
# synth    返回状态码 和原因 语法:return(synth(status code,reason))
# 这里没有判断 所有缓存命中直接返回给用户
return (deliver);
}

# 缓存不命中事件 在lookup操作后自动调用 官网文档说 如没必要 一般不需要修改
sub vcl_miss {
# 此事件中 会默认给http请求加一个 X-Varnish 的header头 提示: nginx可以根据此header来判断是否来自varnish的请求(就不用起2个端口了)
# 要取消此header头 只需要在这里添加 unset bereq.http.x-varnish; 即可
# 这里所有不命中的缓存都去后端拿 没有其他操作 fetch表示从后端服务器拿取请求内容
return (fetch);
}

# 返回给用户的前一个事件 通常用于添加或删除header头,如通过curl -I返回头中添加一个返回值,如下:
sub vcl_deliver {
# 例子
# set resp.http.*    用来添加header头 如 set resp.http.xxxxx = "haha"; unset为删除
# set resp.status     用来设置返回状态 如 set resp.status = 404;
# obj.hits        会返回缓存命中次数 用于判断或赋值给header头
# req.restarts    会返回该请求经历restart事件次数 用户判断或赋值给header头
# 根据判断缓存时间来设置xxxxx-Cache header头
if (obj.hits > 0) {
set resp.http.X-Cache = "cached from " + client.ip;  #如果命中,则显示Hit from +客户端IP
} else {
set resp.http.X-Cache = "uncached";  #未命中则显示"Miss"    具体效果图在最底部
}
#取消显示php框架版本的header头
unset resp.http.X-Powered-By;
#取消显示nginx版本、Via(来自varnish)等header头 为了安全
unset resp.http.Server;
unset resp.http.X-Drupal-Cache;
unset resp.http.Via;
unset resp.http.Link;
unset resp.http.X-Varnish;
#显示请求经历restarts事件的次数
set resp.http.X-restarts_count = req.restarts;
#显示该资源缓存的时间 单位秒
set resp.http.X-Age = resp.http.Age;
#显示该资源命中的次数
set resp.http.X-hit_count = obj.hits;
#取消显示Age 为了不和CDN冲突
unset resp.http.Age;
#返回给用户
return (deliver);
}

#处理对后端返回结果的事件(设置缓存、移除cookie信息、设置header头等) 在fetch事件后自动调用
sub vcl_backend_response {
#后端返回如下错误状态码 则不缓存
if (beresp.status == 499 || beresp.status == 404 || beresp.status == 502) {
set beresp.uncacheable = true;
}
#如请求php或jsp 则不缓存
if (bereq.url ~ "\\.(php|jsp)(\\?|$)") {
set beresp.uncacheable = true;
#php和jsp以外的请求
}else{
#如请求html 则缓存5分钟
if (bereq.url ~ "\\.html(\\?|$)") {
set beresp.ttl = 300s;
unset beresp.http.Set-Cookie;
#其他缓存1小时 如css js等
}else{
set beresp.ttl = 1h;
unset beresp.http.Set-Cookie;
}
}
#开启grace模式 表示当后端全挂掉后 即使缓存资源已过期(超过缓存时间) 也会把该资源返回给用户 资源最大有效时间为6小时
set beresp.grace = 6h;
#返回给用户
return (deliver);
}

#返回给用户前的事件 可以在这里自定义输出给用户的内容
sub vcl_deliver {
}

 

2.squid配置

#
# Recommended minimum configuration:
#

# Example rule allowing access from your local networks.
# Adapt to list your (internal) IP networks from where browsing
# should be allowed
#acl localnet src xx.xx.xx.0/24
#acl localnet src 172.31.16.128/32
acl localnet src 10.0.0.0/8     # RFC1918 possible internal network
acl localnet src 172.16.0.0/12  # RFC1918 possible internal network
acl localnet src 192.168.0.0/16 # RFC1918 possible internal network
acl localnet src fc00::/7       # RFC 4193 local private network range
acl localnet src fe80::/10      # RFC 4291 link-local (directly plugged) machines

acl SSL_ports port 443
acl Safe_ports port 80          # http
acl Safe_ports port 21          # ftp
acl Safe_ports port 443         # https
acl Safe_ports port 70          # gopher
acl Safe_ports port 210         # wais
acl Safe_ports port 1025-65535  # unregistered ports
acl Safe_ports port 280         # http-mgmt
acl Safe_ports port 488         # gss-http
acl Safe_ports port 591         # filemaker
acl Safe_ports port 777         # multiling http
acl CONNECT method CONNECT

#
# Recommended minimum Access Permission configuration:
#
# Deny requests to certain unsafe ports
http_access deny !Safe_ports

# Deny CONNECT to other than secure SSL ports
http_access deny CONNECT !SSL_ports

# Only allow cachemgr access from localhost
http_access allow localhost manager
http_access deny manager

# We strongly recommend the following be uncommented to protect innocent
# web applications running on the proxy server who think the only
# one who can access services on "localhost" is a local user
#http_access deny to_localhost

#
# INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS
#

forwarded_for off
via off
# Example rule allowing access from your local networks.
# Adapt localnet in the ACL section to list your (internal) IP networks
# from where browsing should be allowed
http_access allow localnet
http_access allow localhost

# And finally deny all other access to this proxy
http_access allow all
#http_access deny all

# Squid normally listens to port 3128
#http_port 3128
http_port 80 accel vhost vport    #设置squid监听端口,方便域名直接访问
cache_peer web测试服务器IP parent 80 0 no-query no-digest originserver name=www
cache_peer_domain www www.dannylinux.top dannylinux.top
# Uncomment and adjust the following to add a disk cache directory.
cache_dir ufs /var/spool/squid 100 16 256

# Leave coredumps in the first cache dir
coredump_dir /var/spool/squid

#
# Add any of your own refresh_pattern entries above these.
#


refresh_pattern ^ftp:           1440    20%     10080
refresh_pattern ^gopher:        1440    0%      1440
refresh_pattern -i (/cgi-bin/|\\?) 0     0%      0
refresh_pattern .               0       20%     4320


refresh_pattern -i \\.css$       360    50%     2880    reload-into-ims
refresh_pattern -i \\.js$        1440    50%     2880    reload-into-ims
refresh_pattern -i \\.html$        720   50%     1440    reload-into-ims
refresh_pattern -i \\.jpg$       1440    90%     2880    ignore-reload
refresh_pattern -i \\.gif$       1440    90%     2880    ignore-reload
refresh_pattern -i \\.swf$       1440    90%     2880    ignore-reload
refresh_pattern -i \\.jpg$       1440      50%     2880    ignore-reload
refresh_pattern -i \\.png$       1440      50%     2880      ignore-reload
refresh_pattern -i \\.bmp$       1440      50%     2880      ignore-reload

refresh_pattern -i \\.doc$ 1440    50%     2880      ignore-reload
refresh_pattern -i \\.ppt$ 1440    50%     2880      ignore-reload
refresh_pattern -i \\.xls$ 1440    50%     2880      ignore-reload
refresh_pattern -i \\.pdf$ 1440    50%     2880      ignore-reload
refresh_pattern -i \\.rar$       1440    50%     2880      ignore-reload
refresh_pattern -i \\.zip$ 1440    50%     2880      ignore-reload
refresh_pattern -i \\.txt$ 1440    50%     2880      ignore-reload

 

3.测试

1)varnish测试结果

技术图片

 

 

 2)squid测试结果

 技术图片

 

4.结论

就算是排除我squid配置文件缓存没有配置好的原因,但是这差距还真不是一般的大啊,squid差varnish不是一点半点啊。

 

以上是关于varnish与squid缓存效率对比实例的主要内容,如果未能解决你的问题,请参考以下文章

varnish缓存代理

Varnish缓存代理简介与配置

CDN缓存服务器现状

加速与缓存技术之Varnish

varnish缓存代理

varnish 4.0 缓存代理配置