proxy read timeout закрывает соединение, не получив ответ

nginx_problem nginx-forum at nginx.us
Mon Jan 27 15:58:31 UTC 2014


Добрый день. Столкнулся с проблемой, когда срабатывает proxy_read_timeout
еще до получения какого-либо ответа от бакэнда. 
Ситуация такая: есть скрипт, который отправляет POST данные на локальный
nginx, который проксирует запрос на upstream backend и получает ответ.
Сначала причиной таймаута оказался HTTP/100 Continue. По советам перевел
запрос в HTTP/1.0: в курл добавил опцию curl_setopt($Curl,
CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0), в nginx добавил
proxy_http_version 1.0; При этом apache backend все равно отвечал HTTP/1.1 с
предварительным HTTP/100 Continue. Конфиг апача стандартный. Пришлось
ставить загрушку в виде force-response-1.0 downgrade-1.0 для апача, в итоге
перестал получать HTTP/100 Continue, но проблема с таймаутом не пропала.

часть конфигурации nginx:
    location / {
        proxy_pass http://backend/;
        proxy_next_upstream error timeout http_500 http_502 http_503
http_504;
        proxy_redirect off;
        proxy_buffering off;
        proxy_intercept_errors off;
        reset_timedout_connection on;

        error_page 502 503 504 =403 @error_backend;

        send_timeout            8s;
        proxy_connect_timeout   5s;
        proxy_send_timeout      10s;
        proxy_read_timeout      12s;
        client_body_timeout     20s;

        proxy_http_version 1.0;

        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        add_header  X-Upstream  $upstream_addr;
    }

    location @error_backend {
        return 403 $upstream_addr;
    }


для воспроизведения ошибки без посторонних факторов на бакэнде сделал
скрипт
<?php sleep(20); ?>
отправил 450 байт данных через POST и записал пакеты через tcpdump.
вот что получилось (ip1 - nginx, ip2 - apache backend):
1	0.000000	ip1	ip2	TCP	17433 > http [SYN] Seq=0 Win=14600 Len=0 MSS=1460
WS=7
2	0.097472	ip2	ip1	TCP	http > 17433 [SYN, ACK] Seq=0 Ack=1 Win=5840 Len=0
MSS=1460 WS=7
3	0.097577	ip1	ip2	TCP	17433 > http [ACK] Seq=1 Ack=1 Win=14720 Len=0
4	0.097655	ip1	ip2	HTTP	POST /script.php HTTP/1.0 
(application/x-www-form-urlencoded)
5	0.195452	ip2	ip1	TCP	http > 17433 [ACK] Seq=1 Ack=685 Win=7296 Len=0
6	12.067504	ip1	ip2	TCP	17433 > http [FIN, ACK] Seq=685 Ack=1 Win=14720
Len=0
7	12.206336	ip2	ip1	TCP	http > 17433 [ACK] Seq=1 Ack=686 Win=7296 Len=0
8	20.196969	ip2	ip1	HTTP	HTTP/1.0 200 OK  (text/html)
9	20.197196	ip2	ip1	TCP	http > 17433 [FIN, ACK] Seq=194 Ack=686 Win=7296
Len=0
10	23.195793	ip2	ip1	HTTP	[TCP Retransmission] HTTP/1.0 200 OK  (text/html)
11	29.195275	ip2	ip1	HTTP	[TCP Retransmission] HTTP/1.0 200 OK  (text/html)

апач после того, как принял POST, ответил нормальным ACK, и nginx судя по
всему с этого момента начинает отсчет proxy_read_timeout, но ведь никаких
данных от бакэнда принято еще не было.

Подскажите, нормальная ли это работа proxy_read_timeout и он действительно
включается даже после TCP флагов от бакэнда, либо это какой-то глюк?

Posted at Nginx Forum: http://forum.nginx.org/read.php?21,246872,246872#msg-246872



Подробная информация о списке рассылки nginx-ru