Varnish 3.0.2 到 Apache2 有时会返回错误 503

Varnish 3.0.2 到 Apache2 有时会返回错误 503

嘿伙计们,我希望你们能帮助我。

我有一个 Ngingx,它解析 http 和 https 到 varnish 缓存(3.0.2)。从 varnish 发送到 apache2。现在,我已经跟踪一些奇怪的 503 错误一段时间了。但我似乎找不到灵丹妙药。

目前,我正在通过 varnish 记录 503 错误,方式如下:

sudo varnishlog -c -m TxStatus:503 >> /home/rj/varnishlog503.log

然后参考 apache 访问日志查看是否已处理任何 503 请求。

今天我进行了一次防火墙健康检查,结果失败了:

20 SessionOpen  c 127.0.0.1 34319 :8081
20 ReqStart     c 127.0.0.1 34319 607335635
20 RxRequest    c HEAD
20 RxURL        c /health-check
20 RxProtocol   c HTTP/1.0
20 RxHeader     c X-Real-IP: 192.168.3.254
20 RxHeader     c Host: 192.168.3.189
20 RxHeader     c X-Forwarded-For: 192.168.3.254
20 RxHeader     c Connection: close
20 RxHeader     c User-Agent: Astaro Service Monitor 0.9
20 RxHeader     c Accept: */*
20 VCL_call     c recv lookup
20 VCL_call     c hash
20 Hash         c /health-check
20 VCL_return   c hash
20 VCL_call     c miss fetch
20 Backend      c 33 aurum aurum
20 FetchError   c http first read error: -1 11 (No error recorded)
20 VCL_call     c error deliver
20 VCL_call     c deliver deliver
20 TxProtocol   c HTTP/1.1
20 TxStatus     c 503
20 TxResponse   c Service Unavailable
20 TxHeader     c Server: Varnish
20 TxHeader     c Content-Type: text/html; charset=utf-8
20 TxHeader     c Retry-After: 5
20 TxHeader     c Content-Length: 879
20 TxHeader     c Accept-Ranges: bytes
20 TxHeader     c Date: Wed, 06 Jun 2012 12:35:12 GMT
20 TxHeader     c X-Varnish: 607335635
20 TxHeader     c Age: 60
20 TxHeader     c Via: 1.1 varnish
20 TxHeader     c Connection: close
20 Length       c 879
20 ReqEnd       c 607335635 1338986052.649786949 1338986112.648169994 0.000160217 59.997980356 0.000402689

现在后端服务器(apache)在访问日志中没有任何 503 错误。所以我很困惑。这个 varnish 抛出 503 错误是因为它认为 apache 太慢了吗?此时有大量流量通过,所以我知道服务器已启动并正在运行。

我确实在发帖和获取时遇到了其他 503 错误代码,所以实际上没有规律。它似乎是在随机时间和随机请求中发生的。即使是在早上,当服务器似乎什么也没做的时候。

我确实在日志中看到了另一种模式:

4 VCL_call     c recv pass
4 VCL_call     c hash
4 Hash         c /?id=412
4 VCL_return   c hash
4 VCL_call     c pass pass
4 FetchError   c no backend connection
4 VCL_call     c error deliver
4 VCL_call     c deliver deliver

这里 fetcherror 表示“没有后端连接”。今天日志中的 FetchErrors 总结:

16 FetchError   c http first read error: -1 11 (No error recorded)
 5 FetchError   c http first read error: -1 11 (No error recorded)
 4 FetchError   c http first read error: -1 11 (No error recorded)
19 FetchError   c http first read error: -1 11 (No error recorded)
 5 FetchError   c http first read error: -1 11 (No error recorded)
23 FetchError   c http first read error: -1 11 (No error recorded)
24 FetchError   c http first read error: -1 11 (No error recorded)
16 FetchError   c http first read error: -1 11 (No error recorded)
 6 FetchError   c http first read error: -1 11 (No error recorded)
 4 FetchError   c http first read error: -1 11 (No error recorded)
 5 FetchError   c http first read error: -1 11 (No error recorded)
 4 FetchError   c http first read error: -1 11 (No error recorded)
 4 FetchError   c http first read error: -1 11 (No error recorded)
22 FetchError   c http first read error: -1 11 (No error recorded)
 6 FetchError   c http first read error: -1 11 (No error recorded)
21 FetchError   c http first read error: -1 11 (No error recorded)
26 FetchError   c no backend connection
 4 FetchError   c no backend connection
20 FetchError   c http first read error: -1 11 (No error recorded)
39 FetchError   c http first read error: -1 11 (No error recorded)

我没有更改 varnish 的默认超时值。这是我对其中一个后端服务器的配置。

backend xenon {
    .host = "192.168.3.187";
    .port = "80";
    .probe = {
        .url = "/health-check/";
        .interval = 3s;
        .window = 5;
        .threshold = 2;
    }
}

我在 apache2 上运行 prefork 模块,配置如下

<IfModule mpm_prefork_module>
    StartServers          1
    MinSpareServers       2
    MaxSpareServers       5
    MaxClients           200
    MaxRequestsPerChild  75
</IfModule>

并且只有 PHP 文件会被发送到服务器。其他所有静态文件均由 Nginx 处理。

有任何想法吗?

- - - - 编辑 - - - - - - -

更多调试信息

我已经运行了 varnishadm debug.health

Backend radon is Healthy
Current states  good:  5 threshold:  2 window:  5
Average responsetime of good probes: 0.002560
Oldest                                                    Newest
================================================================
4444444444444444444444444444444444444444444444444444444444444444 Good IPv4
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Good Xmit
RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR Good Recv
HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH Happy
Backend xenon is Healthy
Current states  good:  5 threshold:  2 window:  5
Average responsetime of good probes: 0.002760
Oldest                                                    Newest
================================================================
4444444444444444444444444444444444444444444444444444444444444444 Good IPv4
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Good Xmit
RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR Good Recv
HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH Happy
Backend iridium is Healthy
Current states  good:  5 threshold:  2 window:  5
Average responsetime of good probes: 0.000849
Oldest                                                    Newest
================================================================
4444444444444444444444444444444444444444444444444444444444444444 Good IPv4
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Good Xmit
RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR Good Recv
HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH Happy
Backend aurum is Healthy
Current states  good:  5 threshold:  2 window:  5
Average responsetime of good probes: 0.002100
Oldest                                                    Newest
================================================================
4444444444444444444444444444444444444444444444444444444444444444 Good IPv4
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Good Xmit
RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR Good Recv
HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH Happy

我一直在从两个负载均衡器监控 varnishstat

 3224774         3.99         2.61 backend_conn - Backend conn. success
      27         0.00         0.00 backend_unhealthy - Backend conn. not attempted
      63         0.00         0.00 backend_fail - Backend conn. failures
  358798         0.00         0.29 backend_reuse - Backend conn. reuses
   21035         0.00         0.02 backend_toolate - Backend conn. was closed
  379834         0.00         0.31 backend_recycle - Backend conn. recycles
      26         0.00         0.00 backend_retry - Backend conn. retry

3217751         5.99         2.61 backend_conn - Backend conn. success
      32         0.00         0.00 backend_fail - Backend conn. failures
  364185         0.00         0.30 backend_reuse - Backend conn. reuses
   27077         0.00         0.02 backend_toolate - Backend conn. was closed
  391263         0.00         0.32 backend_recycle - Backend conn. recycles
      36         0.00         0.00 backend_retry - Backend conn. retry

请注意,它们都没有报告 backend_fail。

/罗尼

答案1

我在使用 Apache 时遇到了这个问题,解决方案是以下方法的组合(请注意,我在 AWS EC2 中的 Ubuntu 14.04 LTS 上使用 Apache/2.4.7(Ubuntu)+ varnish 3.0.5-2):

请记住,这是为 Amazon EC2 上的 M3.Medium 实例(1x Intel Xeon E5-2670 核心 + 3.75GB RAM)制作的。请根据您的硬件进行必要的调整!

  1. 在 中/etc/default/varnish,编辑您的启动选项:

     DAEMON_OPTS="-a :80 \
         -T localhost:6082 \
         -f /etc/varnish/default.vcl \
         -S /etc/varnish/secret \
         -p thread_pools=2 \
         -p thread_pool_max=600 \
         -p listen_depth=1024 \
         -p lru_interval=900 \
         -p connect_timeout=600 \
         -p max_restarts=6 \
         -s malloc,1G"
    
  2. 在您的 VCL 中/etc/varnish/default.vcl或无论什么中,更改后端超时(请注意,我们也在 /etc/default/varnish 中设置这些):

    backend default {
        .host = "127.0.0.1";
        .port = "8000";
        .connect_timeout = 600s;
        .first_byte_timeout = 600s;
        .between_bytes_timeout = 600s;
    }
    
  3. 禁用 KeepAlives。此页面有更多信息(因后端 Web 服务器软件而异):http://www.feedthebot.com/pagespeed/keep-alive.html

对于 Apache,我所要做的就是将第 92 行更改为/etc/apache2/apache2.conf以下内容:

    KeepAlive Off

我认为这里发生的原因是,后端 Web 服务器软件中实现的 KeepAlive 正在发送显式连接重置,而 Varnish 无法很好地处理这种情况。这个故事可能还有更多内容,我鼓励您深入研究并在此处发布您的发现,以供后代学习。

补充阅读:-https://www.varnish-cache.org/trac/wiki/Future_Feature#Keepalivetimeoutonbackendconnections (还有一些,但无法发布链接。谷歌搜索“varnish keepalive backend timeout”应该会找到你想要的)

更多调试帮助:如果您仍然遇到问题,请尝试执行以下操作: -varnishlog -w err.log从您的 Varnish 服务器上启动 - 在您的客户端上,获取 Siege:http://www.joedog.org/siege-home/并加载一些你见过 503 的 URL(提示:urls.txt,使用-i -b -c500 -r10就足以触发 503)- start varnishlog -r temp -c -m 'TxStatus:503' > err-parsed.txt。这将抓取所有 Varnish 返回 503 的 Varnish 日志条目。FWIW,这是我的一个错误的全文。TL;DR Varnish 报告的错误是FetchError c http first read error: -1 0 (Success)


936 SessionOpen c 10.8.226.98 51895 :80 936 ReqStart c 10.8.226.98 51895 357447130 936 RxRequest c GET 936 RxURL c /ip/69.120.68.54 936 RxProtocol c HTTP/1.1 936 RxHeader c Host: 10.201.81.157 936 RxHeader c Accept: */* 936 RxHeader c Accept-Encoding: gzip 936 RxHeader c User-Agent: Mozilla/5.0 (apple-x86_64-darwin11.4.2) Siege/3.0.5 936 RxHeader c Connection: close 936 VCL_call c recv lookup 936 VCL_call c hash 936 Hash c /ip/69.120.68.54 936 Hash c 10.201.81.157 936 VCL_return c hash 936 HitPass c 357445183 936 VCL_call c pass pass 936 Backend c 103 default default 936 FetchError c http first read error: -1 0 (Success) 936 Backend c 269 default default 936 FetchError c http first read error: -1 0 (Success) 936 VCL_call c error deliver 936 VCL_call c deliver deliver 936 TxProtocol c HTTP/1.1 936 TxStatus c 503 936 TxResponse c Service Unavailable 936 TxHeader c Server: Varnish 936 TxHeader c Content-Type: text/html; charset=utf-8 936 TxHeader c Retry-After: 5 936 TxHeader c Content-Length: 418 936 TxHeader c Accept-Ranges: bytes 936 TxHeader c Date: Thu, 05 Jun 2014 23:05:48 GMT 936 TxHeader c X-Varnish: 357447130 936 TxHeader c Age: 0 936 TxHeader c Via: 1.1 varnish 936 TxHeader c Connection: close 936 Length c 418

