Atualizei para PHP7 (PHP 7.0.14) em um servidor de produção (CentOS 6.8) há dois dias. Agora, estou recebendo o seguinte erro nos logs do nginx (1.10.2-1).
2017/01/20 08:20:04 [erro] 7654 # 7654: * 153301 upstream enviou registro FastCGI inesperado: 3 ao ler o cabeçalho de resposta do upstream, cliente: XXX.XXX.XXX.XXX, servidor: exemplo.com, solicitação : "GET / HTTP/1.0", upstream: "fastcgi://unix:/var/run/php-fpm/example.fpm.sock:", host: "www.example.com"
- Temos vários sites executando seu pool individual de php-fpm e esse erro ocorre em todos os sites ao mesmo tempo.
- O navegador mostra “502 Bad Gateway” durante esse erro em todos os sites.
- Este erro ocorre por 1-2 minutos e depois disso tudo volta ao normal automaticamente.
- Aconteceu três vezes ao dia, em horários diferentes.
- Não houve problema com o PHP5.
- Eu tentei colocar na lista negra todas as pastas de cache do aplicativo no opcache
Temos outro servidor com configuração semelhante que foi atualizado para PHP7, mas não apresenta esses problemas.
Como devo solucionar e encontrar uma solução para esse problema?
ATUALIZAÇÃO 1
Detalhes do servidor
CPU: 2x Intel (R) Xeon (R) CPU E5-2620 0 @ 2,00 GHz
RAM: 256 GB
SO: CentOS versão 6.8
Kernal: 2.6.32-504.8.1.el6.x86_64
PHP: Usando 7.0.14-3 do repositório IUS
Nginx: 1.10.2-1
O servidor é usado como um servidor web para executar vários sites executando um popular aplicativo PHP de código aberto. Usamos Nginx com php-fpm como backend. Cada site tem um pool php-fpm específico e soquetes diferentes. A aplicação PHP já é compatível com php7 e a única mudança é a atualização para PHP7.
ATUALIZAÇÃO 2
Configuração principal do 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;
}
Modelo de site nginx individual
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;
}
}
Modelo de pool 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"
ATUALIZAÇÃO 3 Quando o problema ocorre
Solicitação 1
GET /moodle/ HTTP/1.0
User-Agent: Pingdom.com_bot_version_1.4_(http://www.pingdom.com/)
Host: www.example.com
Cabeçalho recebido
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
Conteúdo recebido
<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>
Responder1
Ok, todos os pools php-fpm ficam inativos por vários minutos ao mesmo tempo, e a única coisa que mudou com o php 5.6 => php 7. O que mudou com o php7? O que é global em todos os pools php-fpm? O opcache. Você poderia ter a gentileza de fornecer seu php.ini? Caso contrário, verifique a configuração do opcache e verifique pelo menos estes parâmetros:
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!!
altere o force_restart_timeout de 180 para 120, altere opcache.log_verbosity_level para algo >=3 e veja se a interrupção é menor que o normal.. Então sugiro sua revisãoconfiguração de tempo de execução do opcachee ajuste-o corretamente para o seu site.
Responder2
Parece que foi um bug no PHP que foi corrigido na versão 7.0.16 de 16 de fevereiro de 2017.
Bug corrigido #67583(duplo fastcgi_end_request no limite max_children).
Responder3
Verifique o bloco do servidor parafastcgi_passna configuração do site nginx.
Para atualizar o fastcgi_pass para todas as configurações do site, execute:
sed "s/php5/php/php7.0/g" *.conf -i
serviço nginx && php7.0-fpm