Re: Пустая переменная $upstream status при 499
Maxim Dounin
mdounin на mdounin.ru
Пн Янв 13 19:39:16 UTC 2020
Hello!
On Mon, Jan 13, 2020 at 09:39:29AM -0500, yanda.a wrote:
> Да, конечно, единственное что - изменю доменное имя, если вы не против.
Ок, так понятно, что происходит:
> 2020/01/13 02:28:13 [debug] 17855#17855: *29319057 http write filter 00007FF7599D8E48
> 2020/01/13 02:28:13 [debug] 17855#17855: *29319057 gzip in: 0000000000000000
> 2020/01/13 02:28:13 [debug] 17855#17855: *29319057 http copy filter: -2 "/api/epg?from=1578862800&to=1578949199"
> 2020/01/13 02:28:13 [debug] 17855#17855: *29319057 pipe write downstream done
> 2020/01/13 02:28:13 [debug] 17855#17855: *29319057 event timer: 92, old: 7043363034, new: 7043363039
> 2020/01/13 02:28:13 [debug] 17855#17855: *29319057 event timer: 78, old: 7043333034, new: 7043333039
> 2020/01/13 02:28:13 [debug] 17855#17855: *29319057 http upstream exit: 0000000000000000
> 2020/01/13 02:28:13 [debug] 17855#17855: *29319057 finalize http upstream request: 0
> 2020/01/13 02:28:13 [debug] 17855#17855: *29319057 finalize http proxy request
> 2020/01/13 02:28:13 [debug] 17855#17855: *29319057 free rr peer 2 0
> 2020/01/13 02:28:13 [debug] 17855#17855: *29319057 close http upstream connection: 92
Где-то тут общение с бекендом завершено, однако ответ ещё не
полностью отправлен клиенту. В процессе отправки клиенте
закрывает HTTP/2 stream:
> 2020/01/13 02:28:13 [info] 17855#17855: *29319057 client canceled stream 39 while sending to client, client: 176.59.97.91, server: mydomain.info, request: "GET /api/epg?from=1578862800&to=1578949199 HTTP/2.0", upstream: "http://192.168.50.48:8081/api/epg?from=1578862800&to=1578949199", host:"www.mydomain.info", referrer: "https://www.mydomain.info/"
И дальше зовётся ngx_http_test_reading(), который и финализирует
соединение с кодом 499:
> 2020/01/13 02:28:13 [debug] 17855#17855: *29319057 http run request: "/api/epg?from=1578862800&to=1578949199"
> 2020/01/13 02:28:13 [debug] 17855#17855: *29319057 http test reading
> 2020/01/13 02:28:13 [info] 17855#17855: *29319057 client prematurely closed connection while sending to client, client: 176.59.97.91, server: mydomain.info, request: "GET /api/epg?from=1578862800&to=1578949199 HTTP/2.0", upstream: " http://192.168.50.48:8081/api/epg?from=1578862800&to=1578949199", host: "www.mydomain.info", referrer: "https://www.mydomain.info/"
> 2020/01/13 02:28:13 [debug] 17855#17855: *29319057 http finalize request: 499, "/api/epg?from=1578862800&to=1578949199" a:1, c:1
> 2020/01/13 02:28:13 [debug] 17855#17855: *29319057 http terminate request count:1
> 2020/01/13 02:28:13 [debug] 17855#17855: *29319057 http terminate cleanup count:1 blk:0
При этом в функции 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 это
означает, что работа с бекендом завершена или не начиналась.
Возвращаясь к исходному вопросу: да, текущее поведение выглядит
нормально.
--
Maxim Dounin
http://mdounin.ru/
Подробная информация о списке рассылки nginx-ru