暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Nginx代理504错误为何产生,这篇文章告诉你.md

《Nginx代理常见的两个问题,你肯定遇见过》描述了nginx proxy常见的两个http错误(502、504),也通过nginx的access、error日志验证了两种错误,这篇文章更进一步,针对504错误,通过nginx源码和nginx日志进一步挖掘。

1:回顾

再进一步看下nginx配置:

error_log /var/log/error.log debug ;

server {
   
   listen       [::]:8081;
   server_name  _;
   access_log /var/log/access.log upstreamlog;
   location / {
       proxy_pass https://api.test.com;
       proxy_ssl_server_name on;
       proxy_read_timeout 160;
       proxy_connect_timeout 5;
       proxy_buffering off;
   }
}

proxy_buffering是关闭的,主要是代理的upstream支持SSE流协议,需要及时清空缓存区,保持及时的输出。

504发生时候当时的error日志:

2023/11/03 18:28:29 [warn] 17264#17264: *48081 upstream server temporarily disabled while reading response header from upstream, client
2023/11/03 18:28:29 [error] 17264#17264: *48081 upstream timed out (110: Connection timed out) while reading response header from upstream

为了更好的验证问题,把所有的debug信息也打印了出来。

2:通过源码观察

在nginx源码中搜索 upstream server temporarily disabled 错误,在ngx_http_upstream_round_robin.c文件中找到了:

这个max_fails是什么以后再说。

再搜索 upstream timed out 错误,在 ngx_http_upstream.c 中找到了:

ngx_http_upstream_process_non_buffered_upstream函数是关闭buffer后对应的处理函数,NGX_HTTP_GATEWAY_TIME_OUT则是504,验证出现了504错误。

此时很明显说明504是读取超时导致的。

3:通过日志观察

这张图中,结果160s的读取还没有完成,最终就504了。

其中 * 符号后面的是会话号,# 符号后面的是worker进程号,一个查询日志的好办法,先根据某个时间点找到会话号,然后通过会话号找到完整记录。

那么一个正常的请求应该是什么样的呢?由于是SSE请求,可以看到多个 http write filter,如下图:

结论,通过debug日志和源码能够大概了解504问题产生的原因

文章转载自虞大胆的叽叽喳喳,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论