希望这可以帮助!

答案2

如果这是一台繁忙的服务器,我假设是这样,因为您说“此时有很多流量通过,所以我知道服务器正在运行”,您是否首先评估了您的 apache 配置是否能够处理流量涌入?其次,您正在使用 nginx 代理请求到 varnish,您是否为请求设置了重试值?例如,当使用 apache proxypass 时,您可以执行以下操作

ProxyPass / http://192.1.1.11:9001/ retry=3 timeout=5

这将使代理对这些请求不进行重试。为 nginx 找到与此等效的方法。这可能有助于减少 503 的数量,但是如果这是流量问题,则最终需要解决该问题。此外,您可能希望考虑使用 haproxy 而不是 nginx 进行代理,因为这是它的目的。

答案3

503 表示没有可用的健康后端。Apache 没有在超时或 200 内响应探测

varnishadm 后端.健康

可以提供后端健康状态。这就是为什么你的 Apache 日志没有记录 503 的原因

答案4

我希望这是打字错误,但您提到访问日志中没有错误?错误应该在错误日志中(-:如果您还没有检查,请检查那里?该文件名为error_log。另外,请检查您的httpd.conf错误日志级别。尝试将其设置为debug,然后重新启动以查看错误日志中的更多详细信息。我相信默认值是warn。请注意,调试会带来性能开销,因此请执行此操作,直到您拥有必要的数据并将其设置回warn

另一个需要考虑的事项是增加/调整一些 prefork 设置。如果您看到大量流量通过,则这些设置太低了 - 在我看来。以下是我的 RHEL 6.1、apache 2.2 上的默认设置:

<IfModule prefork.c>
    StartServers            8
    MinSpareServers         5
    MaxSpareServers        20
    ServerLimit           256
    MaxClients            256
    MaxRequestsPerChild  4000
</IfModule>

最佳设置取决于您的 Apache 安装和正在运行的硬件——内存、CPU 等。我将从逐渐增加前三个开始。请参阅Apache MPM 预分叉有关这些参数的更多信息。

相关内容