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 / 问题 / 42164
Accepted
davidsmalley
davidsmalley
Asked: 2009-07-18 06:57:01 +0800 CST2009-07-18 06:57:01 +0800 CST 2009-07-18 06:57:01 +0800 CST

清漆配置仅缓存未登录用户

  • 772

我有一个 varnish+nginx 前面的 Ruby on Rails 应用程序。由于大多数站点内容都是静态的,除非您是登录用户,因此我想在用户注销时使用清漆大量缓存站点,但仅在用户登录时缓存静态资产。

当用户登录时,他们的 Cookie: 标头中将包含 cookie 'user_credentials',此外,我需要跳过 /login 和 /sessions 上的缓存,以便用户首先获得他们的 'user_credentials' cookie .

默认情况下,Rails 不设置缓存友好的 Cache-control 标头,但我的应用程序在用户未登录时设置了“public,s-max-age=60”标头。Nginx 设置为返回“远期”到期标头对于所有静态资产。

我目前的配置是在登录时完全绕过所有内容的缓存,包括静态资产——并且在注销时为所有内容返回缓存 MISS。我花了几个小时在圈子里转,这是我当前的 default.vcl

    director rails_director round-robin {
  { 
    .backend = { 
      .host = "xxx.xxx.xxx.xxx"; 
      .port = "http";
      .probe = {
        .url = "/lbcheck/lbuptest";
        .timeout = 0.3 s;
        .window = 8;
        .threshold = 3;
      }
    } 
  }
}

sub vcl_recv {

  if (req.url ~ "^/login") {
    pipe;
  }

  if (req.url ~ "^/sessions") {
    pipe;
  }
  # The regex used here matches the standard rails cache buster urls
  # e.g. /images/an-image.png?1234567
  if (req.url ~ "\.(css|js|jpg|jpeg|gif|ico|png)\??\d*$") {
    unset req.http.cookie;
    lookup;
  } else {
    if (req.http.cookie ~ "user_credentials") {
      pipe;
    }
  }

  # Only cache GET and HEAD requests
  if (req.request != "GET" && req.request != "HEAD") {
    pipe;
  }

}

sub vcl_fetch {

  if (req.url ~ "^/login") {
    pass;
  }

  if (req.url ~ "^/sessions") {
    pass;
  }

  if (req.http.cookie ~ "user_credentials") {
    pass;
  } else {
    unset req.http.Set-Cookie;
  }

  # cache CSS and JS files
  if (req.url ~ "\.(css|js|jpg|jpeg|gif|ico|png)\??\d*$") {
    unset req.http.Set-Cookie;
  } 

  if (obj.status >=400 && obj.status <500) {
    error 404 "File not found";
  }

  if (obj.status >=500 && obj.status <600) {
    error 503 "File is Temporarily Unavailable";
  }

}

sub vcl_deliver {
  if (obj.hits > 0) {
          set resp.http.X-Cache = "HIT";
  } else {
          set resp.http.X-Cache = "MISS";
  }
}
cache ruby-on-rails varnish reverse-proxy
  • 2 2 个回答
  • 10205 Views

