nginx-proxy超时参数解释
先说明下nginx版本是:
nginx version: nginx/1.17.10 (Ubuntu)
配置说明
send_timeout time;
发送数据至客户端超时, 默认60s, 如果连续的60s内客户端没有收到1个字节, 连接关闭
Default: send_timeout 60s;
Context: http, server, location
Sets a timeout for transmitting a response to the client. The timeout is set only between two successive write operations,not for the transmission of the whole response. If the client does not receive anything within this time, the connection is closed.
proxy_connect_timeout time;
nginx与upstream server的连接超时时间
Default: proxy_connect_timeout 60s;
Context: http, server, location
Defines a timeout for establishing a connection with a proxied server. It should be noted that this timeout cannot usually exceed 75 seconds.
proxy_read_timeout time;
nginx接收upstream server数据超时, 默认60s, 如果连续的60s内没有收到1个字节, 连接关闭
Default: proxy_read_timeout 60s;
Context: http, server, location
Defines a timeout for reading a response from the proxied server. The timeout is set only between two successive read operations,not for the transmission of the whole response. If the proxied server does not transmit anything within this time, the connection is closed.
proxy_send_timeout time;
nginx发送数据至upstream server超时, 默认60s, 如果连续的60s内没有发送1个字节, 连接关闭
Default: proxy_send_timeout 60s;
Context: http, server, location
Sets a timeout for transmitting a request to the proxied server. The timeout is set only between two successive write operations,not for the transmission of the whole request. If the proxied server does not receive anything within this time, the connection is closed.
proxy_next_upstream_timeout
nginx请求next upstream的超时时间,默认为0,当为0的时候就是关闭限制,也就是没有超时时间,那这个时候会一直等下去吗? 还是又回到上面的read_timeout,send_timeout这些标准呢?
即在proxy_next_upstream_timeout时间内允许proxy_next_upstream_tries次重试。如果超过了其中一个设置,则Nginx也会结束重试并返回客户端响应。
但是我们知道proxy_next_uptream_tries默认也是0,表示没有限制。那这么看来最后是遵循proxy_send_timeout来的,你proxy_next_uptream再多,最后都是要满足上面的要求。那个时间是有默认值的60秒的。
因此这个参数没看源码,没有测试就是猜测出来是这个结果。后面我们自己测试下看看。
Default: proxy_next_upstream_timeout 0;
Context: http, server, location
Limits the time during which a request can be passed to the next server. The 0 value turns off this limitation.
试验
那就我们来做个试验吧。
后面81和82都只是用nc来监听的。
proxy_send_timeout时间远大于proxy_next_upstream timeout
1 | server { |
1 | HTTP/1.1 504 Gateway Time-out |
很奇怪吧,为什么是60秒啊。好像跟proxy_next_upstream_timeout完全没关系。
而且看到现象是82端口压根就没有请求,只请求了81端口。
下面附上日志
1 | 127.0.0.1 127.0.0.1 - [2020-06-30T22:28:36+08:00] "GET / HTTP/1.1" 504 177 "-" "curl/7.68.0" "-" 60.000|60.000|test|127.0.0.1:82|-|504 |
proxy_read_timeout小于proxy_next_upstream timeout
好了,我们改下配置,把send_timeout和read_timeout都改为6秒,next部分不变
1 | upstream test { |
curl下结果如下:
1 | HTTP/1.1 504 Gateway Time-out |
出乎意料居然是12秒,我们再来看看日志
1 | 127.0.0.1 127.0.0.1 - [2020-06-30T22:38:53+08:00] "GET / HTTP/1.1" 504 177 "-" "curl/7.68.0" "-" 12.002|6.000, 6.001|test|127.0.0.1:81, 127.0.0.1:82|-|504, 504 |
proxy_read_timeout时间*2大于proxy_next_upstream_timeout
2个后端都请求了,每个都是6s。总计时间控制再15秒内。那是不是意味着如果我send_timeout和read_timeout是8秒,最后一次请求是7秒超时呢?
现实又给我们打脸了
1 | server { |
1 | HTTP/1.1 504 Gateway Time-out |
16秒,完全不受next_uptream_timeout的控制啊。日志里也是同样如此:
1 | 127.0.0.1 127.0.0.1 - [2020-06-30T22:43:46+08:00] "GET / HTTP/1.1" 504 177 "-" "curl/7.68.0" "-" 16.002|8.001, 8.001|test|127.0.0.1:82, 127.0.0.1:81|-|504, 504 |
proxy_read_timeout时间等于proxy_next_upstream_timeout*tries
1 | server { |
这次结果如下:
1 | HTTP/1.1 504 Gateway Time-out |
1 | 127.0.0.1 127.0.0.1 - [2020-06-30T23:04:38+08:00] "GET / HTTP/1.1" 504 177 "-" "curl/7.68.0" "-" 8.001|8.001|test|127.0.0.1:82|-|504 |
总结
有上面试验可见 proxy_next_upstream_timeout和proxy_next_upstream_tries是同时使用的,先满足哪个就全部完成。
同时,单次的upstream请求是受proxy_send_timeout和proxy_read_timeout来控制的。proxy_next_upstream_timeout是一个整体的请求后端的累计时间。
proxy_send/proxy_read | proxy_next_upstream_timeout | proxy_next_upstream_tries | 整体请求时间 | upstream请求次数 |
---|---|---|---|---|
8s | 4s | 2 | 8s | 1 |
8s | 15s | 2 | 16s | 2 |
6s | 15s | 2 | 12s | 2 |
60s | 15s | 10 | 60s | 1 |