一、Grace mode(优雅模式)

为什么使用Grace mode ,优雅模式的优点是什么?

如果你每秒需要相应成千上万的点击,等待的请求队列就会很巨大。这里有两个潜在问题:一个是thundering herd problem(这个无法翻译。。。wiki有专门的对应解释),突然增加一千个线程去提供内容,会让负载变得很高;第二个,没有人喜欢等。为了解决这个问题,我们指示varnish去保持缓存的对象超过他们的TTL(就是该过期的,不让它过期),并且去提供旧的内容给正在等待的请求。 既然要提供旧的内容,首先我们必须有内容去提供。所以,我们使用以下VCL,以使varnish保持所有对象超出了他们的TTL30分钟。

sub vcl_fetch {set beresp.grace = 30m;
}

这样,varnish还不会提供旧对象。为了启用varnish去提供旧对象,我们必须在请求上开启它。下面表示,我们接收15s的旧对象:

sub vcl_recv {set req.grace = 15s;
}

varnish的优势在于内存级的cache,所以内存的多少决定了cache的数据量的多少。如果开启了优雅模式,在TTL到期后,我们仍不将其从mem里清除掉,而是要再等待一段时间才清除,这就无端的浪费了资源。但如果你开启了健康检查,你可以检查后端是否出问题。如果出问题了,我们可以提供长点时间的旧内容。如果后端没有问题,我们可以将该时间设置的短一些。这就在保证优雅的本身,减少了资源的浪费,其配置如下:

if (! req.backend.healthy) {set req.grace = 5m;
} else {set req.grace = 15s;
}

所以,综上所述。优雅模式的主要功能有以下两点:

1、合并请求,当N个客户端请求同一个页面的时候,varnish只发送一个请求到后端服务器,然后让其他几个请求挂起等待返回结果,返回结果后,复制请求的结果发送给客户端。。

2、通过提供旧的内容,避免请求扎堆。如果后端提供旧的内容,减少后端和前端请求的压力,而且为后端的重启和切换提供了时间。

二、神圣模式(Saint mode)

有时候,服务器很古怪,他们发出随机错误,您需要通知 varnish 使用更加优雅的方式处理 它,这种方式叫神圣模式(saint mode)。Saint mode 允许您抛弃一个后端服务器或者另一个尝试的后端服务器或者 cache 中服务陈旧的内容。如:

sub vcl_fetch {if (beresp.status == 500) {set beresp.saintmode = 10s;return (restart);}set beresp.grace = 5m;
}

如上面的配置,当我们设置beresp.saintmode为10秒时,varnish会不请求该服务器10秒。或多或少可以算是一个黑名单。restart被执行时,如果我们有其他后端可以提供该内容,varnish会请求它们。当没有其他后端可用,varnish就会提供缓存中的旧内容。

三、grace和saint模式的局限性

以上两种模式也并非是万能的,如当请求正在被获取时,如果你的请求失败,会被扔到vcl_error中。由于vcl_error对数据集的访问会在前端显示,所以你不能启用优雅模式和神圣模式。在以后发布的版本中会解决这个问题,但是这里我们还是可以做些尽量避免该问题,官方给出的原文是:

Declare a backend that is always sick.
Set a magic marker in vcl_error
Restart the transaction
Note the magic marker in vcl_recv and set the backend to the one mentioned
Varnish will now serve stale data is any is available

这段话理解上比较费力,也有人做了一个中文翻译版是:

1、声明总是出状况的后端
2、在vcl_error中设置magic marker
3、重启事务
4、注意vcl_recv中的magic marker,并设置后端为之前提到的。
5、varnish现在将提供旧任何可获得的数据

注:其中magic marker是其参数中的一部分,具体可以参看官方wiki上的示例。

以上内容主要参看官方的如下页面:

varnish 3.0.5官网文档

varnish static book部分

四、完整示例

由于版本和参数变更的问题,示例中的配置并不保证能完全适用您所用的版本,不过具体可以在该示例的基础上做下适当的增减。其中一些涉及到的参数也可以对比官方文档做下适当更改。

import std;
backend web1 {.host = "172.16.2.31";.port = "80";.probe = {.url = "/";.interval = 10s;.timeout = 2s;.window = 3;.threshold = 3;}
}
backend web2 {.host = "172.16.2.32";.port = "80";.probe = {.url = "/";.interval = 10s;.timeout = 2s;.window = 3;.threshold = 3;}
}
# 定义负载均衡组
director webgroup random {{.backend = web1;.weight = 1;}{.backend = web2;.weight = 1;}
}
# 允许刷新缓存的ip
acl purgeAllow {"localhost";"172.16.2.5";
}
sub vcl_recv {# 刷新缓存设置if (req.request == "PURGE") {#判断是否允许ipif (!client.ip ~ purgeAllow) {error 405 "Not allowed.";}#去缓存中查找return (lookup);}std.log("LOG_DEBUG: URL=" + req.url);set req.backend = webgroup;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);}# 只缓存 GET 和 HEAD 请求if (req.request != "GET" && req.request != "HEAD") {std.log("LOG_DEBUG: req.request not get!  " + req.request );return(pass);}# http 认证的页面也 passif (req.http.Authorization) {std.log("LOG_DEBUG: req is authorization !");return (pass);}if (req.http.Cache-Control ~ "no-cache") {std.log("LOG_DEBUG: req is no-cache");return (pass);}# 忽略admin、verify、servlet目录,以.jsp和.do结尾以及带有?的URL,直接从后端服务器读取内容if (req.url ~ "^/admin" || req.url ~ "^/verify/" || req.url ~ "^/servlet/" || req.url ~ ".(jsp|php|do)($|?)") {std.log("url is admin or servlet or jsp|php|do, pass.");return (pass);}# 只缓存指定扩展名的请求, 并去除 cookieif (req.url ~ "^/[^?]+.(jpeg|jpg|png|gif|bmp|tif|tiff|ico|wmf|js|css|ejs|swf|txt|zip|exe|html|htm)(?.*|)$") {std.log("*** url is jpeg|jpg|png|gif|ico|js|css|txt|zip|exe|html|htm set cached! ***");unset req.http.cookie;# 规范请求头,Accept-Encoding 只保留必要的内容if (req.http.Accept-Encoding) {if (req.url ~ ".(jpg|png|gif|jpeg)(?.*|)$") {remove req.http.Accept-Encoding;} elsif (req.http.Accept-Encoding ~ "gzip") {set req.http.Accept-Encoding = "gzip";} elsif (req.http.Accept-Encoding ~ "deflate") {set req.http.Accept-Encoding = "deflate";} else {remove req.http.Accept-Encoding;}}return(lookup);} else {std.log("url is not cached!");return (pass);}
}
sub vcl_hit {if (req.request == "PURGE") {set obj.ttl = 0s;error 200 "Purged.";}return (deliver);
}
sub vcl_miss {std.log("################# cache miss ################### url=" + req.url);if (req.request == "PURGE") {purge;error 200 "Purged.";}
}
sub vcl_fetch {# 如果后端服务器返回错误,则进入 saintmodeif (beresp.status == 500 || beresp.status == 501 || beresp.status == 502 || beresp.status == 503 || beresp.status == 504) {std.log("beresp.status error!!! beresp.status=" + beresp.status);set req.http.host = "status";set beresp.saintmode = 20s;return (restart);}# 如果后端静止缓存, 则跳过if (beresp.http.Pragma ~ "no-cache" || beresp.http.Cache-Control ~ "no-cache" || beresp.http.Cache-Control ~ "private") {std.log("not allow cached!   beresp.http.Cache-Control=" + beresp.http.Cache-Control);return (hit_for_pass);}if (beresp.ttl <= 0s || beresp.http.Set-Cookie || beresp.http.Vary == "*") {/* Mark as "Hit-For-Pass" for the next 2 minutes */set beresp.ttl = 120 s;return (hit_for_pass);}if (req.request == "GET" && req.url ~ ".(css|js|ejs|html|htm)$") {std.log("gzip is enable.");set beresp.do_gzip = true;set beresp.ttl = 20s;}if (req.request == "GET" && req.url ~ "^/[^?]+.(jpeg|jpg|png|gif|bmp|tif|tiff|ico|wmf|js|css|ejs|swf|txt|zip|exe)(?.*|)$") {std.log("url css|js|gif|jpg|jpeg|bmp|png|tiff|tif|ico|swf|exe|zip|bmp|wmf is cache 5m!");set beresp.ttl = 5m;} elseif (req.request == "GET" && req.url ~ ".(html|htm)$") {set beresp.ttl = 30s;} else {return (hit_for_pass);}# 如果后端不健康,则先返回缓存数据1分钟if (!req.backend.healthy) {std.log("eq.backend not healthy! req.grace = 1m");set req.grace = 1m;} else {set req.grace = 30s;}return (deliver);
}
# 发送给客户端
sub vcl_deliver {if ( obj.hits > 0 ) {set resp.http.X-Cache = "has cache";} else {#set resp.http.X-Cache = "no cache";}return (deliver);
}

Varnish的优雅模式和神圣模式相关推荐

  1. 【游戏设计模式】之二 论撤消重做、回放系统的优雅实现:命令模式

    转载自:https://blog.csdn.net/poem_qianmo/article/details/52663057 这篇文章起源于<Game Programming Patterns& ...

  2. 听webcast的行为型模式篇-迭代器模式(Iterator Pattern) 记录

    < DOCTYPE html PUBLIC -WCDTD XHTML StrictEN httpwwwworgTRxhtmlDTDxhtml-strictdtd> dotnet或java里 ...

  3. 主模式和野蛮模式_网络野蛮行为的含混性和观念

    主模式和野蛮模式 Taking a dig at Jakob Nielsen's po-faced disapproval of Flash, Joel Spolsky wrote a post th ...

  4. 委派模式与策略模式综合应用

    在上面的代码中我们列举了非常几个业务场景,相信小伙伴对委派模式和策略模式有了非常深刻的理解了.现在,我们再来回顾一下,DispatcherServlet 的委派逻辑,代码如下: private voi ...

  5. js对象赋值只保留存在的属性_js对象的创建对象模式和继承模式(上)---构建对象模式...

    ​前言 ECMAScript与其他面向对象语言不同的是,它没有类的概念,因此它的对象也和基于类的语言中的对象有所不同,深入理解js的对象是每个前端工程师的基本素养,本文将就创建对象模式的方面对对象进行 ...

  6. 代理模式 委派模式 策略模式_委派模式和策略模式

    一.委派模式 委派模式(Delegate Pattern):指负责任务的调度和分配任务,跟代理模式很像,可以看做是一种特殊情况下的静态代理的全权代理,但是代理模式注重过程,而委派模式注重结果.(属于行 ...

  7. 策略模式、工厂模式、装饰者模式总结解析

    今天在面试的时候被问到自己策略模式怎么用的时候有被问懵到,以至于明明是自己的代码在脑海里已经混乱了,而且面试官提出的还是没有更好的利用设计模式也让我思考了一下我之前的代码到底是怎么实现的,重新梳理下策 ...

  8. 23种设计模式之单例模式、工厂模式、原型模式、建造者模式

    系列文章目录 第一章:程序设计原则-单一职责.接口隔离.依赖倒置.里式替换 第二章:程序设计原则-开闭原则.迪米特法则.合成复用原则 文章目录 系列文章目录 一.设计模式简单介绍 1.1.什么是设计模 ...

  9. 【IO】IO设计模式:TPR模式,Reactor模式、Proactor模式

    1.TPR模式 传统的 Server/Client 模式会基于TPR(Thread per Request),服务器会为每个客户端请求建立一个线程,由该线程单独负责处理一个客户请求. 这种模式虽然处理 ...

最新文章

  1. poj 2482 Stars in Your Window (线段树扫描线)
  2. leetcode -39组合总数
  3. ubuntu18.04 安装Teamviewer15出现依赖库出错
  4. 文化的作用与本质是什么
  5. 基于java的随机森林算法_基于Spark实现随机森林代码
  6. mysql配置文件参数详解 my.cnf
  7. php访问oracle写sql不能换行
  8. 系统学习机器学习之线性判别式(一)
  9. linux命令:tail 命令
  10. 警告解决办法:class xxxx has virtual method but non-virtual destructor
  11. 使用.NET和Jquery打造简单的便签纸
  12. orcadcapture安装_OrCAD下载
  13. APK 包名修改工具
  14. html扫雷源码js,js实现扫雷源代码.pdf
  15. ABB工业机器人程序编写与实战
  16. js中 new,self和this的用法解释
  17. 9.23 未来的规划 BEC
  18. 简析also, too, as well,either用法
  19. 拆弹专家(密码BFS)
  20. 7-139 手机话费

热门文章

  1. 【Python编程练习100题】P06—P10
  2. 服务器系统装内存条,hp服务器怎么安装内存条 hp服务器内存推荐【图文】
  3. beforeEach
  4. lol1月24服务器维护,LOL测试服1月24日:蔚技能全面调整 刀妹再次削弱
  5. 互联网电脑监控软件有哪些?可以远程办公的监控软件?
  6. 剪切波变换matlab,剪切波变换MATLAB实现代码
  7. 【点云处理技术之PCL】点云分割算法1——平面模型分割、圆柱模型分割和欧式聚类提取(含欧式聚类原理)
  8. win10显卡驱动怎么装_win10系统显卡驱动安装失败怎么办
  9. Java 实现订单未支付超时自动取消
  10. 如何在Unity5.0 下实现贴图材质的Animation动画功能