go - PHP cURL随机超时,接收到100%的正文

标签 go nginx curl

我们有一个应用程序,其中约有50个带有PHP代码的前端服务器,这些应用程序通过guzzle库通过nginx以100ms超时,总共向GO API服务器提供15-25k HTTP RPS。有时(每天随机几次),我们看到500-10k RPS因PHP前端服务器日志中的curl timeout错误而失败。日志中的所有异常如下所示:
cURL error 28: Operation timed out after 100 milliseconds with 143 out of 143 bytes received

最有趣的部分是,它始终是收到的100% out of 100%字节,从来没有100 of 1020 of 70。因此,PHP接收到完整的正文(我们可以肯定,因为当我们通过CLI curl重播这些请求时,其大小始终等于失败的响应正文大小)。

当我们开始在nginx访问日志中跟踪这些超时的请求时,我们看到,每个请求均由上游服务(Go API)在1ms(平均)内成功处理,并由nginx立即返回。 Nginx访问日志:
GET [path] HTTP/1.1" 200 228 "-" [...] request_time: 0.001 upstream_addr: [addr] upstream_response_time: 0.001 upstream_status: 200
当我与开发人员交谈时,

  • nginx已针对最大客户端(数百万个连接)进行了调整;
  • Go服务中响应时间的第99个百分点<1ms;

  • 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 "";
    }
    

    GO 1.13版。 net/http用于服务客户。该服务没有外部依赖项(数据库,缓存等),它只是根据输入数据为传入请求计算哈希。

    PHP 7.2.0版使用guzzlehttp/guzzle@5.3.4 HTTP客户端

    最佳答案

    在负载平衡器上,当请求完成时,您应强制关闭连接

    backend nodes
      ...
      option forceclose
      ...
    

    这样,负载平衡器将在看到响应传输时关闭连接

    https://cbonte.github.io/haproxy-dconv/1.7/configuration.html#option%20forceclose

    关于go - PHP cURL随机超时,接收到100%的正文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60174136/

    相关文章:

    interface - 任意接口(interface)列表中哪些接口(interface)满足?

    nginx - Openresty/nginx ngx.say() 开始下载

    php - guzzle,如何在多部分/表单数据中强制内容类型

    java - 带有 Spring Boot 和 Spring Data Neo4j 的 REST API

    php - 使用 cURL 和 Mailchimp API v3 更新列表中的订阅者

    Golang (Go) AES CBC 密文由于某种原因被填充了 16 个 0x00 字节

    go - 使用 Go Web 语言提供静态内容

    http - 在不使用内容长度的情况下禁用分块传输编码

    ssl - Jelastic Nginx http 到 https 重定向

    nginx - 如何增加页面超时以防止504错误?