Nginx服务器中414错误和504错误的配置解决方法

这篇文章主要介绍了Nginx服务器中414错误和504错误的配置解决方法,分别对应Request-URI Too Large和Gateway Time-out这样的错误提示,需要的朋友可以参考下

414 Request-URI Too Large

#客户端请求头缓冲区大小,如果请求头总长度大于小于128k,则使用此缓冲区,
#请求头总长度大于128k时使用large_client_header_buffers设置的缓存区
client_header_buffer_size 128k;

#large_client_header_buffers 指令参数4为个数,128k为大小,默认是8k。申请4个128k。
large_client_header_buffers 4 128k;

当http 的URI太长或者request header过大时会报414 Request URI too large或400 bad request错误。

可能原因

场景1.cookie中写入的值太大造成的,因为header中的其他参数的size一般比较固定,只有cookie可能被写入较大的数据

场景2.请求参数太长,比如发布一个文章正文,用urlencode后,使用get方式传到后台。

GET http://www.264.cn/ HTTP/1.1
Host: www.264.cn
Connection: keep-alive
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.31 
Accept-Encoding: gzip,deflate,sdch
Accept-Language: zh-CN,zh;q=0.8
Accept-Charset: GBK,utf-8;q=0.7,*;q=0.3
Cookie: bdshare_firstime=1363517175366; 
If-Modified-Since: Mon, 13 May 2013 13:40:02 GMT

当请求头过大时,超过large_client_header_buffer时,
nginx可能返回"Request URI too large" (414)或者"Bad-request"(400)错误,

如上例HTTP请求头由多行构成,
其中"GET http://www.264.cn/ HTTP/1.1"表示Request line

当Request line的长度大于large_client_header_buffer的一个buffer(128k)时,nginx会返回"Request URI too large" (414)错误,对应上面的场景2。

请求投中最长的一行也要小于large_client_header_buffer,当不是Request line的最长行大于一个buffer(128k)时,会返回"Bad-request"(400)错误,对应上面的场景1。

解决办法:这时可以调大上述两个值。

client_header_buffer_size 512k;
large_client_header_buffers 4 512k;

504 Gateway Time-out
之前网站一直是使用nginx做代理后端的apache运行php来提供服务。

apache经常会不定期不定时间的出现不能服务失去响应,然后nginx出现"504 Gateway Time-out"

查看错误日志也看不到任何东西,以为是apache的bug(其实不是,下面会说原因)。

也许年龄大了人就不爱折腾,愿意保持原状不动,使用监控工具,每次收到报警后都重新启动apache勉强维持着。

终于有一天我烦了,不就是处理php吗,我不用apache总行了吧,一怒之下使用源安装php-fpm转移到php-fpm来运行php。

安装php并不麻烦,使用源安装还是很顺利的,唯一需要做的就是设置php worker工作进程的日志输出php错误日志。


一切准备就绪后把原来的proxy_pass换成fastcgipass就可以了。

upstream apachephp {
  server www.quancha.cn:8080; #Apache1
}

....
proxy_pass http://apachephp;

替换成成

upstream php {
    server 127.0.0.1:9000;
}

...
fastcgi_pass php;

就可以把apache上跑的php迁移到php-fpm上来跑。

原以为这样就可以高枕无忧了,迁移完成是也确实没什么问题,但是如果你不去分析问题的根本原因在哪。

问题还是会找上门来,第二天nginx又报了504的gateway timeout。

这回没apache什么事了吧,apache总算撇清了关系。

那应该还是在nginx和php-fpm身上,查看nginx的错误日志,可以看到

[error] 6695#0: *168438 upstream timed out (110: Connection timed out) while reading response header from upstream,
...
request: "GET /kd/open.php?company=chinapost&number=PA24977020344 HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "www.quancha.cn"

看到这里基本上就排除了nginx嫌疑,nginx是在等待php处理"GET /kd/open.php?company=chinapost&number=PA24977020344 HTTP/1.1"超时退出了。

马上重启php-fpm,问题没有了,网站可以访问了。

再次访问该页面,依然没有响应,但同时访问别的页面正常,该页面刷新几次后,整个网站都是bad gateway timeout了。

问题就缩小到这个php脚本上了。

netstat -napo |grep "php5-fpm" | wc -l

查看php工作进程已经达到了配置文件里的上限10,有种感觉就是大家都被open.php这个脚本卡住了。

这个脚本是干什么的呢?这个脚本就是采集快递信息的,里面用到了php_curl。

PHP脚本如果执行时间超过php.ini中的配置项max_execution_time不出结果就会强制退出。

查看了php.ini中max_execution_time确实配了,值为30。

万能google派上用场了,经过不断google后得到下面这句话

set_time_limit()函数和配置指令max_execution_time只影响脚本本身执行的时间。任何发生在诸如使用system()的系统调用,流操作,数据库操作等的脚本执行的最大时间不包括其中,当该脚本已运行。

就是说如果脚本中执行了其它操作的时间是不计在脚本运行时间当中的,如果你没设置超时,那么php就会一直等待调用的结果。

查看open.php源文件一看,果然没有设置curl的超时时间。

增加如下两行,重新刷新,后问题解决了。

curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); //timeout on connect
curl_setopt($ch, CURLOPT_TIMEOUT, 10); //timeout on response

当然,除了这种方法外,php-fpm里也提供参数供我们强制杀死长时间无结果的进程,只是该参数默认没打开。

php-fpm的配置文件里可以设置一个参数request_terminate_timeout,请求终止的超时时间,当请求执行超过这个时间就会被kill。

同时它还有个参数request_slowlog_timeout,用来记录慢请求日志的。

命令行运行php的话,可以使用这段代码

$real_execution_time_limit = 60; //时间限制

if (pcntl_fork())
{
// some long time code which should be
// terminated after $real_execution_time_limit seconds passed if it's not
// finished by that time
}
else
{
sleep($real_execution_time_limit);
posix_kill(posix_getppid(), SIGKILL);
}

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

一:确定你的系统是UTF编码 [root@Tserver ~]# env|grep LANG LANG=en_US.UTF-8 二:NGINX配置文件里默认编码设置为utf-8 server { listen 80; server_name .inginx.com ; index index.html index.htm index.php; root /usr/local/nginx/html/inginx.com; ch
很多网站需要采用伪静态来访问动态网页。所以像phpcms这样的系统,都提供了一个.htaccess文件,供写伪静态规则。但这个规则是针对Apache的。在nginx服务器上并不起作用。 nginx 可以直接将伪静态规则写在配置文件中,但这个需要有服务器管理权限,普通站长不
JRE(Java Runtime Environment,Java运行环境),运行JAVA程序所必须的环境的集合,包含JVM标准实现及Java核心类库。 下载解压,然后双击安装,跟普通安装程序一样。 安装完毕之后就是需要我们来设置环境变量了 假设jre安装目录为 C:\Program Files (x86)\J
在网站建设中需要网页重定向的情况很多:如网页目录结构变动,网页重命名、网页的扩展名改变、网站域名改变等。如果不做重定向,用户的收藏和搜索引 擎数据库中的旧地址只能让访客得到一个404错误信息页面,访问流量白白丧失。不仅如此,之前该页面的一切积
出现503错误,其日志都是记录在%Systemroot%\System32\LogFiles\HTTPERR\httperr1.log中。 其中的s-reason项: 1、若为AppShutdown,可能是由于CPU占用率太高导致自动关闭应用程序池。 2、若为AppOffline,可能是由于应用程序标识出错引起的。 3、若为Disabl
apache web服务器的站点,下载pptx,docx,xlsx文件,却被浏览器当作zip文件保存。 这不是浏览器的问题,而是apache不认docx,pptx,,xlsx等Microsoft Office 2007+的文件格式,而这些文件本身是zip压缩文件,所以被apache当作zip压缩文件发给浏览器了。 做个形