0

我在 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 不必进行重定向,那么一切正常。有任何想法吗?

4

3 回答 3

1

希望我正确理解了您的问题。我真的不明白 PHPSESSID 与处理 503 错误有何关系,但您根本不需要使用 cookie 来重试请求。

你可以在 Varnish 中使用重启来完成你想要做的事情。例如尝试请求 2 次,你可以这样做:

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

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

这很明显,但我还是要说:你真正应该做的是找出导致 503 错误的原因。如果它们不是来自后端,则它们是由超时或 Varnish 配置问题引起的。密切注意您的 Varnish 日志中的“TxStatus c 503”行,看看请求发生了什么。

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

显然,您在 POST 请求中收到 503 错误(即当用户尝试登录时)。如果帖子是通过慢速链接完成的,或者由于其他原因在 POST 正文完全传输之前客户端终止了连接,则可能会发生这种情况。但是,这不应该像no error recorded在 varnishlog 中那样显示。在任何情况下,您可能都想试一试,看看它是否能解决您的问题。

Varnish 默认为 POST 请求返回(通过),但这并不是在所有情况下都按预期工作(有关更多信息,请参阅Varnish 票证 #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);
}
于 2012-08-30T07:31:13.427 回答
0

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

之后,我们只是将我们想要设置的 cookie 附加到来自后端的已经存在的 cookie 中。

于 2012-08-30T12:48:56.207 回答
-1

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

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

backend www {
    .host = "www.example.com";
    .port = "http";
    .connect_timeout = 500s;    
    .first_byte_timeout = 500s;
    .between_bytes_timeout =500s;
}
于 2012-08-24T21:44:40.863 回答