AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / server / 问题 / 517963
Accepted
mark
mark
Asked: 2013-06-24 14:34:00 +0800 CST2013-06-24 14:34:00 +0800 CST 2013-06-24 14:34:00 +0800 CST

让清漆在获取新数据时从缓存中发送旧数据?

  • 772

我正在缓存动态生成的页面(PHP-FPM、NGINX)并在它们前面有清漆,这很好用。

但是,一旦达到缓存超时,我会看到:

  • 新客户请求页面
  • varnish 识别缓存超时
  • 客户等待
  • varnish 从后端获取新页面
  • varnish 向客户端提供新页面(并且也缓存了页面,以供下一个立即获取它的请求)

我想做的是:

  • 客户请求页面
  • varnish 识别超时
  • varnish 将旧页面交付给客户端
  • varnish 从后端获取新页面并将其放入缓存中

就我而言,过时信息不是一个大问题的网站,尤其是当我们谈论几分钟后的缓存超时时。

但是,我不想惩罚用户排队等候,而是立即交付一些东西。这在某种程度上可能吗?

为了说明,下面是对我的服务器运行 siege 5 分钟的示例输出,该服务器配置为缓存一分钟:

HTTP/1.1,200,  1.97,  12710,/,1,2013-06-24 00:21:06
...
HTTP/1.1,200,  1.88,  12710,/,1,2013-06-24 00:21:20
...
HTTP/1.1,200,  1.93,  12710,/,1,2013-06-24 00:22:08
...
HTTP/1.1,200,  1.89,  12710,/,1,2013-06-24 00:22:22
...
HTTP/1.1,200,  1.94,  12710,/,1,2013-06-24 00:23:10
...
HTTP/1.1,200,  1.91,  12709,/,1,2013-06-24 00:23:23
...
HTTP/1.1,200,  1.93,  12710,/,1,2013-06-24 00:24:12
...

我忽略了数百个正在运行的请求0.02。但我仍然担心会有用户不得不等待将近 2 秒才能获得原始 HTML。

我们不能在这里做得更好吗?

(我遇到了Varnish send while cache,听起来很相似,但不完全是我想要做的。)

解决方案

Shane Madden 的回答包含了解决方案,但我没有立即意识到。还有一个细节我没有包含在我的问题中,因为我认为它不相关,但实际上它是。

我目前使用的 CMS 解决方案有一个 varnish 数据库侦听器,因此能够通知 varnish 禁止内容已更改的页面。它使用一些正则表达式发送PURGE请求以禁止某些页面。

总结一下,有两种情况我遇到了不幸的用户:

  1. 页面的普通清漆 TTL 过期
  2. 后端用户更改内容,这会向清漆发送清除请求

在这两种情况下,我都有“不幸”的用户。在第二种情况下,后端用户通常会在页面更改后检查页面,从而缓解了这种情况;但不一定。

尽管如此,对于第二种情况,我创建了一个解决方案(是的,我意识到这个问题始于为第一种情况寻求答案......我的问题表述不佳):

我没有发送清除请求,而是使用 Shanes 建议并调整了 VCL,以便我的 varnish 数据库侦听器可以发送特殊请求来获取hash_always_miss设置为的页面true。

在当前架构下,我并没有真正做一个真正的异步请求的奢侈,但是在我如何在 PHP 中发出异步 GET 请求的帮助下?我能够制作一个 GET 请求来清漆,它不会等待页面加载,但足以触发清漆从后端获取页面并缓存它。

最终结果是数据库侦听器将请求发送到清漆,当我轮询特定页面时,它从来没有让我的请求“不走运”,但是一旦清漆从后端完全获取页面(这可能从 300 毫秒到 2 秒)它突然出现了。

我还必须找到一个解决方案如何在正常 TTL 用完时避免同样的问题,但我想这个解决方案也完全像 Shane 建议的那样:使用 wget 触发hash_always_miss,我只需要足够聪明就可以获取列表我必须刷新的页面。

performance
  • 3 3 个回答
  • 8801 Views

