我有一个网站,它查询 Varnish 服务器,它查询 Apache 服务器,它查询 db 服务器。
07:00:00,一个请求被发送到 Apache 服务器,这会触发一个数据库请求,该请求需要 30 多秒才能处理。当数据库服务器处于“锁定”状态时,并发数据库请求会堆积起来,从而导致 Apache 请求也堆积起来。到目前为止,这不是我的问题。
与此同时,Varnish 每 5 秒轮询一次 Apache,超时时间为 1 秒。探测目标是一个空的 html 文件。
Apache 日志告诉我每个轮询都以 200 状态代码答复。
我从 Varnish/Apache 日志组合中获得以下结果:
Polled at Served at Delay (s)
07:00:26 07:00:26 0
07:00:31 07:00:34 3
07:00:37 07:01:01 24
07:00:43 07:01:01 18
07:00:49 07:01:01 12
07:00:55 07:01:01 6
07:01:01 07:01:01 0
07:01:06 07:01:06 0
我不明白的是:
- 鉴于 Apache 处理每个轮询请求,它应该意味着 MaxClients 尚未达到。否则,我猜 Apache 会拒绝任何新的传入轮询请求。我说得对吗?
- 如果 Apache 可以接受轮询请求的连接,为何回复延迟?提供空的 html 文件应该和往常一样快,即使许多并发请求仍在等待数据库“解锁”。时间看起来 Apache 需要以某种方式解锁数据库,并提供服务其他进程,以便它可以处理轮询请求。
延迟导致 Varnish 认为我的服务器“不健康”,从而自动拒绝所有后续请求,而这些请求都可以在 30 秒的延迟内得到处理。
清漆配置:
backend foo {
.timeout = 60s;
.probe = {
.url = "/check.html";
.interval = 5s;
.timeout = 1s;
.window = 10;
.threshold = 8;
}
}
Apache 配置:
Timeout 300
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 15
<IfModule mpm_prefork_module>
StartServers 5
MinSpareServers 5
MaxSpareServers 20
ServerLimit 200
MaxClients 200
MaxRequestsPerChild 0
</IfModule>
不要犹豫,询问更多的配置信息或日志。
答案1
如果所有 http 工作线程都很忙,Apache 确实允许建立待处理连接队列。这由 ListenBackLog 指令控制:
https://httpd.apache.org/docs/current/mod/mpm_common.html#listenbacklog
因此,当所有其他请求备份时,请求可能会进入此队列,从而导致延迟。
我还将启用 /server-status 处理程序并在服务器繁忙时对其进行监控,而不是在服务器已经繁忙时对其进行监控,因为 Apache 将无法提供服务状态页面。
另一个技巧是将 %D 添加到您的访问日志格式中,因为它将告诉您 Apache 从第一次收到请求到完成请求所花费的时间(以微秒为单位)。