PHP cURL 随机超时,收到 100% 的正文
Posted
技术标签:
【中文标题】PHP cURL 随机超时,收到 100% 的正文【英文标题】:PHP cURL randomly timeouts with 100% of body received 【发布时间】:2020-02-11 17:12:26 【问题描述】:我们有一个带有大约 50 个前端服务器的应用程序,其中包含 php 代码,通过使用 guzzle
库的 nginx 与 100 毫秒超时,总共 15-25k HTTP RPS 到 GO API 服务器。有时(随机,一天几次)我们会在 PHP 前端服务器日志中看到 500-10k RPS 失败并出现 curl 超时错误。日志中的所有异常如下所示:
cURL error 28: Operation timed out after 100 milliseconds with 143 out of 143 bytes received
。
最有趣的部分是它总是收到100% out of 100%
字节,从来没有100 of 102
或0 of 70
。所以 PHP 接收到完整的主体(我们对此很确定,因为当我们通过 CLI curl 重放这些请求时,它的大小总是等于失败的响应主体大小)。
当我们开始在 nginx-access 日志中跟踪这些超时请求时,我们看到,上游服务(Go API)在 1 毫秒(平均)内成功处理了每个请求,并由 nginx 毫无延迟地返回。 Nginx 访问日志:
GET [path] HTTP/1.1" 200 228 "-" [...] request_time: 0.001 upstream_addr: [addr] upstream_response_time: 0.001 upstream_status: 200
100ms超时可能是什么问题,在哪里挖掘解决?
UPD:
与客户端连接相关的NGINX配置:
worker_processes 32;
worker_rlimit_nofile 65535;
events
worker_connections 32767;
accept_mutex on;
upstream [service]
server [main] max_fails=0;
server [...] backup max_fails=0;
keepalive 16;
location ^~ /[path]/
proxy_pass http://[service]/;
proxy_http_version 1.1;
keepalive_timeout 30;
keepalive_requests 500;
reset_timedout_connection on;
proxy_set_header Connection "";
转到 1.13 版。 net/http
用于服务客户。该服务没有外部依赖项(数据库、缓存等),它只是根据输入数据计算传入请求的哈希值。
PHP 7.2.0 版本使用guzzlehttp/guzzle@5.3.4
HTTP 客户端
【问题讨论】:
为什么会涉及到 Nginx? @Adrian 因为它被用作从公共客户端到内部 Go 服务的代理 + 负载均衡器。 Go 服务在 3 个实例上运行。 考虑到发生了多少,有很多潜在的故障点,从 Go 代码到 Nginx 配置,再到 PHP 代码,再到任何服务 PHP(nginx 中的 php-fpm ?)。没有看到就不可能说出来。 【参考方案1】:在您的负载均衡器上,您应该在请求完成时强制关闭连接
backend nodes
...
option forceclose
...
通过这样做,负载均衡器将在看到传输的响应时关闭连接
https://cbonte.github.io/haproxy-dconv/1.7/configuration.html#option%20forceclose
【讨论】:
为什么?这个答案没有说明为什么会导致问题。 我们没有 haproxy 作为平衡器,只有 nginx以上是关于PHP cURL 随机超时,收到 100% 的正文的主要内容,如果未能解决你的问题,请参考以下文章