Отладка неудачных запросов с помощью client_disconnected_before_any_response

У нас есть HTTP Балансировщик нагрузки, созданный приложением kubernetes, который указывает на бэкэнд, образованный множеством модулей, запускающих nginx и Ruby on Rails.

Взглянув на журналы балансировки нагрузки, мы обнаружили все большее число запросов с кодом ответа 0 и statusDetails= client_disconnected_before_any_response.

Мы пытаемся понять, почему это происходит, но мы не нашли ничего подходящего. В журналах доступа или ошибок nginx ничего нет.

Это происходит для нескольких запросов, от GET до POST.

Мы также подозреваем, что иногда, несмотря на то, что запрос регистрируется с этой ошибкой, запросы фактически передаются на бэкэнд. Например, мы видим ошибки PG :: UniqueViolation, из-за того, что идентификационные запросы для регистрации дважды отправляются на сервер в нашей конечной точке регистрации.

Любая помощь будет оценена по достоинству. Спасибо!


ОБНОВЛЕНИЕ 1

В качестве запрошенного здесь находится файл yaml для входного ресурса:


ОБНОВЛЕНИЕ 2

Я создал метку Stackdriver на основе журнала, чтобы подсчитать количество запросов, которые представляют это поведение. Вот диаграмма:

chart

Большие пики приблизительно соответствуют отметке времени для этих событий кубернетов:

events

Полная ошибка: Readiness probe failed: Get http://10.48.1.28:80/health_check: net/http: request canceled (Client.Timeout exceeded while awaiting headers)"

Так что иногда кажется, что готовность зондов для стручков позади бэкэнда терпит неудачу, но не всегда.

Вот определение готовностиProbe

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

Ответ 1

Код ответа 0 и statusDetails = client_disconnected_before_any_response означает, что клиент закрыл соединение, прежде чем Балансировщик нагрузки сможет предоставить ответ в соответствии с этой документацией GCP.

Исследуя, почему он не ответил вовремя, одной из причин может быть разница между тайм-аутами keepalive от nginx и балансировщиком нагрузки GCP, даже если это будет больше всего похоже на предоставление backend_connection_closed_before_data_sent_to_client, вызванное состоянием гонки 502 Bad Gateway.

Чтобы убедиться, что бэкэнд отвечает на запрос и посмотреть, сколько времени потребуется, вы можете повторить этот процесс пару раз (так как вы все еще получаете некоторые действительные ответы):

время отклика

$ 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, о которых вы упомянули.