2 日前、本番サーバー (CentOS 6.8) で PHP7 (PHP 7.0.14) にアップグレードしました。現在、nginx (1.10.2-1) ログに次のエラーが表示されています。
2017/01/20 08:20:04 [エラー] 7654#7654: *153301 アップストリームが、アップストリームからの応答ヘッダーの読み取り中に予期しない FastCGI レコード: 3 を送信しました。クライアント: XXX.XXX.XXX.XXX、サーバー: example.com、リクエスト: "GET / HTTP/1.0"、アップストリーム: "fastcgi://unix:/var/run/php-fpm/example.fpm.sock:"、ホスト: "www.example.com"
- 当社には複数の Web サイトがあり、それぞれが個別の php-fpm プールを実行していますが、このエラーはすべての Web サイトで同時に発生します。
- このエラーが発生すると、すべての Web サイトでブラウザに「502 Bad Gateway」と表示されます。
- このエラーは 1 ~ 2 分間発生し、その後はすべて自動的に正常に戻ります。
- それは一日のうちに異なる時間に3回起こりました。
- PHP5では問題ありませんでした。
- 私はopcache内のすべてのアプリケーションキャッシュフォルダをブラックリストに登録しようとしました
同様の設定で PHP7 にアップグレードされた別のサーバーがありますが、そのような問題は発生していません。
この問題をどのようにトラブルシューティングして解決策を見つければよいでしょうか?
アップデート1
サーバーの詳細
CPU: 2x Intel(R) Xeon(R) CPU E5-2620 0 @ 2.00GHz
RAM: 256GB
OS: CentOS リリース 6.8
カーネル: 2.6.32-504.8.1.el6.x86_64
PHP: IUS リポジトリの 7.0.14-3 を使用
Nginx: 1.10.2-1
サーバーは、人気のオープン ソース PHP アプリケーションを実行する複数のサイトを実行するための Web サーバーとして使用されます。バックエンドとして php-fpm を備えた Nginx を使用します。各 Web サイトには、個別の php-fpm プールと異なるソケットがあります。PHP アプリケーションは既に php7 と互換性があり、変更点は PHP7 へのアップグレードのみです。
アップデート2
Nginxのメイン設定
user apache;
worker_processes auto;
error_log /var/log/nginx/error.log alert;
pid /var/run/nginx.pid;
events {
use epoll;
worker_connections 4024;
multi_accept on;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
server_names_hash_bucket_size 256;
server_names_hash_max_size 1024;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
client_max_body_size 512M;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
gzip on;
gzip_http_version 1.1;
gzip_vary on;
gzip_comp_level 6;
gzip_proxied any;
gzip_min_length 1000;
gzip_types text/plain text/css application/json application/javascript application/x-javascript text/javascript text/xml application/xml application/rss+xml application/atom+xml application/rdf+xmli font/ttf font/otf image/svg+xm;
gzip_buffers 16 24k;
gzip_disable msie6;
fastcgi_connect_timeout 120;
fastcgi_send_timeout 1200;
fastcgi_read_timeout 1200;
fastcgi_buffer_size 256k;
fastcgi_buffers 16 256k;
fastcgi_busy_buffers_size 256k;
fastcgi_temp_file_write_size 256k;
fastcgi_intercept_errors on;
keepalive_requests 10000;
include /etc/nginx/conf.d/*.conf;
# Load all vhosts !
include /etc/nginx/sites-enabled/*.conf;
}
個別の nginx サイト テンプレート
server {
server_name @@HOSTNAME@@ www.@@HOSTNAME@@;
root "@@PATH@@";
index index.php index.html index.htm;
add_header Cache-Control public;
client_max_body_size 512m;
access_log @@LOG_PATH@@/access.log;
error_log @@LOG_PATH@@/error.log;
location / {
# This is cool because no php is touched for static content
try_files $uri $uri/ $uri/index.php @rewrite /index.php$uri?$args;
}
location @rewrite {
rewrite ^ /index.php;
}
location ~ \.php$ {
send_timeout 1200;
proxy_read_timeout 1200;
proxy_connect_timeout 120;
fastcgi_read_timeout 1200;
fastcgi_pass unix:@@SOCKET@@;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires max;
log_not_found off;
access_log off;
}
location ~* \.(html|htm)$ {
expires 30m;
}
location ~* /\.(ht|git|svn|bak) {
deny all;
}
location ~ ^/sites/.*/files/styles/ {
try_files $uri @rewrite;
}
}
PHP FPM プール テンプレート
[@@USER@@]
listen = /var/run/php-fpm/@@USER@@.fpm.sock
listen.owner = nobody
listen.group = nobody
listen.mode = 0666
user = @@USER@@
group = @@USER@@
pm = ondemand
pm.max_children = 50
pm.process_idle_timeout = 300s
pm.max_requests = 5000
rlimit_files = 1024
request_terminate_timeout = 1200s
security.limit_extensions = .php
php_admin_value[session.save_path] = "@@HOME_DIR@@/_sessions"
php_admin_value[error_log] = "@@HOME_DIR@@/logs/www-error.log"
アップデート3 問題が発生した場合
リクエスト1
GET /moodle/ HTTP/1.0
User-Agent: Pingdom.com_bot_version_1.4_(http://www.pingdom.com/)
Host: www.example.com
受信ヘッダー
502 Bad Gateway
Server: nginx/1.10.2
Date: Wed, 25 Jan 2017 12:32:00 GMT
Content-Type: text/html
Content-Length: 173
Connection: close
受信したコンテンツ
<html>
<head><title>502 Bad Gateway</title></head>
<body bgcolor="white">
<center><h1>502 Bad Gateway</h1></center>
<hr><center>nginx/1.10.2</center>
</body>
</html>
答え1
わかりました。すべての php-fpm プールが同時に数分間停止しています。変更されたのは php 5.6 => php 7 だけです。php7 で何が変わったのでしょうか? すべての php-fpm プールでグローバルに設定されているものは何でしょうか? opcache です。php.ini を提供していただけますか? そうでない場合は、opcache 構成をチェックして、少なくとも次のパラメータを確認してください。
zend_extension=opcache.so;
opcache.enable=1; # on or off on your config ?
opcache.memory_consumption=64; # Too small for you ?
opcache.max_accelerated_files=2000; # maybe to small for you ?
opcache.force_restart_timeout="180"; # Oh!!! This is the time of your outage!!
force_restart_timeoutを180から120に変更し、opcache.log_verbosity_levelを3以上の値に変更して、停止時間が通常より短くなるかどうかを確認します。その後、レビューをお勧めします。opcache ランタイム構成サイトに合わせて適切に調整します。
答え2
これは PHP のバグだったようで、2017 年 2 月 16 日のバージョン 7.0.16 で修正されました。
バグを修正しました #67583(max_children 制限で fastcgi_end_request が 2 倍になります)。
答え3
サーバーブロックを確認する高速パスnginx サイト構成で。
すべてのサイト設定の fastcgi_pass を更新するには、次のコマンドを実行します。
sed "s/php5/php/php7.0/g" *.conf -i
サービス nginx && php7.0-fpm