varnish案例学习

一、定义在vcl_deliver中,向响应给客户端的报文添加一个自定义首部X-Cache;

(1)在vcl_deliver
sub vcl_deliver {
# Happens when we have all the pieces we need, and are about to send the
# response to the client.
#
# You can do accounting or modifying the final object here.
# 像客户端发送一个相应首部,反应是否缓存命中
if (obj.hits>0) {
set resp.http.X-Cache = “HIT ” + server.ip;
} else {
set resp.http.X-Cahce = “MISS ” + server.ip;
}
}

二、支持虚拟主机:
sub vcl_recv {
。。
### this is a rewrite rule for our CDN traffic, that comes in on org.www.cpe.* – we rewrite the request to ###www.cpe.*
if (req.http.host == “org.www.cpe.com”) {
set req.http.newhost = regsub(req.http.host, “(org)?\.(www)?\.(.*)”, “\2.\3”);
remove req.http.host;
set req.http.host = req.http.newhost;
}
。。
}
三、强制对某资源的请求,不检查缓存;
/admin
/login
sub vcl_recv {
。。
if (req.url ~ “(?i)^/login” || req.url ~ “(?i)^/admin”) {
return(pass);
}
if (req.url ~”test8.html”) {
/*不缓存test8.html*/
return(pass);
}

。。
}

四、对特定类型的资源取消其私有的cookie标识,并强行设定其可以varnish缓存的时长:
使用环境:有个别场景程序不严谨某些共同缓存加上了cookie,我们可以强制他去掉cookie并且让程序缓存。

vcl_backend_response {
if (beresp.http.cache-control !~ “s-maxage”) {
if (bereq.url ~ “(?i)\.jpg$”) {
/*经过测试缓存时间1个小时,普通过去后他依然在缓存*/
set beresp.ttl = 3600s;
unset beresp.http.Set-Cookie;
}
if (bereq.url ~ “(?i)\.css$”) {
set beresp.ttl = 600s;
unset beresp.http.Set-Cookie;
}
}
}
五、backend server的定义以及健康状态检测
1、backend server的定义:
backend name {
.attribute = “value”;
}

.host: BE主机的IP;
.port:BE主机监听的PORT;

.probe: 对BE做健康状态检测;
.max_connections:并连接最大数量;
2、后端主机cluster以及健康状态检测方式:
参考:https://www.varnish-cache.org/trac/wiki/VCLExampleDirector
参考:详细配置参考:man vmod_directors

probe name {
.attribute = “value”;
}

.url: 判定BE健康与否要请求的url;
.expected_response:期望响应状态码;默认为200;

varnish> backend.list
200
Backend name Refs Admin Probe
default(192.168.31.129,,80) 11 probe Healthy (no probe)
webser1(192.168.31.129,,80) 2 probe Healthy 8/8
webser2(192.168.31.128,,80) 2 probe Healthy 8/8
配置案例1:
(1)创建backend
backend webser1 {
.host = “192.168.31.129”;
.port = “80”;
.probe = {
.url = “/1.html”;
}
}
backend webser2 {
.host = “192.168.31.128”;
.port = “80”;
.probe = {
.url = “/1.html”;
}
}
(2)vcl_recv中调用不同资源发向不同后端

sub vcl_recv {
if (req.url ~ “(?i)\test1.(jpg|png|gif)$”) {
return(pass);
set req.backend_hint = webser1;
} if (req.url ~ “(?i)test.(jpg|png|gif)$”){
set req.backend_hint = webser2;
}
if (req.url ~ “(?i)\.(jpg|png|gif)$”) {
set req.backend_hint = websrv1;
} else {
set req.backend_hint = websrv2;
}
}

配置案例2:
(1)创建backend
backend webser1 {
.host = “192.168.31.129”;
.port = “80”;
.probe = {
.url = “/1.html”;
}
}
backend webser2 {
.host = “192.168.31.128”;
.port = “80”;
.probe = {
.url = “/1.html”;
}
}
(2)初始化后端调度cluster

import directors;
sub vcl_init {
new mycluster = directors.round_robin();
mycluster.add_backend(websrv1);
mycluster.add_backend(websrv2);
}
(3)vcl_recv中调用
vcl_recv {
set req.backend_hint = mycluster.backend();
}

负载均衡算法:
fallback, random, round_robin, hash
六、移除单个缓存对象

purge用于清理缓存中的某特定对象及其变种(variants),因此,在有着明确要修剪的缓存对象时可以使用此种方式。HTTP协议的PURGE方法可以实现purge功能,不过,其仅能用于vcl_hit和vcl_miss中,它会释放内存工作并移除指定缓存对象的所有Vary:-变种,并等待下一个针对此内容的客户端请求到达时刷新此内容。另外,其一般要与return(restart)一起使用。下面是个在VCL中配置的示例。
v3:
acl purgers {
“127.0.0.1”;
“192.168.0.0”/24;
}

sub vcl_recv {
if (req.request == “PURGE”) {
if (!client.ip ~ purgers) {
error 405 “Method not allowed”;
}
return (lookup);
}
}
sub vcl_hit {
if (req.request == “PURGE”) {
purge;
error 200 “Purged”;
}
}
sub vcl_miss {
if (req.request == “PURGE”) {
purge;
error 404 “Not in cache”;
}
}
sub vcl_pass {
if (req.request == “PURGE”) {
error 502 “PURGE on a passed object”;
}
}

