首页 > 解决方案 > 如何使用 client_disconnected_before_any_response 调试失败的请求

问题描述

我们有一个由 kubernetes 入口创建的HTTP(s) 负载均衡器,它指向由一组运行 nginx 和 Ruby on Rails 的 pod 形成的后端。

查看负载均衡器日志,我们检测到越来越多的请求的响应代码为0and statusDetails= client_disconnected_before_any_response

我们正试图了解他为什么会发生这种情况,但我们没有发现任何相关信息。nginx 访问或错误日志中没有任何内容。

这发生在从 GET 到 POST 的多种请求中。

我们还怀疑,有时尽管请求记录了该错误,但请求实际上已传递到后端。例如,我们看到 PG::UniqueViolation 错误,这是由于在我们的注册端点中向后端发送了两次相同的注册请求。

任何形式的帮助将不胜感激。谢谢!


 更新 1

这里要求的是入口资源的 yaml文件:


 更新 2

我创建了一个基于日志的 Stackdriver 指标,以计算呈现此行为的请求数。这是图表:

图表

大峰值与这些 kubernetes 事件的时间戳大致匹配:

事件

完整错误:Readiness probe failed: Get http://10.48.1.28:80/health_check: net/http: request canceled (Client.Timeout exceeded while awaiting headers)"

因此,有时后端后面的 pod 的就绪性探测似乎会失败,但并非总是如此。

这是readinessProbe的定义

readinessProbe:
  failureThreshold: 3
  httpGet:
    httpHeaders:
    - name: X-Forwarded-Proto
      value: https
    - name: Host
      value: [redacted]
    path: /health_check
    port: 80
    scheme: HTTP
  initialDelaySeconds: 1
  periodSeconds: 30
  successThreshold: 1
  timeoutSeconds: 5

标签: kubernetesgoogle-kubernetes-enginekubernetes-ingressgoogle-cloud-networking

解决方案


响应代码 0 和 statusDetails = client_disconnected_before_any_response 表示客户端在负载均衡器能够根据此GCP 文档提供响应之前关闭连接。

调查它为什么没有及时响应,原因之一可能是来自 nginx 和 GCP 负载均衡器的keepalive 超时之间的差异,即使这很可能会提供由502 Bad Gateway 竞争条件引起的 backend_connection_closed_before_data_sent_to_client 。

为了确保后端响应请求并查看是否需要多长时间,您可以重复此过程几次(因为您仍然会得到一些有效的响应):

卷曲响应时间

$ curl -w "@curl.txt" -o /dev/null -s IP_HERE

curl.txt 内容(先创建并保存此文件):

   time_namelookup:  %{time_namelookup}\n
      time_connect:  %{time_connect}\n
   time_appconnect:  %{time_appconnect}\n
  time_pretransfer:  %{time_pretransfer}\n
     time_redirect:  %{time_redirect}\n
time_starttransfer:  %{time_starttransfer}\n
                ----------\n
        time_total:  %{time_total}\n

如果是这种情况,请查看任何类型的循环的注册端点代码,例如您提到的 PG::UniqueViolation 错误。


推荐阅读