经常得到空的 $_POST 数据和 proxy_fcgi 错误 / Apache2 / PHP-FPM
Often getting empty $_POST data and proxy_fcgi error / Apache2 / PHP-FPM
我有一个 Apache2 服务器 PHP-FPM (正在 Ubuntu 20) 而且我经常从客户端得到空的 $_POST 数据,但是 Content-Length in header is > 0. 我的流量不小 (~20 req/sec (max) on PHP-FPM) 并且从一些客户那里我收到一个空的 POST 请求 (它可以是 1 小时或有时 > 10)。这是我收到的示例 header:
[Content-Length] => 454
[Content-Type] => application/x-www-form-urlencoded
[User-Agent] => BestHTTP/2 v2.3.1
[Te] => identity
[Keep-Alive] => timeout=21
[Connection] => Keep-Alive, TE
[Accept-Encoding] => gzip, identity
[Host] => example.com
还有一些来自 $_SERVER 的信息:
[USER] => www-data
[HOME] => /var/www
[SCRIPT_NAME] => some/path/set_score.php
[REQUEST_URI] => some/path/set_score.php
[REQUEST_METHOD] => POST
[SERVER_PROTOCOL] => HTTP/1.1
[GATEWAY_INTERFACE] => CGI/1.1
[REMOTE_PORT] => 43852
[SCRIPT_FILENAME] => //var/www/example.com/public_html/some/path/set_score.php
[SERVER_ADMIN] => webmaster@localhost
[CONTEXT_DOCUMENT_ROOT] => /var/www/example.com/public_html/
[REQUEST_SCHEME] => https
[DOCUMENT_ROOT] => /var/www/example.com/public_html/
[REMOTE_ADDR] => **.**.***.**
[SERVER_PORT] => 443
[SERVER_ADDR] => ***.***.***.***
[SERVER_NAME] => example.com
[SERVER_SOFTWARE] => Apache
[SERVER_SIGNATURE] => <address>Apache Server at example.com Port 443</address>
[PATH] => /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin
[CONTENT_LENGTH] => 454
[CONTENT in /var/www/example.com/public_html/some/path/set_score.php on line 3
如您所见,Content-Length > 0,但 $_POST 数据数组为空.同时,这个空的 POST 请求经常跟随着 proxy_fcgi error:
[Sun May 02 04:17:59.777441 2021] [proxy_fcgi:error] [pid 105827:tid 140667812566784] (70007)The timeout specified has expired: [client ***.***.***.***:40171] AH01075: Error dispatching request to : (reading input brigade)
此外,当发生此错误时,在 access.log 中,我看到了 408 代码。
而且我不知道问题出在 Apache 配置或 PHP-FPM,因为我从客户端发送的 POST 数据 很小而且只是文本数据 。奇怪的是,在以前的服务器 (cloudways) 上我没有遇到这些问题。但是现在当我做我自己的服务器时,这个神奇的错误发生了。也许他们只是忽略了这些类型的错误或者超时值太大了。我的脚本执行时间小于 0.1 秒,我不需要大的超时值 (我猜).
这是我配置中的一些重要设置:
apache2.conf
Timeout 60
KeepAlive On
MaxKeepAliveRequests 164
KeepAliveTimeout 5
HostnameLookups Off
<Directory />
Options FollowSymLinks
AllowOverride None
Require all denied
</Directory>
<Directory /usr/share>
AllowOverride None
Require all granted
</Directory>
<Directory /var/www/>
Options FollowSymLinks
AllowOverride None
Require all granted
</Directory>
/apache2/sites-available/example.com.conf
<VirtualHost *:443>
ServerAdmin webmaster@localhost
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/example.com/public_html/
SSLEngine on
SSLProtocol -all +TLSv1.2 +TLSv1.3
SSLCertificateFile /etc/ssl/certs/example.com.crt
SSLCertificateKeyFile /etc/ssl/private/example.com.key
SSLCertificateChainFile /etc/ssl/certs/ca-example.com.crt
# tried to fix that "Error dispatching request to"
<IfModule reqtimeout_module>
RequestReadTimeout header=20-40,minrate=150
RequestReadTimeout body=20,minrate=150
</IfModule>
<FilesMatch ".+\.ph(ar|p|tml)$">
SetHandler "proxy:unix:/run/php/php7.4-fpm-example.com.sock|fcgi://localhost/"
</FilesMatch>
</VirtualHost>
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
Redirect 301 / https://example.com/
</VirtualHost>
/php/7.4/fpm/pool.d/example.com.conf
[example.com]
user = www-data
group = www-data
listen = /run/php/php7.4-fpm-example.com.sock
listen.owner = www-data
listen.group = www-data
pm = dynamic
pm.max_children = 64
pm.start_servers = 16
pm.min_spare_servers = 8
pm.max_spare_servers = 16
php_admin_value[error_log] = /var/www/example.com/logs/error-fpm-php.log
php_admin_flag[log_errors] = on
通过从 HTTP/1.1 协议切换到 HTTP/2 修复了超时错误的出现。空 POST 请求现在很少出现,但确实如此。
我有一个 Apache2 服务器 PHP-FPM (正在 Ubuntu 20) 而且我经常从客户端得到空的 $_POST 数据,但是 Content-Length in header is > 0. 我的流量不小 (~20 req/sec (max) on PHP-FPM) 并且从一些客户那里我收到一个空的 POST 请求 (它可以是 1 小时或有时 > 10)。这是我收到的示例 header:
[Content-Length] => 454
[Content-Type] => application/x-www-form-urlencoded
[User-Agent] => BestHTTP/2 v2.3.1
[Te] => identity
[Keep-Alive] => timeout=21
[Connection] => Keep-Alive, TE
[Accept-Encoding] => gzip, identity
[Host] => example.com
还有一些来自 $_SERVER 的信息:
[USER] => www-data
[HOME] => /var/www
[SCRIPT_NAME] => some/path/set_score.php
[REQUEST_URI] => some/path/set_score.php
[REQUEST_METHOD] => POST
[SERVER_PROTOCOL] => HTTP/1.1
[GATEWAY_INTERFACE] => CGI/1.1
[REMOTE_PORT] => 43852
[SCRIPT_FILENAME] => //var/www/example.com/public_html/some/path/set_score.php
[SERVER_ADMIN] => webmaster@localhost
[CONTEXT_DOCUMENT_ROOT] => /var/www/example.com/public_html/
[REQUEST_SCHEME] => https
[DOCUMENT_ROOT] => /var/www/example.com/public_html/
[REMOTE_ADDR] => **.**.***.**
[SERVER_PORT] => 443
[SERVER_ADDR] => ***.***.***.***
[SERVER_NAME] => example.com
[SERVER_SOFTWARE] => Apache
[SERVER_SIGNATURE] => <address>Apache Server at example.com Port 443</address>
[PATH] => /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin
[CONTENT_LENGTH] => 454
[CONTENT in /var/www/example.com/public_html/some/path/set_score.php on line 3
如您所见,Content-Length > 0,但 $_POST 数据数组为空.同时,这个空的 POST 请求经常跟随着 proxy_fcgi error:
[Sun May 02 04:17:59.777441 2021] [proxy_fcgi:error] [pid 105827:tid 140667812566784] (70007)The timeout specified has expired: [client ***.***.***.***:40171] AH01075: Error dispatching request to : (reading input brigade)
此外,当发生此错误时,在 access.log 中,我看到了 408 代码。 而且我不知道问题出在 Apache 配置或 PHP-FPM,因为我从客户端发送的 POST 数据 很小而且只是文本数据 。奇怪的是,在以前的服务器 (cloudways) 上我没有遇到这些问题。但是现在当我做我自己的服务器时,这个神奇的错误发生了。也许他们只是忽略了这些类型的错误或者超时值太大了。我的脚本执行时间小于 0.1 秒,我不需要大的超时值 (我猜).
这是我配置中的一些重要设置:
apache2.conf
Timeout 60
KeepAlive On
MaxKeepAliveRequests 164
KeepAliveTimeout 5
HostnameLookups Off
<Directory />
Options FollowSymLinks
AllowOverride None
Require all denied
</Directory>
<Directory /usr/share>
AllowOverride None
Require all granted
</Directory>
<Directory /var/www/>
Options FollowSymLinks
AllowOverride None
Require all granted
</Directory>
/apache2/sites-available/example.com.conf
<VirtualHost *:443>
ServerAdmin webmaster@localhost
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/example.com/public_html/
SSLEngine on
SSLProtocol -all +TLSv1.2 +TLSv1.3
SSLCertificateFile /etc/ssl/certs/example.com.crt
SSLCertificateKeyFile /etc/ssl/private/example.com.key
SSLCertificateChainFile /etc/ssl/certs/ca-example.com.crt
# tried to fix that "Error dispatching request to"
<IfModule reqtimeout_module>
RequestReadTimeout header=20-40,minrate=150
RequestReadTimeout body=20,minrate=150
</IfModule>
<FilesMatch ".+\.ph(ar|p|tml)$">
SetHandler "proxy:unix:/run/php/php7.4-fpm-example.com.sock|fcgi://localhost/"
</FilesMatch>
</VirtualHost>
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
Redirect 301 / https://example.com/
</VirtualHost>
/php/7.4/fpm/pool.d/example.com.conf
[example.com]
user = www-data
group = www-data
listen = /run/php/php7.4-fpm-example.com.sock
listen.owner = www-data
listen.group = www-data
pm = dynamic
pm.max_children = 64
pm.start_servers = 16
pm.min_spare_servers = 8
pm.max_spare_servers = 16
php_admin_value[error_log] = /var/www/example.com/logs/error-fpm-php.log
php_admin_flag[log_errors] = on
通过从 HTTP/1.1 协议切换到 HTTP/2 修复了超时错误的出现。空 POST 请求现在很少出现,但确实如此。