客户端在发起HTTP请求时,只需要为所请求的URL使用PURGE方法即可,其命令使用方式如下:
# curl -I -X PURGE http://varniship/path/to/someurl

v4:
acl purgers {
“127.0.0.1”;
“192.168.0.0”/24;
}
sub vcl_recv {
# allow PURGE from localhost and 192.168.0…
if (req.method == “PURGE”) {
if (!client.ip ~ purgers) {
return (synth(405, “Purging not allowed for ” + client.ip));
}
return (purge);
}
}

sub vcl_purge {
set req.method = “GET”;
return (restart);
# return (synth(999, “clean ok!!!”));
}

curl -I -X PURGE http://192.168.31.130/1.html

七、生产环境案例一则:

acl purge {
/*配置允许清理缓存的ip列表*/
“localhost”;
“127.0.0.1”;
“10.1.0.0”/16;
“192.168.0.0”/16;
}

sub vcl_hash {
/*使用请求的url做hash*/
hash_data(req.url);
return (hash);
}

sub vcl_recv {
/*调用后端服务集组群*/
set req.backend = shopweb;
# set req.grace = 4h;
if (req.request == “PURGE”) {
if (!client.ip ~ purge) {
error 405 “Not allowed.”;
}
return(lookup);
}
if (req.request == “REPURGE”) {
if (!client.ip ~ purge) {
error 405 “Not allowed.”;
}
ban(“req.http.host == ” + req.http.host + ” && req.url ~ ” + req.url);
error 200 “Ban OK”;
}
##添加clientip进入header便于日志记录
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.request != “GET” &&
req.request != “HEAD” &&
req.request != “PUT” &&
req.request != “POST” &&
req.request != “TRACE” &&
req.request != “OPTIONS” &&
req.request != “DELETE”) {
/* Non-RFC2616 or CONNECT which is weird. */
return (pipe);
}
if (req.request != “GET” && req.request != “HEAD”) {
/* We only deal with GET and HEAD by default */
return (pass);
}
if (req.http.Authorization) {
/* Not cacheable by default 认证的不缓存*/
return (pass);
}

if ( req.url == “/Heartbeat.html” ) {
return (pipe);
}
if ( req.url == “/” ) {
return (pipe);
}
if ( req.url == “/index.jsp” ) {
return (pipe);
}

if (req.http.Cookie ~ “dper=”) {
return (pass);
}
if (req.http.Cookie ~ “sqltrace=”) {
return (pass);
}
if (req.http.Cookie ~ “errortrace=”) {
return (pass);
}
# if ( req.request == “GET” && req.url ~ “req.url ~ “^/shop/[0-9]+$” ) {
#url=/shop/[0-9]+$或者/shop/[0-9]?.*查询缓存
if ( req.url ~ “^/shop/[0-9]+$” || req.url ~ “^/shop/[0-9]?.*” ) {
return (lookup);
}

#url=”^/shop/\d{1,}/editmember” \d==[0-9]等等查询缓存
if ( req.url ~ “^/shop/(\d{1,})/editmember” || req.url ~ “^/shop/(\d{1,})/map” || req.url ~ “^/shop/(\d+)/dish-([^/]+)” ) {
return (lookup);
}

return (pass);
# return (lookup);
}

sub vcl_pipe {
return (pipe);
}

sub vcl_pass {
return (pass);
}
#命中PURGE清除缓存
sub vcl_hit {
if (req.request == “PURGE”) {
purge;
error 200 “Purged.”;
}
return (deliver);
}

sub vcl_miss {
if (req.request == “PURGE”) {
error 404 “Not in cache.”;
}
# if (object needs ESI processing) {
# unset bereq.http.accept-encoding;
# }
return (fetch);
}
sub vcl_fetch {
##设置缓存时间
set beresp.ttl = 3600s;
set beresp.http.expires = beresp.ttl;
#set beresp.grace = 4h;
# if (object needs ESI processing) {
# set beresp.do_esi = true;
# set beresp.do_gzip = true;
# }

if ( req.url ~ “^/shop/[0-9]+$” || req.url ~ “^/shop/[0-9]?.*” ) {
set beresp.ttl = 4h;
}

if ( req.url ~ “^/shop/(\d{1,})/editmember” || req.url ~ “^/shop/(\d{1,})/map” || req.url ~ “^/shop/(\d+)/dish-([^/]+)” ) {
set beresp.ttl = 24h;
}

if (beresp.status != 200){
return (hit_for_pass);
}
return (deliver);
}

sub vcl_deliver {
if (obj.hits > 0){
set resp.http.X-Cache = “HIT”;
}
else {
set resp.http.X-Cache = “MISS”;
}
set resp.http.X-Powered-By = “Cache on ” + server.ip;
set resp.http.X-Age = resp.http.Age;
return (deliver);
}

sub vcl_error {
set obj.http.Content-Type = “text/html; charset=utf-8”;
set obj.http.Retry-After = “5”;
synthetic {“”} + obj.status + ” ” + obj.response + {“”};
return (deliver);
}

sub vcl_init {
return (ok);
}

sub vcl_fini {
return (ok);
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值