3

nginx 反代高并发时,偶尔出现 upstream timed out 该怎么排查原因?

 1 year ago
source link: https://www.v2ex.com/t/883940
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

V2EX  ›  程序员

nginx 反代高并发时,偶尔出现 upstream timed out 该怎么排查原因?

  kisshere · 13 小时 5 分钟前 · 2041 次点击

高并发状态下,error_log 偶尔出现:

upstream timed out (110: Connection timed out) while reading response header from upstream

因为是偶尔出现这个 time out, 我自己访问又没有任何问题,所以不知道该怎么排查,是 upstream 服务器请求太多处理不过来?还是反代服务器和 upstream 服务器网络连接有问题,还是反代服务器 nginx 配置问题?

so 上给出的最高赞答案: https://stackoverflow.com/questions/18740635/nginx-upstream-timed-out-110-connection-timed-out-while-reading-response-hea 把 proxy_read_timeout 加大就可以了,感觉完全是治标不治本啊

nginx 能不能设置一个超过 time out 就自动再向 upstream 服务器重新发送请求的功能?

26 条回复    2022-09-30 14:13:19 +08:00
seers

seers      13 小时 1 分钟前

proxy_next_upstream 配置看看
justest123

justest123      12 小时 42 分钟前   ❤️ 1

以前学 Nginx 的时候收藏的一篇博客[TCP SOCKET 中 backlog 参数的用途是什么?]( https://www.cnxct.com/something-about-phpfpm-s-backlog/),其中提到过上游服务 backlog 过大的情况下,可能来不及处理,导致 Nginx 超时报 110 (提一个思路,不一定是这个问题
picone

picone      12 小时 42 分钟前   ❤️ 9

首先要理解这个错误,请求分 3 个阶段,连接,写,读,这个错误意思是读的时候超时了。那错误本身就是从 upstream 读取请求结果超时。我认为的排查方向:
- 找到下游服务对应的日志,看看请求处理时间是多少。经验来说这个问题可能性最大,需要下游增加处理请求超时。
- 网络问题,下游返回回包了,上游没接到,看一下网络 IO 是不是打满了,看一下 TCP 重传的指标。
- 超时重试有 proxy_next_upstream ,但是注意幂等请求。https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_next_upstream
qoo2019

qoo2019      12 小时 39 分钟前

proxy_next_upstream error timeout http_500;
julyclyde

julyclyde      12 小时 13 分钟前

应该是上游处理能力满了
nginx 到上游的连接,在上游的处理能力以外,但还在 backlog 范围内
上游内核会先接受 tcp 连接,等实际服务的程序调用 accept 获得这个链接
redford42

redford42      12 小时 10 分钟前

可以看一下服务器的 tcp 链接是否有丢弃请求的情况
zliea

zliea      11 小时 43 分钟前

upstream 用 keepalive 了么?
zliea

zliea      11 小时 42 分钟前

还需要看是否需要调整后端服务器的连接数。
facelezz

facelezz      10 小时 59 分钟前

@picone 是的 既然都是 reading timeout 那出错的方向 肯定在 nginx 和你的服务上 1.检查 I/O 2.带宽 3.检测丢包情况 4.你的服务偶尔超时 5.proxy_read_timeout 过小(严格上来讲还是属于 4 ) 楼上提到的 proxy_next_upstream 可以让 ng 在这个情况下 重试下一个 upstream 里的节点

经验来说 4 可能性最大,连接数我觉得不需要调整,毕竟是 reading timeout (已经连上了)
facelezz

facelezz      10 小时 57 分钟前

不过 4 的话 你们有 APM 的话 应该很容易发现吧
lambdaq

lambdaq      10 小时 46 分钟前

二楼 @justest123 的回答是对的。就是你代码处理不过来排队了,后面的请求一看卧槽排这么长的队就 gg 了。
lambdaq

lambdaq      10 小时 44 分钟前

有一个思路是 nginx 请求的时候带上一个头比如 proxy_set_header x-nginx-time $time_iso8601;

然后你在代码接到请求里对比一下,看下别人请求在排队的时候蹲了多长时间。
facelezz

facelezz      10 小时 25 分钟前   ❤️ 1

@lambdaq 那也不对吧 backlog 过大是 Connection timed out 过小是 Connection refused 题主的报错不是 reading timeout 么
julyclyde

julyclyde      9 小时 28 分钟前

@facelezz backlog 过大的话是可以建立连接的
建立连接和 backlog 是内核处理的。user space 的是 accept 从已经建立的连接们取一个回来
kisshere

kisshere      8 小时 28 分钟前 via Android

@facelezz 那请问一下,怎么查看当前 Nginx 默认的 proxy_read_timeout 呢?谢谢
lambdaq

lambdaq      8 小时 6 分钟前

@facelezz backlog 过大,已经连上的比如有 1000 个,但是都过了 60s 没能得到 accept(),那么 nginx 还是会 upstream timed out 的。

upstream 其实很多时候压根不知道 nginx 已经放弃请求了,还在那里吭哧吭哧挨个处理队列呢。。。
facelezz

facelezz      7 小时 58 分钟前

@julyclyde
@lambdaq
这就超出我知道的知识了,只是感觉 reading timeout 看上去不像是这个问题

@kisshere 默认好像是 60s 可以 Google 下
julyclyde

julyclyde      7 小时 58 分钟前

@facelezz reading timeout 就是 exactly 这个问题
如果把 backlog 设小一点,早就失败然后下一个了
facelezz

facelezz      7 小时 54 分钟前

@julyclyde 这样吗 学到了~
kisshere

kisshere      7 小时 47 分钟前

@picone 下游服务对应的 error_log 日志只记录了 host 和 referer 还有请求网址,没有处理时间啊?
kisshere

kisshere      7 小时 37 分钟前

@facelezz 查了下默认超时是 60s ,话说你愿意等待一个网页加载超过 60s 么?大多数人等个三四秒没反应就关闭网页了,这个超时时间加长和没加长又有什么区别。。。
picone

picone      7 小时 36 分钟前

@lambdaq 查了一下 nginx 的 backlog 的配置文档:
sets the backlog parameter in the listen() call that limits the maximum length for the queue of pending connections. By default, backlog is set to -1 on FreeBSD, DragonFly BSD, and macOS, and to 511 on other platforms.
这个 backlog 也就是 listen 队列的长度。其实调整这个感觉是治标不治本,相当于更多需要 accept 的连接都没被处理到,如果都 accept 了就是往 upstream 建立更多的连接。upstream 其实是能指定 nginx 放弃请求的,TCP 会 FIN ,对应比如 Go 里面就是 context canceled 。
定位错误的另外一个方法是开启 debug 级别的日志观察一下。
picone

picone      7 小时 34 分钟前

@kisshere 下游服务也是 nginx 服务? 可以查一下下游的 access_log ,如果是对应的请求有 499 的话基本实锤是下游服务的问题了。
感觉你们的日志并没有串起来,建议在最上游的服务搞一个 logid/traceid 之类含义的字段,放 header ,然后全链路都透传这个字段,查日志就能一一对应了。
lambdaq

lambdaq      7 小时 33 分钟前

@picone 这里说的不是 nginx 的 backlog 。说的是响应 nginx 请求的 upstream 的 backlog 。
facelezz

facelezz      7 小时 28 分钟前

@kisshere 不是 这个有的公司会配的很短 你如果没配的话 就没必要改
facelezz

facelezz      7 小时 26 分钟前

我感觉这个少了 APM 和日志链 并不好排查 可以按照上面的提示调整下 backlog 或者配置 proxy_next_upstream 来缓解

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK