Maxim Dounin Wrote:
-------------------------------------------------------
> Hello!
>
> Где-то тут общение с бекендом завершено, однако ответ ещё не
> полностью отправлен клиенту. В процессе отправки клиенте
> закрывает HTTP/2 stream:
Кстати да, я немного не досмотрел. В этом server {} не используется listen http2. Но, в логах наблюдается именно http/2.0 и в хроме видно h2 в консоли разработчика. Не могли бы вы подсказать, насколько это адекватно?
> При этом в функции ngx_http_terminate_request(), которая обновляет
> статус запроса тогда и только тогда, когда статус либо ещё не
> стоит, либо клиенту вообще ничего не было отправлено. В данном
> случае, видимо, за счёт использования HTTP/2 случается ситуация,
> когда клиенту вообще ничего не отправлено (вероятно, за счёт
> других данных в соединении), и статус таки обновляется на 499.
>
> Ситуация с $upstream_status "-", видимо, получается похожим
> образом: если в процессе работы с бекендом клиент отменяет HTTP/2
> stream, то у соответствующей этому stream'у структуре соединения
> будет проставлен флаг c->error. И если после этого случается
> timeout бекенда, то в ngx_http_upstream_next() nginx, увидев
> стоящий флаг c->error, не пойдёт на следующий бекенд, а вместо
> этого завершит обработку запроса с кодом 499.
>
> То есть я был неправ, получить в логах 499 при использовании
> proxy_ignore_client_abort таки можно, хотя и непросто. В простых
> случаях это в основном затрагивает HTTP/2, но и в HTTP/1.x можно
> получить похожее поведение, например, при использовании
> подзапросов.
>
> На практике при использовании proxy_ignore_client_abort это
> означает, что работа с бекендом завершена или не начиналась.
>
> Возвращаясь к исходному вопросу: да, текущее поведение выглядит
> нормально.
Постараюсь описать ситуацию. Мы пытаемся выгружать эти логи в clickhouse для анализа latency и работы бекендов в целом, и сбора разнообразной статистики. Для этого на выходе у нас ожидается, что переменные (после парсинга это массивы в нашем случае) $upstream_addr, $upstream_response_time и $upstream_status имеют одну длину. Но, как показала практика, это не всегда так. В связи с этим ещё один, вероятно последний, вопрос. Есть ли возможность сделать это поведение более предсказуемым? Или проще добавлять недостающие элементы массива в процессе обработки (по сути угадывая, что там должно быть)?