闲聊Nginx的超时(timeout)
引言
1.问题出现
前端调用一个线上业务API,报错 504 Gateway Time Out,分析原因:
首先排除业务API的逻辑问题。该API用来做不同系统之间的数据同步,传入不同的参数会同步不同的数据,这些数据有json,也会有打包的静态文件等等。当传入一些牵扯到比较小规模的同步参数时,API调用没有问题。
所以猜测问题应该是同步的数据体积大、打包慢、传输速度慢,导致接口耗时长,触发了某一环节的超时限制。
那么需要逐步排除哪一层限制了超时时间,导致接口还没正常返回就把连接切断了。
2.问题解决
从前端到后端一步步排查:
先让前端取消掉接口的超时限制,发现还是超时,不过这次从浏览器->开发者工具->NetWork中发现一个现象,调用该接口时,会显示pending状态,1分钟后,立即返回504 Gateway Time Out,且每次都可复现。
据此推测,是Nginx中的某个关于代理/调用相关的配置的默认值是1分钟,导致所有接口timeout时间被限制在了1分钟。
查找Nginx文档,找到
- proxy_read_timeout
- proxy_send_timeout
- proxy_connect_timeout
这三个看起来有眼缘的配置默认值恰好是60s。暴力点,直接配置线上Nginx的这三个配置为1200(20分种),再测试,问题解决: )
探索
Nginx的超时(timeout)相关配置
auth相关
设置与认证服务器通信的超时时间。
client相关
定义读取客户端请求正文的超时。仅在两次连续读取操作之间的一段时间内设置超时,而不是为整个请求主体的传输设置超时。如果客户端在此时间内未传输任何内容,则请求会因408(请求超时)错误而终止。
定义用于读取客户端请求标头的超时。如果客户端在此时间内未传输整个标头,则请求会因408(请求超时)错误而终止。
proxy相关
proxy_connect_timeout (ngx_http_proxy_module)
定义与代理服务器建立连接的超时。请注意,此超时通常不能超过75秒。
Syntax: proxy_connect_timeout time;Default: proxy_connect_timeout 60s;Context: http,server,locationproxy_connect_timeout (ngx_stream_proxy_module)
定义与代理服务器建立连接的超时。
Syntax: proxy_connect_timeout time;Default: proxy_connect_timeout 60s;Context: stream,server定义用于从代理服务器读取响应的超时。超时仅在两次连续的读取操作之间设置,而不用于传输整个响应。如果代理服务器在此时间内未传输任何内容,则连接将关闭。
Syntax: proxy_read_timeout time;Default: proxy_read_timeout 60s;Context: http,server,locationproxy_timeout (ngx_stream_proxy_module)
与代理服务器建立连接时,启用或禁用通过TLS服务器名称指示扩展名(SNI)传递服务器名称。
keepalive相关
keepalive_timeout (ngx_http_core_module)
第一个参数设置超时,在此期间,保持活动的客户端连接将在服务器端保持打开状态。
0值将禁用保持活动状态的客户端连接。可选的第二个参数在“ Keep-Alive: timeout=time”响应标头字段中设置一个值。两个参数可能不同。Mozilla和Konqueror可以识别 “ Keep-Alive: timeout=time ” header字段。MSIE会在大约60秒内自行关闭保持活动的连接。Syntax: keepalive_timeout timeout [header_timeout];Default: keepalive_timeout 75s;Context: http,server,locationkeepalive_timeout (ngx_http_upstream_module)
version 1.15.3 + 可用。
设置一个超时,在此超时期间,与上游服务器的空闲keepalive连接将保持打开状态。
Syntax: keepalive_timeout timeout;Default: keepalive_timeout 60s;Context: upstream
grpc相关
定义与gRPC服务器建立连接的超时。请注意,此超时通常不能超过75秒。
限制将请求传递到 上游服务器的时间。该
0值将关闭此限制。
其他
反思
- 有必要记录每次接口的调用用时/参数/IP等信息。
- 接口/业务设计时,要预估这个业务的耗时,耗时可能过长的要做特定处理。
- 要了解Nginx的常用配置
参考
Nginx的所有配置项: Nginx-Directives