2 个回答

  • Voted
  1. Best Answer
    davidsmalley
    2009-07-18T07:55:28+08:002009-07-18T07:55:28+08:00

    好的,最后我设法使用以下 vcl 文件解决了这个问题。请注意,我添加了一些额外的位以在后端死亡时允许缓存过期宽限期。

    似乎我的主要失败是unset req.http.Set-Cookie;在我应该unset obj.http.Set-Cookie;在该vcl_fetch部分中使用时使用。(obj在 vcl_fetch 和reqvcl_recv 部分)。

    director rails_director round-robin {
      { 
        .backend = { 
          .host = "xxx.xxx.xxx.xxx"; 
          .port = "http";
          .probe = {
            .url = "/lbcheck/lbuptest";
            .timeout = 0.3 s;
            .window = 8;
            .threshold = 3;
          }
        } 
      }
    }
    
    sub vcl_recv {
    
      if (req.backend.healthy) {
        set req.grace = 30s;
      } else {
        set req.grace = 1h;
      }
    
      if (req.url ~ "^/login") {
        pipe;
      }
    
      if (req.url ~ "^/sessions") {
        pipe;
      }
    
      if (req.url ~ "\.(css|js|jpg|jpeg|gif|ico|png)\??\d*$") {
        unset req.http.cookie;
        lookup;
      } else {
        if (req.http.cookie ~ "user_credentials") {
          pipe;
        } else {
          unset req.http.cookie;
        }
      }
    
      # Only cache GET and HEAD requests
      if (req.request != "GET" && req.request != "HEAD") {
        pipe;
      }
    
    }
    
    sub vcl_fetch {
    
      set obj.grace = 1h;
    
      if (req.url ~ "^/login") {
        pass;
      }
    
      if (req.url ~ "^/sessions") {
        pass;
      }
    
      if (req.http.cookie ~ "user_credentials") {
        pass;
      } else {
        unset obj.http.Set-Cookie;
      }
    
      # cache CSS and JS files
      if (req.url ~ "\.(css|js|jpg|jpeg|gif|ico|png)\??\d*$") {
        unset obj.http.Set-Cookie;
      } 
    
      if (obj.status >=400 && obj.status <500) {
        error 404 "File not found";
      }
    
      if (obj.status >=500 && obj.status <600) {
        error 503 "File is Temporarily Unavailable";
      }
    
    }
    
    sub vcl_deliver {
      if (obj.hits > 0) {
              set resp.http.X-Cache = "HIT";
      } else {
              set resp.http.X-Cache = "MISS";
      }
    }
    
    • 6
  2. Thiago Figueiro
    2010-06-10T13:26:43+08:002010-06-10T13:26:43+08:00

    我无法发表评论,所以我将其发布为答案。

    注意:从 2.1.0 开始,obj.* 在 vcl_fetch 中被称为 beresp.*,而 obj.* 现在是只读的。

    这些似乎也更好地放置在 vcl_recv 而不是 vcl_fetch 中:

      if (req.url ~ "^/login") {
        pipe;
      }
    
      if (req.url ~ "^/sessions") {
        pipe;
      }
    

    最后,在你的后端定义中,我会添加

    .max_connections = 32;
    

    调整您允许 nginx/apache 创建的乘客后端的数量。如果你没有设置这个限制,你应该留意你的乘客全局队列(假设你正在使用乘客)。

    • 0

相关问题

  • 缩放大文件下载?

  • Gzip 与反向代理缓存

  • 如何禁用tomcat缓存?我遇到了奇怪的静态文件问题

  • mod_mem_cache 提供错误的内容!

  • NFS 缓存导致间歇性滞后

Sidebar

Stats

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

    SFTP 使用什么端口?

    • 6 个回答
  • Marko Smith

    从 IP 地址解析主机名

    • 8 个回答
  • Marko Smith

    如何按大小对 du -h 输出进行排序

    • 30 个回答
  • Marko Smith

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

    • 9 个回答
  • Marko Smith

    Windows 中执行反向 DNS 查找的命令行实用程序是什么?

    • 14 个回答
  • Marko Smith

    如何检查 Windows 机器上的端口是否被阻塞?

    • 4 个回答
  • Marko Smith

    我应该打开哪个端口以允许远程桌面?

    • 9 个回答
  • Marko Smith

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

    • 3 个回答
  • Marko Smith

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

    • 15 个回答
  • Martin Hope
    MikeN 在 Nginx 中,如何在维护子域的同时将所有 http 请求重写为 https? 2009-09-22 06:04:43 +0800 CST
  • Martin Hope
    Tom Feiner 如何按大小对 du -h 输出进行排序 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    0x89 bash中的双方括号和单方括号有什么区别? 2009-08-10 13:11:51 +0800 CST
  • Martin Hope
    kch 如何更改我的私钥密码? 2009-08-06 21:37:57 +0800 CST
  • Martin Hope
    Kyle Brandt IPv4 子网如何工作? 2009-08-05 06:05:31 +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