Home  >  Article  >  Backend Development  >  nginx 504 Gateway Time-out error troubleshooting_PHP tutorial

nginx 504 Gateway Time-out error troubleshooting_PHP tutorial

WBOY
WBOYOriginal
2016-07-13 10:29:232041browse

An nginx 504 Gateway Time-out error troubleshooting and resolution record. After repeated inspections, it was found that the cause of this problem was that PHP's CURL did not set a timeout. The solution is to set the timeout or modify it. The configuration of nginx can solve it.

Troubleshooting an inexplicable website failure. Previously, the website had been using nginx as the proxy backend and apache running php to provide services. Apache often fails to serve and loses response from time to time, and then nginx appears "504 Gateway Time-out"
I can't see anything in the error log, so I thought it was an apache bug (actually it is not, the reason will be explained below) ).
Maybe as you get older, you don’t like to mess around, and are willing to keep things as they are, use monitoring tools, and restart apache every time you receive an alarm to survive. Finally one day I got bored. I was just dealing with php. I didn’t need the apache headquarters anymore. In a rage, I used the source to install php-fpm and moved it to php-fpm to run php. Installing PHP is not troublesome. Installation using the source is very smooth. The only thing you need to do is to set the log of the PHP worker process to output the PHP error log.

When everything is ready, just replace the original proxy_pass with fastcgipass.
upstream apachephp {

server www.jb51.net:8080; #Apache1
}
....
proxy_pass http://apachephp;

is replaced with
upstream php {

server 127.0.0.1:9000;
}
...
fastcgi_pass php;

You can migrate php running on apache to php-fpm.
I thought that I would be able to sit back and relax. There is indeed no problem after the migration is completed, but if you don’t analyze the root cause of the problem. The problem still comes, and nginx reported a 504 gateway timeout the next day. Nothing will happen to Apache this time. Apache finally cleared up the relationship.
It should still be nginx and php-fpm. Check the error log of nginx and you can see
[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.jb51 .net"

Seeing this basically eliminates the suspicion of nginx. nginx is waiting for php to process "GET /kd/open.php?company=chinapost&number=PA24977020344 HTTP/1.1" and timed out.
Restart php-fpm immediately. The problem is gone and the website can be accessed.
When I accessed the page again, there was still no response, but it was normal to access other pages at the same time. After the page was refreshed several times, the entire website became a bad gateway timeout.
The problem is narrowed down to this php script.
netstat -napo |grep "php5-fpm" | wc -l

Looking at the php working process, it has reached the upper limit of 10 in the configuration file. It feels like everyone is stuck by the open.php script.
What does this script do? This script is to collect express delivery information, and php_curl is used in it.
If the execution time of the PHP script exceeds the configuration item max_execution_time in php.ini and no results are produced, it will be forced to exit.
I checked that max_execution_time is indeed configured in php.ini, and the value is 30.
The universal google comes in handy. After constant google, I got the following sentence
The set_time_limit() function and the configuration instruction max_execution_time only affect the execution time of the script itself. The maximum time for any script execution that occurs such as system calls using system(), stream operations, database operations, etc. is not included when the script is already running. www.jbxue.com
That is to say, if the time during which other operations are performed in the script is not included in the script running time, if you do not set a timeout, then PHP will always wait for the result of the call.
Looking at the open.php source file, it turns out that the curl timeout is not set.
Add the following two lines, refresh again, and the problem is solved.
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); //timeout on connect

curl_setopt($ch, CURLOPT_TIMEOUT, 10); //timeout on response
Of course, in addition to this method, php-fpm also provides parameters for us to forcefully kill processes that have no results for a long time, but this The parameter is not turned on by default.
You can set a parameter request_terminate_timeout in the configuration file of php-fpm, which is the timeout for request termination. When the request execution exceeds this time, it will be killed.
At the same time, it also has a parameter request_slowlog_timeout, which is used to record slow request logs.
If you want to run php from the command line, you can use this code

<span>$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);
}</span>

www.bkjia.comtruehttp: //www.bkjia.com/PHPjc/776506.htmlTechArticleAn nginx 504 Gateway Time-out error troubleshooting and resolution record. After repeated inspections, it was found that the cause of this problem is PHP's CURL does not have a timeout set. The solution is just to set the timeout...
Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn