Nginx reports 504 gateway timeout error solution

Reprinted article source: http://www.111cn.net/sys/nginx/90669.htm (if invaded and deleted)

Nginx reports 504 gateway timeout error, one is a file configuration problem, the other is related processing time, and finally it may be caused by insufficient resources. Let's take a look.

The explanation is as follows:

Recently at work, I need to do the function of importing Excel. Because there is a lot of data in Excel, and our server program needs to verify the content of the data, it will call a lot of external service interfaces, so there is no suspense to import the Excel interface. The call took more than a minute and an error was reported: 504 gateway timeout. Here are two solutions:

1. Optimize business code

If an API call takes more than one minute, there must be something that can be optimized. Check whether the database or API call is reasonable and whether the request can be merged.

2. Modify the server configuration of Nginx

If it is really impossible to optimize, you can increase the Nginx timeout.
To see if the time meets the requirements, there are three parameters in nginx.config:

fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;

The above units are seconds.

If you are using an Nginx proxy, you can add:

proxy_connect_timeout 300s;
proxy_send_timeout 300s;
proxy_read_timeout 300s;

become:

location /foo {
     proxy_pass http://xxx.xxx.xxx.xxx:8080/foo;
     proxy_set_header Host $host;
     proxy_set_header X-Real-IP $remote_addr;
     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
     proxy_connect_timeout 300s;
     proxy_send_timeout 300s;
     proxy_read_timeout 300s;
     access_log /var/log/nginx/access.foo.log main;
     error_log /var/log/nginx/error.foo.log;
}

If it doesn't work out, let's take a look

 From the error code, it can be basically determined that it has nothing to do with nginx itself, mainly because the request submitted to php-fpm fails to feedback correctly. In general, when submitting a dynamic request, nginx will directly transfer the request to php-fpm, while php -fpm then allocates the php-cgi process to handle related requests, and then returns in turn, and finally nginx feeds back the results to the client browser, but my v ps is currently running a pure php application content, in fact, all the user's The requests are all php requests, some take a long time, and the php-cgi process is always full, and the configuration file of php-fpm itself only opens 10 groups of php-cgi processes. It will cause the request to not be processed normally and an error will occur.
  
  The reason is probably analyzed. It is easier to do the following. First, change several configurations of php-fpm:
  
  change max_children from the previous 10 to the current 30, so as to ensure that there are enough php-cgi processes to be used. ; Change
  the request _terminate_timeout from 0s to 60s, so that the timeout time for the php-cgi process to process the script is 60 seconds, which can prevent the process from being suspended and improve the utilization efficiency.
  
  Then change several configuration items of nginx to reduce the number of FastCGI requests and keep the buffers unchanged as much as possible:
  
  fastcgi_buffers is changed from 4 64k to 2 256k;
  fastcgi_buffer_size is changed from 64k to 128K;
  fastcgi_busy_buffers_size is changed from 128K to 256K;
  fastcgi_temp_file_write_size is changed from 128K to 256K 256K.
  
  Well, reload the configuration of php-fpm and nginx, and test again. So far, there has been no 504 Gateway Time-out within two weeks, which is considered to be effective. 

  In addition, the default static processing method of php-fpm will cause the process of php-cgi to occupy memory for a long time and cannot be released, which is also one of the reasons for the error of nginx. Therefore, the processing method of php-fpm can be changed to apache mode.
  <value name=”style”>apache-like</value>

  From the change to the present, the test shows that the effect of the above method is still obvious, and no Nginx502 bad gateway or 504 Gateway Time-out error has been found. Of course, if your VPS or server performance is good enough, you don't need to make unnecessary changes according to the specific situation.


example


Taking my current server as an example, the CPU is 1.5G Pentium IV, the memory is 1GB, and the CENTOS system has about 50 visitors online at the same time.

But most people online need to request PHP-CGI for a lot of information processing, so I set nginx.conf as:
fastcgi_connect_timeout 300s;
fastcgi_send_timeout 300s;
fastcgi_read_timeout 300s;
fastcgi_buffer_size 128k;
fastcgi_buffers 8 128k; #8 128
fastcgi_busy_buffers_size 256k;
fastcgi_temp
fastcgi_intercept_errors on;
The main settings here are the first three, namely
fastcgi_connect_timeout 300s;
fastcgi_send_timeout 300s;
fastcgi_read_timeout 300s;
here specifies the connection, sending and reading time of PHP-CGI, 300 seconds is enough, so my server is very few The error 504 Gateway Time-out appears. The most critical is the setting of php-fpm.conf, which will directly lead to 502 Bad Gateway and 504 Gateway Time-out.

Let's take a closer look at several important parameters of php-fpm.conf:
php-fpm.conf has two crucial parameters, one is "max_children", and the other is "request_terminate_timeout"
. The value of my two settings One is "40" and the other is "900", but this value is not universal, but needs to be calculated by yourself.
The calculation method is as follows:
If your server performance is good enough, the bandwidth resources are sufficient, and the PHP script does not have loops or bugs, you can directly set "request_terminate_timeout" to 0s. The meaning of 0s is to let PHP-CGI continue to execute without time limit. And if you can't do this, that is to say your PHP-CGI may have a bug, or your bandwidth is not enough or other reasons cause your PHP-CGI to be suspended, then it is recommended that you assign "request_terminate_timeout" to "request_terminate_timeout" A value that can be set according to the performance of your server. Generally speaking, the better the performance, the higher you can set it, 20 minutes to 30 minutes is fine. Since my server PHP script needs to run for a long time, some may exceed 10 minutes, so I set it to 900 seconds, so that it will not cause PHP-CGI to die and appear 502 Bad gateway error.
And how is the value of "max_children" calculated? In principle, the larger the value, the better, the more php-cgi processes, the faster the processing, and the fewer requests queued. Setting "max_children" also needs to be set according to the performance of the server. Generally speaking, a server normally consumes about 20M of memory per php-cgi, so I set my "max_children" to 40, 20M* 40=800M means that all PHP-CGI consumes less than 800M of memory at the peak, which is 1Gb lower than my effective memory. And if my "max_children" is set to a small value, such as 5-10, then php-cgi will be "tired", the processing speed will be very slow, and the waiting time will be longer. If the request has not been processed for a long time, the 504 Gateway Time-out error will appear, and the php-cgi that are being processed very tired will have the 502 Bad gateway error if they encounter problems.
The settings of fastcgi are added to server {}.
After the modification, if you start nginx, you will be prompted:
nginx: [emerg] unknown directive " fastcgi_connect_timeout" in /home/chen/workspace/jamy/nginx.conf:2
Similar errors may occur. It is not to remove the full-width spaces in front of it.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324450252&siteId=291194637