nginx响应超时的解决办法

最近接手一个新项目,但是其中一个接口却出了问题

网页提示 504 gateway time-out

也没细想,直接更改nginx配置

http{
	fastcgi_connect_timeout 300s;
	fastcgi_send_timeout 300s;
	fastcgi_read_timeout 300s;
	fastcgi_buffer_size 128k;
	fastcgi_buffers 8 128k;
	fastcgi_busy_buffers_size 256k;
	fastcgi_temp_file_write_size 256k;
	fastcgi_intercept_errors on;
	......
}

结果还是出现 504 gateway time-out
查看nginx错误日志,找到原因如下

2019/10/09 08:51:19 [error] 36142#36142: *5938121 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 192.168.16.81, server: serv7.api.ruizhiedu.com, request: "GET /ssp_php/admin/api/searchCompanyInfo HTTP/1.0", upstream: "http://127.0.0.1:8104/admin/api/searchCompanyInfo", host: "192.168.16.38:8103"

原来是nginx代理超时
继续更改nginx配置

server {
    listen       80;
    server_name  XXX.xxxxxx.com;
	large_client_header_buffers 4 128k;# 读取大型客户端请求头的缓冲区的最大数量和大小
	client_max_body_size 300m;#设置nginx能处理的最大请求主体大小。
	client_body_buffer_size 128k;#请求主体的缓冲区大小。 
	proxy_connect_timeout 300;
	proxy_read_timeout 300;
	proxy_send_timeout 300;
	proxy_buffer_size 256k;
	proxy_buffers 4 128k;
	proxy_busy_buffers_size 256k;
	proxy_temp_file_write_size 256k;
	......
	location / {
		uwsgi_send_timeout 300;# 指定向uWSGI传送请求的超时时间,完成握手后向uWSGI传送请求的超时时间。
		uwsgi_connect_timeout 300;# 指定连接到后端uWSGI的超时时间。
		uwsgi_read_timeout 300;# 指定接收uWSGI应答的超时时间,完成握手后接收uWSGI应答的超时时间。
		......
	}

顺利解决超时问题

如下是一些配置说明,从网上摘抄过来的

优化性能参数设置,在ngnix.conf中的http 层加上fastcgi参数如下:

http {
	fastcgi_cache_path  /usr/local/nginx/fastcgi_cache levels=1:2 keys_zone=TEST:10m inactive=5m;
	fastcgi_connect_timeout=300;
	fastcgi_send_timeout=300;
	fastcgi_buffer_size=64k;
	fastcgi_buffers 4 64k;
	fastcgi_busy_buffers_size 128k;
	fastcgi_temp_file_write_size 128k;
	fastcgi_cache TEST;
	fastcgi_cache_valid 200 302 1h;
	fastcgi_cache_valid 301 1d;
	fastcgi_cache_valid any 1m;
}

fastcgi_cache_path /usr/local/nginx/fastcgi_cache levels=1:2 keys_zone=TEST:10m inactive=5m; #缓存路径文件,目录结构等级,关键字区域实际和非活动时间

fastcgi_connect_timeout=300; #连接到后端fastcgi超时时间

fastcgi_send_timeout=300; #向fastcgi请求超时时间(这个指定值已经完成两次握手后向fastcgi传送请求的超时时间)

fastcgi_rend_timeout=300; #接收fastcgi应答超时时间,同理也是2次握手后

fastcgi_buffer_size=64k; #读取fastcgi应答第一部分需要多大缓冲区,该值表示使用1个64kb的缓冲区读取应答第一部分(应答头),可以设置为fastcgi_buffers选项缓冲区大小

fastcgi_buffers 4 64k;#指定本地需要多少和多大的缓冲区来缓冲fastcgi应答请求,假设一个php或java脚本所产生页面大小为256kb,那么会为其分配4个64kb的缓冲来缓存;若页面大于256kb,那么大于的256kb的部分会缓存到fastcgi_temp指定路径中,这并非是个好办法,内存数据处理快于硬盘,一般该值应该为站点中php/java脚本所产生页面大小中间值,如果站点大部分脚本所产生的页面大小为256kb,那么可把值设置为16 16k,4 64k等

fastcgi_busy_buffers_size 128k; #默认值是fastcgi_buffer的2倍

fastcgi_temp_file_write_size 128k;#写入缓存文件使用多大的数据块,默认值是fastcgi_buffer的2倍

fastcgi_cache TEST;#开启fastcgi缓存并为其指定为TEST名称,降低cpu负载,防止502错误发生.

#应答代码缓存时间,200和302应答缓存为1个小时,301一天,其他1分钟

	fastcgi_cache_valid 200 302 1h;
	fastcgi_cache_valid 301 1d;
	fastcgi_cache_valid any 1m;

eg:
这些字句的设置规定了PHP-CGI的连接、发送和读取时间限制,需根据服务器性能及网络流量综合考虑设置,时间设置过长会给网站服务器造成压力,导致网站响应缓慢,甚至服务器宕机;时间设置过短,则会出现504 Gateway Time-out或者其他CGI无响应错误。

还有就是php-fpm.conf中max_children与request_terminate_timeout两个重要参数的设置。这两个参数的设置需要我们根据PHP程序情况及服务器带宽状况综合考虑并计算出合理准确的值,才能够避免504 Gateway Time-out或者其他CGI无响应错误的出现。

正常情况下,一般网站可将request_terminate_timeou设置在900s左右,而max_children值根据服务器内存大小和CGI请求数目设置为合理的数值,一般设置为800M左右。

计算的方式如下:
如果你的服务器性能足够好,且宽带资源足够充足,PHP脚本没有系循环或BUG的话你可以直接将”request_terminate_timeout”设置成0s。0s的含义是让PHP-CGI一直执行下去而没有时间限制。而如果你做不到这一点,也就是说你的PHP-CGI可能出现某个BUG,或者你的宽带不够充足或者其他的原因导致你的PHP-CGI能够假死那么就建议你给”request_terminate_timeout”赋一个值,这个值可以根据你服务器的性能进行设定。一般来说性能越好你可以设置越高,20分钟-30分钟都可以。由于我的服务器PHP脚本需要长时间运行,有的可能会超过10分钟因此我设置了900秒,这样不会导致PHP-CGI死掉而出现502 Bad gateway这个错误。

而”max_children”这个值又是怎么计算出来的呢?这个值原则上是越大越好,php-cgi的进程多了就会处理的很快,排队的请求就会很少。设置”max_children”也需要根据服务器的性能进行设定,一般来说一台服务器正常情况下每一个php-cgi所耗费的内存在20M左右,因此我的”max_children”我设置成40个,20M*40=800M也就是说在峰值的时候所有PHP-CGI所耗内存在800M以内,低于我的有效内存1Gb。而如果我的”max_children”设置的较小,比如5-10个,那么php-cgi就会“很累”,处理速度也很慢,等待的时间也较长。如果长时间没有得到处理的请求就会出现504 Gateway Time-out这个错误,而正在处理的很累的那几个php-cgi如果遇到了问题就会出现502 Bad gateway这个错误。

提高nginx网络吞吐量buffers优化指令说明

client_body_buffer_size
此指令设置用于请求主体的缓冲区大小。 如果主体超过缓冲区大小,则完整主体或其一部分将写入临时文件。 如果NGINX配置为使用文件而不是内存缓冲区,则该指令会被忽略。 默认情况下,该指令为32位系统设置一个8k缓冲区,为64位系统设置一个16k缓冲区。 该指令在NGINX配置的http,server和location区块使用。如下:
server{
client_body_buffer_size 8k;
}

client_max_body_size
此指令设置NGINX能处理的最大请求主体大小。 如果请求大于指定的大小,则NGINX发回HTTP 413(Request Entity too large)错误。 如果服务器处理大文件上传,则该指令非常重要。
server{
client_max_body_size 2m;
}

client_body_in_file_only
此指令禁用NGINX缓冲区并将请求体存储在临时文件中。 文件包含纯文本数据。 该指令在NGINX配置的http,server和location区块使用。 可选值有:
off:该值将禁用文件写入
clean:请求body将被写入文件。 该文件将在处理请求后删除。
on: 请求正文将被写入文件。 处理请求后,将不会删除该文件。
默认情况下,指令值为关闭。 如下:
http{
client_body_in_file_only clean;
}

client_body_in_single_buffer
该指令设置NGINX将完整的请求主体存储在单个缓冲区中。 默认情况下,指令值为off。 如果启用,它将优化读取$request_body变量时涉及的I/O操作。如下例子:
server{
client_body_in_single_buffer on;
}

client_body_temp_path
此指令指定存储请求正文的临时文件的位置。 除了位置之外,指令还可以指定文件是否需要最多三个级别的文件夹层次结构。 级别指定为用于生成文件夹的位数。
默认情况下,NGINX在NGINX安装路径下?client_body_temp文件夹创建临时文件。 如下例子:
server{
client_body_temp_pathtemp_files 1 2;
}
该指令生成的文件路径如temp_files/1/05/0000003051。

client_header_buffer_size
此指令与client_body_buffer_size类似。 它为请求头分配一个缓冲区。 如果请求头大小大于指定的缓冲区,则使用large_client_header_buffers指令分配更大的缓冲区。如下例子:
http{
client_header_buffer_size 1m;
}

large_client_header_buffers
此指令规定了用于读取大型客户端请求头的缓冲区的最大数量和大小。 这些缓冲区仅在缺省缓冲区不足时按需分配。 当处理请求或连接转换到保持活动状态时,释放缓冲区。
http{
large_client_header_buffers 4 8k;
}

nginx代理超时配置

proxy_connect_timeout
默认值60s, nginx连接到后端服务器的连接超时时间,发起握手等候响应超时时间。

proxy_read_timeout
连接成功后,等候后端服务器响应时间。其实已经进入后端的排队之中等候处理(也可以说是后端服务器处理请求的时间)。

proxy_send_timeout
后端服务器数据回传时间,就是在规定时间之内后端服务器必须传完所有的数据。
注:nginx使用proxy模块时,默认的读取超时时间是60s。

nginx缓存区大小设置

proxy_buffer_size
nginx可从服务器一次接收的最大数据大小

proxy_buffers
该指令设置缓冲区的大小和数量,从被代理的后端服务器取得的响应内容,会放置到这里. 默认情况下,一个缓冲区的大小等于内存页面大小,可能是4K也可能是8K,这取决于平台。

proxy_busy_buffers_size
proxy_busy_buffers_size不是独立的空间,他是proxy_buffers和proxy_buffer_size的一部分。nginx会在没有完全读完后端响应的时候就开始向客户端传送数据,所以它会划出一部分缓冲区来专门向客户端传送数据(这部分的大小是由proxy_busy_buffers_size来控制的,建议为proxy_buffers中单个缓冲区大小的2倍),然后它继续从后端取数据,缓冲区满了之后就写到磁盘的临时文件中。

proxy_max_temp_file_size和proxy_temp_file_write_size
临时文件由proxy_max_temp_file_size和proxy_temp_file_write_size这两个指令决定。
proxy_temp_file_write_size 是一次访问能写入的临时文件的大小,默认是proxy_buffer_size和proxy_buffers中设置的缓冲区大小的2倍,Linux下一般是8k。
proxy_max_temp_file_size 指定当响应内容大于proxy_buffers指定的缓冲区时, 写入硬盘的临时文件的大小. 如果超过了这个值, Nginx将与Proxy服务器同步的传递内容, 而不再缓冲到硬盘. 设置为0时, 则直接关闭硬盘缓冲.

示例

proxy_buffer_size 4k;   #设置代理服务器(nginx)保存用户头信息的缓冲区大小
proxy_buffers 4 32k;   #proxy_buffers缓冲区,网页平均在32k以下的设置
proxy_busy_buffers_size 64k;   #高负荷下缓冲大小(proxy_buffers*2)
proxy_temp_file_write_size 64k;   #设定缓存文件夹大小,大于这个值,将从upstream服务器传

参考链接:
Ngnix中的fastcgi参数性能优化和解释
提高Nginx网络吞吐量之buffers优化
https://blog.csdn.net/u014218983/article/details/81217032
https://blog.csdn.net/zschu2008/article/details/7204552

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