清漆不发送PHPSESSID cookie

时间:2012-08-24 07:17:55

标签: php apache cookies varnish varnish-vcl

我在Apache2 + PHP 5.3服务器前运行Varnish 3.0。我的问题是Varnish抛出了许多503 Service Unavailable错误,所以我添加了一个解决方法,说出类似的内容:

if http_code = 503 and cookie(REDIRECTED) = false
  set-cookie REDIRECTED=true
  header 307 redirect to same page // try again, maybe this time it doesn't fail
else if http_code = 503 and cookie(REDIRECTED) = true
  header 503 // we tried, but the server doesn't want to

这是我所做的主要想法的伪代码草图。但是,在进行307重定向时,不会发送apache在Set-Cookie标头中发送的cookie。我主要担心的是PHPSESSID cookie没有被发送。如果我没有得到503错误而且Varnish不必进行重定向,那么一切正常。有什么想法吗?

3 个答案:

答案 0 :(得分:1)

希望我理解你的问题是正确的。我真的没有看到PHPSESSID与处理503错误有什么关系,但您根本不需要使用cookie来重新尝试请求。

您可以在Varnish中使用重启来完成您要执行的操作。例如,你可以做2次尝试请求:

sub vcl_error {
    if (obj.status == 503 && req.restarts < 2) {
        return (restart);
    }
}

这应该提供您正在寻找的功能,而无需触及cookie。

这很明显,但无论如何我会说:你真正应该做的是找出造成503错误的原因。如果它们不是来自后端,则是由超时或Varnish配置问题引起的。关注“TxStatus c 503”行的清漆日志,看看请求发生了什么。

有关503错误可能原因的更新:

显然,您在POST请求中收到503错误(即,当用户尝试登录时)。如果通过慢速链接完成帖子,或者在POST主体完全传输之前由于某些其他原因终止连接,则会发生这种情况。但是,这不应该在varnishlog中显示为no error recorded。在任何情况下,您可能想要提供以下内容,以确定它是否能解决您的问题。

Varnish默认返回(传递)POST请求,但在所有情况下都不能按预期工作(有关详细信息,请参阅Varnish ticket #849)。

我们已选择管道所有POST请求,并将X-Forwarded-For附加到请求中。这是相关的VCL:

# PIPE all POST requests

sub vcl_recv {
 if (req.request == "POST") {
   return (pipe);
 }
}

# Set XFF for piped requests

sub vcl_pipe {
  set bereq.http.Connection = "close";
  set bereq.http.X-Forwarded-For = req.http.X-Forwarded-For;
  if (bereq.http.x-forwarded-for) {
    set bereq.http.X-Forwarded-For = bereq.http.X-Forwarded-For + ", " + client.ip;
  } else {
    set bereq.http.X-Forwarded-For = client.ip;
  }
  return (pipe);
}

答案 1 :(得分:0)

我们解决这个问题的唯一方法是安装一个名为vmod-headers的清漆模块,它允许您将标头附加到其他标头。

之后我们只是将我们想要设置的cookie附加到来自后端的现有cookie中。

答案 2 :(得分:-1)

默认的vcl不应删除任何cookie,也不应缓存没有缓存头的任何页面。

你从清漆中获得503的原因是因为你的apache没有及时响应。如果您希望它更宽容,您可以为后端更改以下设置(下面非常高):

backend www {
    .host = "www.example.com";
    .port = "http";
    .connect_timeout = 500s;    
    .first_byte_timeout = 500s;
    .between_bytes_timeout =500s;
}