3 个回答

  • Voted
  1. David
    2013-07-31T00:57:38+08:002013-07-31T00:57:38+08:00

    @编辑:

    只是一个快速的让您知道此功能似乎只是在 master 分支的最新版本中实现的,您的版本可能不支持真正的 stale-while-revalidate yet / 我发布的示例将服务9999/10000 个请求,一个可怜的虫子仍然必须等待请求在后端完成(总比没有好;)...


    好吧,我不是 100% 确定为什么之前的评论说它不起作用,但根据:https ://www.varnish-software.com/static/book/Saving_a_request.html

    • req.grace - 定义一个对象可以在多长时间后被 Varnish 考虑为宽限模式。
    • beresp.grace - 定义超过 beresp.ttl-time Varnish 将保留对象的时间。
    • req.grace - 通常在 vcl_recv 中根据后端的状态进行修改。

    我目前正在使用手册中所说的配置,并且工作正常......这是我的 vcl 文件的片段......

    sub vcl_recv {
        # Cache rules above here...
        if (req.backend.healthy) {
            set req.grace = 30d;
        } else {
            set req.grace = 300d;
        }
    }
    
    sub vcl_fetch {
        # Fetch rules above here ...
    
        # If backend returns 500 error then boost the cache grace period...
        if (beresp.status == 500) {
            set beresp.grace = 10h;
            return (restart);
        }
    
        # How long carnish should keep the objects in cache..
        set beresp.grace = 1h;
    
        # Actual TTL of cache - If an object is older than this an update will be triggered to the backend server :)
        set beresp.ttl = 1m;
    }
    

    请注意,如果您想提供更长的后端响应宽限期(对于我的配置中的 500 错误),您将需要设置后端探测......这是我的后端探测的副本..

    backend default {
        .host = "127.0.0.1";
        .port = "8080";
        .probe = { 
            .url = "/nginx-status";
            .timeout = 500 ms; 
            .interval = 3s; 
            .window = 10;
            .threshold = 4;
        }
    }
    
    • 4
  2. Best Answer
    Shane Madden
    2013-06-24T14:53:49+08:002013-06-24T14:53:49+08:00

    我用来解决此问题的解决方案是确保页面上的 TTL 在刷新之前永远不会过期 - 强制在我的一个系统上运行的 HTTP 客户端获得缓慢的负载,而不是不幸的客户端要求。

    就我而言,这涉及wget到一个 cron,发送一个特殊的标头来标记请求并req.hash_always_miss基于此进行设置,强制将内容的新副本提取到缓存中。

    acl purge {
        "localhost";
    }
    
    sub vcl_recv {
        /* other config here */
        if (req.http.X-Varnish-Nuke == "1" && client.ip ~ purge) {
            set req.hash_always_miss = true;
        }
        /* ... */
    }
    

    对于您的内容,这可能意味着将 Varnish TTL 设置为 5 分钟左右,但将 cron 的 wget 配置为每分钟发出一次缓存刷新请求。

    • 3
  3. NITEMAN
    2013-06-25T07:45:56+08:002013-06-25T07:45:56+08:00

    在 Varnish 3 中,这是通过“宽限模式”实现的。根据手册[1],您必须添加以下逻辑:

    sub vcl_fetch {
      set beresp.grace = 30m;
    } // Makes objects to be cached/stored 30 min beyond its max-age/ttl
    
    sub vcl_recv {
      set req.grace = 60s;
    } // Allows varnish to serve objects which expired within last minute.
    

    [1] https://www.varnish-cache.org/docs/3.0/tutorial/handling_misbehave_servers.html#grace-mode

    • 0

相关问题

  • 基于 Microsoft 的服务器(IIS、MSSQL 等)上的病毒扫描应排除哪些内容?

  • jvm性能调优技巧/资源?

  • 加快 MSSQL 快照复制到 SQLExpress 副本的速度

  • 聚集索引与非聚集索引?

  • 使用大量 javascript 的页面上的鱿鱼速度很慢

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    新安装后 postgres 的默认超级用户用户名/密码是什么?

    • 5 个回答
  • Marko Smith

    SFTP 使用什么端口?

    • 6 个回答
  • Marko Smith

    命令行列出 Windows Active Directory 组中的用户?

    • 9 个回答
  • Marko Smith

    什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同?

    • 3 个回答
  • Marko Smith

    如何确定bash变量是否为空?

    • 15 个回答
  • Martin Hope
    Tom Feiner 如何按大小对 du -h 输出进行排序 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    Noah Goodrich 什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent 如何确定bash变量是否为空? 2009-05-13 09:54:48 +0800 CST
  • Martin Hope
    cletus 您如何找到在 Windows 中打开文件的进程? 2009-05-01 16:47:16 +0800 CST

热门标签

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve