php - 如何从 Varnish 缓存中删除 PHPSESSIONID

标签 php linux apache varnish varnish-vcl

我对特定网站的 Varnish 和其他网站的 Varnish 一直存在问题(按照 Varnish -wordpress的官方指南工作正常)https://www.varnish-software.com/blog/step-step-speed-wordpress-varnish-software

在同一台服务器上有其他站点(没有cms),该站点在 Varnish 缓存方面存在问题,在标题中显示最大年龄= 0,所以没有缓存,可能是因为有一个cookie PHPSESSIONID,我已经在线测试了每个指南,但没有解决方案。

这是我的标题:

HTTP/1.1 200 OK
Server: Apache/2.2.27 (Unix) mod_ssl/2.2.27 OpenSSL/1.0.1e-fips
X-Powered-By: PHP/5.4.27
Set-Cookie: PHPSESSID=xxxxxxxxxxxxxxxxxxxxxx; path=/
Content-Type: text/html
Content-Length: 40627
Accept-Ranges: bytes
Date: Sat, 27 Jun 2015 10:56:14 GMT
X-Varnish: 1838947681
Age: 0
Via: 1.1 varnish
Connection: keep-alive

这是我的default.vcl:

# This is a basic VCL configuration file for varnish.  See the vcl(7)
# man page for details on VCL syntax and semantics.
# 
# Default backend definition.  Set this to point to your content
# server.
# 
backend default {
  .host = "127.0.0.1";
  .port = "82";
}
# 
# Below is a commented-out copy of the default VCL logic.  If you
# redefine any of these subroutines, the built-in logic will be
# appended to your code.
# sub vcl_recv {
#     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 || req.http.Cookie) {
#         /* Not cacheable by default */
#         return (pass);
#     }
#     return (lookup);
# }
# 
# sub vcl_pipe {
#     # Note that only the first request to the backend will have
#     # X-Forwarded-For set.  If you use X-Forwarded-For and want to
#     # have it set for all requests, make sure to have:
#     # set bereq.http.connection = "close";
#     # here.  It is not set by default as it might break some broken web
#     # applications, like IIS with NTLM authentication.
#     return (pipe);
# }
# 
# sub vcl_pass {
#     return (pass);
# }
# 
# sub vcl_hash {
#     hash_data(req.url);
#     if (req.http.host) {
#         hash_data(req.http.host);
#     } else {
#         hash_data(server.ip);
#     }
#     return (hash);
# }
# 
# sub vcl_hit {
#     return (deliver);
# }
# 
# sub vcl_miss {
#     return (fetch);
# }
# 
# sub vcl_fetch {
#     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);
#     }
#     return (deliver);
# }
# 
# sub vcl_deliver {
#     return (deliver);
# }
# 
# sub vcl_error {
#     set obj.http.Content-Type = "text/html; charset=utf-8";
#     set obj.http.Retry-After = "5";
#     synthetic {"
# <?xml version="1.0" encoding="utf-8"?>
# <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
#  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
# <html>
#   <head>
#     <title>"} + obj.status + " " + obj.response + {"</title>
#   </head>
#   <body>
#     <h1>Error "} + obj.status + " " + obj.response + {"</h1>
#     <p>"} + obj.response + {"</p>
#     <h3>Guru Meditation:</h3>
#     <p>XID: "} + req.xid + {"</p>
#     <hr>
#     <p>Varnish cache server</p>
#   </body>
# </html>
# "};
#     return (deliver);
# }
# 
# sub vcl_init {
#   return (ok);
# }
# 
# sub vcl_fini {
#   return (ok);
# }

一些设置如下: 1)

sub vcl_recv {
    // Remove all cookies except the session ID.
    if (req.http.Cookie) {
        set req.http.Cookie = ";" + req.http.Cookie;
        set req.http.Cookie = regsuball(req.http.Cookie, "; +", ";");
        set req.http.Cookie = regsuball(req.http.Cookie, ";(PHPSESSID)=", "; \1=");
        set req.http.Cookie = regsuball(req.http.Cookie, ";[^ ][^;]*", "");
        set req.http.Cookie = regsuball(req.http.Cookie, "^[; ]+|[; ]+$", "");

        if (req.http.Cookie == "") {
            // If there are no more cookies, remove the header to get page cached.
            remove req.http.Cookie;
        }
    }
}

2)

sub vcl_fetch {
  if (!(beresp.http.Set-Cookie ~ "LOGIN") && !(req.http.cookie ~ "LOGIN")) {
    unset beresp.http.Pragma;
    unset beresp.http.Set-Cookie;
    set beresp.http.Cache-Control = "public; max-age=1800";
    unset beresp.http.Expires;
    set beresp.ttl = 30m;
    return (deliver);
  }
}

sub vcl_recv {
  if (req.http.Cookie ~ "LOGIN") {
    set req.http.Cookie = ";" req.http.Cookie;
    set req.http.Cookie = regsuball(req.http.Cookie, "; +", ";");
    set req.http.Cookie = regsuball(req.http.Cookie, ";(PHPSESSID|LOGIN)=", "; 1=");
    set req.http.Cookie = regsuball(req.http.Cookie, ";[^ ][^;]*", "");
    set req.http.Cookie = regsuball(req.http.Cookie, "^[; ]+|[; ]+$", "");
    if (req.http.Cookie == "") {
      remove req.http.Cookie;
    }
  } else {
    remove req.http.Cookie;
  }
}

还有这个:https://www.varnish-cache.org/trac/wiki/VCLExampleRemovingSomeCookies

还有其他想法吗?

最佳答案

就我而言,这是由变化 header 引起的。

变化:接受编码 会为每个不同的accept编码头创建不同的缓存对象

变化:用户代理 将为每个不同的用户代理创建不同的缓存对象

对此的一个很好的解释可以在 https://www.maxcdn.com/blog/accept-encoding-its-vary-important/ 找到。

当您仅在 Accept-encoding 上更改 header 时,请务必使用以下代码在 vcl_rcv 中对其进行规范化。 如 https://www.varnish-cache.org/docs/3.0/tutorial/vary.html 中所述

### parse accept encoding rulesets to normalize
if (req.http.Accept-Encoding) {
    if (req.url ~ "\.(jpg|jpeg|png|gif|gz|tgz|bz2|tbz|mp3|ogg|swf|mp4|flv)$") {
        # don't try to compress already compressed files
        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 {
        # unkown algorithm
        remove req.http.Accept-Encoding;
    }
}

关于php - 如何从 Varnish 缓存中删除 PHPSESSIONID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31088129/

相关文章:

PHP 版本 "market share"

java - 如何使用类路径在Linux终端中运行java程序

c++ - 检查终端中的参数

java - 对于java应用程序的web服务,apache或tomcat apache哪个更好?

apache - 从tomcat上的jira应用程序中删除url

linux - 需要帮助在 CentOS 5.5 上设置 Apache,得到 403

php - Symfony 3 - 编辑表单 - 用数据库数据(数组)填充字段

php - 尝试使用动态创建的表单更新数据库中的日期

php - 在 Laravel Supervisor 中使用多个排队作业的 Mysql 死锁

linux - 如何在我的 LKM 和 Linux 内核之间同步共享数据结构?