《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进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




