TFA*_*oon 53 php http nginx amazon-web-services
在上周末,我注意到我的一个中型AWS实例出现问题,如果请求超过60秒,Nginx总是返回HTTP 499响应.请求的页面是PHP脚本
我花了几天时间试图找到答案,并尝试了我可以在互联网上找到的所有内容,包括Stack Overflow上的几个条目,没有任何效果.
我已经尝试修改PHP设置,PHP-FPM设置和Nginx设置.你可以在星期五看到我在NginX论坛上提出的一个问题(http://forum.nginx.org/read.php?9,237692)虽然没有得到任何答复所以我希望我能找到一个在我被迫回到Apache之前回答这个问题,我知道它正常工作.
这是不是同样的问题在其他项中报告的HTTP 500错误.
我已经能够使用PHP 5.4.11使用NginX的新的微型AWS实例来复制问题.
为了帮助那些希望看到问题的人,我将带你完成设置,我为最新的Micro测试服务器运行.
您需要使用AMI ami-c1aaabb5启动新的AWS Micro实例(因此它是免费的)
此PasteBin条目具有完整的设置,可以运行以镜像我的测试环境.您最后需要在NginX配置中更改example.com
一旦设置完毕,您只需要创建我正在测试的示例PHP文件
<?php
sleep(70);
die( 'Hello World' );
?>
Run Code Online (Sandbox Code Playgroud)
将其保存到webroot中然后进行测试.如果您使用php或php-cgi从命令行运行脚本,它将起作用.如果您通过网页访问脚本并拖动访问日志/var/log/nginx/example.access.log,您会注意到在60秒后收到HTTP 1.1 499响应.
现在您可以看到超时,我将完成我对PHP和NginX所做的一些配置更改以尝试解决此问题.对于PHP,我将创建几个配置文件,以便可以轻松禁用它们
更新PHP FPM配置以包含外部配置文件
sudo echo '
include=/usr/local/php/php-fpm.d/*.conf
' >> /usr/local/php/etc/php-fpm.conf
Run Code Online (Sandbox Code Playgroud)
创建一个新的PHP-FPM配置以覆盖请求超时
sudo echo '[www]
request_terminate_timeout = 120s
request_slowlog_timeout = 60s
slowlog = /var/log/php-fpm-slow.log ' >
/usr/local/php/php-fpm.d/timeouts.conf
Run Code Online (Sandbox Code Playgroud)
更改一些全局设置以确保紧急重启间隔为2分钟
# Create a global tweaks
sudo echo '[global]
error_log = /var/log/php-fpm.log
emergency_restart_threshold = 10
emergency_restart_interval = 2m
process_control_timeout = 10s
' > /usr/local/php/php-fpm.d/global-tweaks.conf
Run Code Online (Sandbox Code Playgroud)
接下来,我们将使用单独的文件更改一些PHP.INI设置
# Log PHP Errors
sudo echo '[PHP]
log_errors = on
error_log = /var/log/php.log
' > /usr/local/php/conf.d/errors.ini
sudo echo '[PHP]
post_max_size=32M
upload_max_filesize=32M
max_execution_time = 360
default_socket_timeout = 360
mysql.connect_timeout = 360
max_input_time = 360
' > /usr/local/php/conf.d/filesize.ini
Run Code Online (Sandbox Code Playgroud)
如您所见,这会将套接字超时增加到3分钟,并有助于记录错误.
最后,我将编辑一些NginX设置以增加该方的超时
首先,我编辑文件/etc/nginx/nginx.conf并将其添加到http指令fastcgi_read_timeout 300;
接下来,我编辑我们之前创建的文件/ etc/nginx/sites-enabled/example(请参阅pastebin条目)并将以下设置添加到server指令中
client_max_body_size 200;
client_header_timeout 360;
client_body_timeout 360;
fastcgi_read_timeout 360;
keepalive_timeout 360;
proxy_ignore_client_abort on;
send_timeout 360;
lingering_timeout 360;
Run Code Online (Sandbox Code Playgroud)
最后,我将以下内容添加到服务器目录的〜.php $部分
fastcgi_read_timeout 360;
fastcgi_send_timeout 360;
fastcgi_connect_timeout 1200;
Run Code Online (Sandbox Code Playgroud)
在重试脚本之前,启动nginx和php-fpm以确保已经拾取新设置.然后我尝试访问该页面,仍然在NginX example.error.log中收到HTTP/1.1 499条目.
那么,我哪里错了?当我将PHP的最大执行时间设置为2分钟时,这只适用于apache.
我可以看到通过从Web可访问页面运行phpinfo()来获取PHP设置.我只是没有得到,我实际上认为已经增加了太多,因为它应该只需要PHP的max_execution_time,default_socket_timeout以及仅在server-> location指令中的NginX的fastcgi_read_timeout.
进行了一些进一步的测试,表明问题不是客户端正在死亡,我已经修改了测试文件
<?php
file_put_contents('/www/log.log', 'My first data');
sleep(70);
file_put_contents('/www/log.log','The sleep has passed');
die('Hello World after sleep');
?>
Run Code Online (Sandbox Code Playgroud)
如果我从网页运行脚本,那么我可以看到文件的内容设置为第一个字符串.60秒后,NginX日志中出现错误.10秒后,文件内容变为第二个字符串,证明PHP正在完成该过程.
设置fastcgi_ignore_client_abort; 确实将HTTP 499的响应更改为HTTP 200,但仍未将任何内容返回给最终客户端.
将Apache和PHP(5.3.10)直接安装到盒子上(使用apt),然后增加执行时间,问题确实也出现在Apache上.现在的症状与NginX相同,HTTP200响应但实际的客户端连接超时.
我也开始注意到,在NginX日志中,如果我使用Firefox进行测试,它会发出一个双重请求(就像这个PHP脚本在超过60秒时执行两次).虽然这似乎是客户端请求脚本失败
TFA*_*oon 65
问题的原因是AWS上的Elastic Load Balancers.默认情况下,它们会在60秒不活动后超时,这是造成问题的原因.
所以它不是NginX,PHP-FPM或PHP而是负载均衡器.
要解决此问题,只需进入ELB"描述"选项卡,滚动到底部,然后单击"空闲超时:60秒"值旁边的"(编辑)"链接
| 归档时间: |
|
| 查看次数: |
77229 次 |
| 最近记录: |