Qual configuração php5-fpm para alto número de conexões simultâneas + nginx

3

Por favor, ajude-me a ajustar minha configuração para o php5-fpm e o nginx.

O problema é que meu log php5-fpm continua reportando scripts lentos e matando um encadeamento filho.

Servidor dedicado, quad xeon, 32Gb Ram. 1 aplicativo php / site em execução.

Aplicativo Php: Resumindo, mecanismo de pesquisa, resultados disparam solicitações de curl. O tempo de carregamento da página é geralmente de 2 a 3 segundos por pesquisa.

Aqui está o que eu acho que está acontecendo Estou recebendo 750 usuários php concorrentes realizando pesquisas. Eu só posso definir pm.max_children = 400 devido a limites de RAM. Eu suponho 50Mb por usuário (thread filho) para que = 20GB. Eu estou supondo que cada usuário = 1 thread filho. Portanto, pm.max_children não é suficiente para cobrir os 750 usuários php ativos que estão fazendo pesquisas que demoram 3 segundos.

Então, eu acho que estou vendo filas de usuários porque vejo três segundos se transformando em quatro a sete segundos. Como os usuários enfileiram acho que o script está ficando lento acionar a mensagem de log de erro e php5-fpm pm mata o filho?

Isso é o que eu acho que está acontecendo. Eu forneci minha saída de log de erro, nginx, php5-fpm config abaixo.

Eu realmente aprecio qualquer conselho sobre se eu posso ajustar minha configuração e se de fato pm.max_children deve ser pelo menos igual ao seu máximo de usuários simultâneos, tendo em mente que minhas pesquisas php estão abertas por cerca de 3 segundos. Preciso de muito mais memória ou talvez de servidores adicionais?

Esta é a minha memória, mas eu só reiniciei o nginx cerca de 30 minutos atrás

:/var/log# free -m
             total       used       free     shared    buffers     cached
Mem:         32151      26175       5975          0        186      13334
-/+ buffers/cache:      12654      19496
Swap:        32739          5      32734

php5-fpm: www.conf: gerenciador de processos está definido como estático

Estou usando estática porque achei que todas as crianças estariam disponíveis instantaneamente em vez de spawn time e estou executando apenas 1 aplicativo na caixa.

;pm = dynamic
pm = static

;pm.max_children = 10
pm.max_children = 400


;pm.start_servers = 4
pm.start_servers = 150


;pm.min_spare_servers = 2
pm.min_spare_servers = 32


;pm.max_spare_servers = 6
pm.max_spare_servers = 64


;pm.max_requests = 500
pm.max_requests = 10000

Erros nos logs do php5-fpm

Devo esclarecer, o comportamento que vejo sob alta carga, 750 usuários de uma vez, é que os resultados da pesquisa armazenados em cache e não armazenados em cache começam a demorar mais. isto é > 1 segundo para cache e entre 4 e 7 segundos para não armazenado em cache. Assim, à medida que os usuários enfileiram-se e aguardam, acho que os tempos de pesquisa aumentam e isso se transforma em um ponto em que os scripts são lentos sob a carga. Provoque um aviso e a criança será morta.

por exemplo. isso foi logo após o reinício

[04-Jun-2013 20:11:07] NOTICE: Finishing ...
[04-Jun-2013 20:11:11] NOTICE: exiting, bye-bye!
[04-Jun-2013 20:11:12] NOTICE: fpm is running, pid 17899
[04-Jun-2013 20:11:12] NOTICE: ready to handle connections
[04-Jun-2013 20:27:28] WARNING: [pool www] child 18200, script '/home/site/public_html/index.php' (request: "POST /index.php") executing too slow (10.827363 sec), logging
[04-Jun-2013 20:27:28] WARNING: [pool www] child 18138, script '/home/site/public_html/index.php' (request: "POST /index.php") executing too slow (10.827034 sec), logging
[04-Jun-2013 20:27:28] NOTICE: child 18138 stopped for tracing
[04-Jun-2013 20:27:28] NOTICE: about to trace 18138
[04-Jun-2013 20:27:28] NOTICE: finished trace of 18138
[04-Jun-2013 20:27:28] NOTICE: child 18200 stopped for tracing
[04-Jun-2013 20:27:28] NOTICE: about to trace 18200
[04-Jun-2013 20:27:28] NOTICE: finished trace of 18200
[04-Jun-2013 20:52:52] WARNING: [pool www] child 17948, script '/home/site/public_html/index.php' (request: "GET /index.php") executing too slow (11.724081 sec), logging
[04-Jun-2013 20:52:52] NOTICE: child 17948 stopped for tracing
[04-Jun-2013 20:52:52] NOTICE: about to trace 17948
[04-Jun-2013 20:52:52] ERROR: failed to ptrace(PEEKDATA) pid 17948: Input/output error (5)
[04-Jun-2013 20:52:52] NOTICE: finished trace of 17948
[04-Jun-2013 20:58:22] WARNING: [pool www] child 18287, script '/home/site/public_html/index.php' (request: "POST /index.php") executing too slow (10.701504 sec), logging
[04-Jun-2013 20:58:22] NOTICE: child 18287 stopped for tracing
[04-Jun-2013 20:58:22] NOTICE: about to trace 18287
[04-Jun-2013 20:58:22] NOTICE: finished trace of 18287
[04-Jun-2013 21:19:22] WARNING: [pool www] child 18224, script '/home/site/public_html/index.php' (request: "GET /index.php") executing too slow (10.005466 sec), logging
[04-Jun-2013 21:19:22] WARNING: [pool www] child 18197, script '/home/site/public_html/index.php' (request: "GET /index.php") executing too slow (12.141221 sec), logging
[04-Jun-2013 21:19:22] WARNING: [pool www] child 17946, script '/home/site/public_html/index.php' (request: "GET /index.php") executing too slow (11.107080 sec), logging
[04-Jun-2013 21:19:22] NOTICE: child 17946 stopped for tracing
[04-Jun-2013 21:19:22] NOTICE: about to trace 17946
[04-Jun-2013 21:19:22] NOTICE: finished trace of 17946
[04-Jun-2013 21:19:22] NOTICE: child 18197 stopped for tracing
[04-Jun-2013 21:19:22] NOTICE: about to trace 18197
[04-Jun-2013 21:19:22] NOTICE: finished trace of 18197
[04-Jun-2013 21:19:22] NOTICE: child 18224 stopped for tracing
[04-Jun-2013 21:19:22] NOTICE: about to trace 18224
[04-Jun-2013 21:19:22] NOTICE: finished trace of 18224
[04-Jun-2013 21:19:26] WARNING: [pool www] child 18197, script '/home/site/public_html/index.php' (request: "GET /index.php") execution timed out (15.475021 sec), terminating
[04-Jun-2013 21:19:26] WARNING: [pool www] child 18055, script '/home/site/public_html/index.php' (request: "GET /index.php") executing too slow (12.927407 sec), logging
[04-Jun-2013 21:19:26] NOTICE: child 18055 stopped for tracing
[04-Jun-2013 21:19:26] NOTICE: about to trace 18055
[04-Jun-2013 21:19:26] NOTICE: finished trace of 18055
[04-Jun-2013 21:19:26] WARNING: [pool www] child 18197 exited on signal 15 (SIGTERM) after 4094.193190 seconds from start
[04-Jun-2013 21:19:26] NOTICE: [pool www] child 5137 started
[04-Jun-2013 21:24:49] WARNING: [pool www] child 17918, script '/home/site/public_html/index.php' (request: "GET /index.php") executing too slow (11.367854 sec), logging
[04-Jun-2013 21:24:49] NOTICE: child 17918 stopped for tracing
[04-Jun-2013 21:24:49] NOTICE: about to trace 17918
[04-Jun-2013 21:24:49] NOTICE: finished trace of 17918
[04-Jun-2013 21:24:53] WARNING: [pool www] child 18226, script '/home/site/public_html/index.php' (request: "GET /index.php") executing too slow (10.763667 sec), logging
[04-Jun-2013 21:24:53] WARNING: [pool www] child 18206, script '/home/site/public_html/index.php' (request: "GET /index.php") executing too slow (12.060464 sec), logging
[04-Jun-2013 21:24:53] WARNING: [pool www] child 18073, script '/home/site/public_html/index.php' (request: "GET /index.php") executing too slow (11.846097 sec), logging
[04-Jun-2013 21:24:53] NOTICE: child 18073 stopped for tracing
[04-Jun-2013 21:24:53] NOTICE: about to trace 18073
[04-Jun-2013 21:24:53] NOTICE: finished trace of 18073
[04-Jun-2013 21:24:53] NOTICE: child 18206 stopped for tracing
[04-Jun-2013 21:24:53] NOTICE: about to trace 18206
[04-Jun-2013 21:24:53] NOTICE: finished trace of 18206
[04-Jun-2013 21:24:53] NOTICE: child 18226 stopped for tracing
[04-Jun-2013 21:24:53] NOTICE: about to trace 18226
[04-Jun-2013 21:24:53] NOTICE: finished trace of 18226
[04-Jun-2013 21:24:56] WARNING: [pool www] child 5137, script '/home/site/public_html/index.php' (request: "GET /index.php") executing too slow (12.055624 sec), logging
[04-Jun-2013 21:24:56] WARNING: [pool www] child 18206, script '/home/site/public_html/index.php' (request: "GET /index.php") execution timed out (15.395149 sec), terminating
[04-Jun-2013 21:24:56] WARNING: [pool www] child 17996, script '/home/site/public_html/index.php' (request: "GET /index.php") executing too slow (12.145728 sec), logging
[04-Jun-2013 21:24:56] WARNING: [pool www] child 17918, script '/home/site/public_html/index.php' (request: "GET /index.php") execution timed out (18.036700 sec), terminating
[04-Jun-2013 21:24:56] NOTICE: child 17996 stopped for tracing
[04-Jun-2013 21:24:56] NOTICE: about to trace 17996
[04-Jun-2013 21:24:56] NOTICE: finished trace of 17996
[04-Jun-2013 21:24:56] NOTICE: child 5137 stopped for tracing
[04-Jun-2013 21:24:56] NOTICE: about to trace 5137
[04-Jun-2013 21:24:56] NOTICE: finished trace of 5137
[04-Jun-2013 21:24:56] WARNING: [pool www] child 17918 exited on signal 15 (SIGTERM) after 4424.343036 seconds from start
[04-Jun-2013 21:24:56] NOTICE: [pool www] child 6706 started
[04-Jun-2013 21:24:56] WARNING: [pool www] child 18206 exited on signal 15 (SIGTERM) after 4424.264130 seconds from start
[04-Jun-2013 21:24:56] NOTICE: [pool www] child 6707 started
[04-Jun-2013 21:24:59] WARNING: [pool www] child 17996, script '/home/site/public_html/index.php' (request: "GET /index.php") execution timed out (15.479201 sec), terminating
[04-Jun-2013 21:24:59] WARNING: [pool www] child 17996 exited on signal 15 (SIGTERM) after 4427.655572 seconds from start
[04-Jun-2013 21:24:59] NOTICE: [pool www] child 6708 started

Aqui está minha configuração nginx

user www-data;
worker_processes 4;
pid /var/run/nginx.pid;
worker_rlimit_nofile 20000;

events {
    #worker_connections 768;
    #worker_connections 19000;

    #multi_accept on;
    use epoll;
    #worker_connections 10240;  
    worker_connections 4096;
}


http {

    ##
    # Basic Settings
    ##

    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    #keepalive_timeout 65;
    #keepalive_timeout 5;

#added
    client_body_timeout   15;
    client_header_timeout 15;
    keepalive_timeout     15;
    send_timeout          15;

site.conf

proxy_buffer_size   128k;
    proxy_buffers   4 256k;
    proxy_busy_buffers_size   256k;

    fastcgi_connect_timeout 60;
    fastcgi_send_timeout 180;
    fastcgi_read_timeout 180;
    fastcgi_buffer_size 128k;
    fastcgi_buffers 4 256k;
    #fastcgi_buffers 256 16k; #4096k total
    fastcgi_busy_buffers_size 256k;
    fastcgi_temp_file_write_size 256k;
    fastcgi_intercept_errors on;

php5-fpm está conectando via porta TCP

Obrigado

    
por B p 05.06.2013 / 03:40

4 respostas

4

Acho que você provavelmente está executando muitos processos php simultâneos, mas é difícil saber sem mais informações sobre onde estão os gargalos de recursos. Eu imagino que você provavelmente está limitado pelo Disk IO e / ou CPU, e que todos os seus processos paralelos em PHP estão competindo por eles e ficando cada vez mais lentos. Em algum momento, a sobrecarga de comutação de processos se torna um fator significativo, e você obtém menos throughput do que mais tendo muitos processos em execução. Você também pode estar se arriscando, ou arriscando, situações em que você fica sem RAM e começa a trocar, o que é muito ruim. Confie no nginx sendo capaz de enfileirar os pedidos e manter uma maior taxa de processamento de pedidos mais rápidos, enquanto executa menos deles simultaneamente.

Eu geralmente escolho de 5 a 50 processos PHP, com ambas as extremidades desse intervalo sendo um pouco excepcionais. Mais geralmente 10-15. Com muito sistemas de disco de alto desempenho, e mais do que os habituais 16 ou mais núcleos, pode fazer sentido ter mais processos, mas isso geralmente é uma economia falsa comparada a ter um número maior de servidores mais baratos. Na minha experiência, a menos que você tenha um código muito mal escrito, geralmente há pouco benefício em ter mais de 15 processos php em paralelo em um único servidor, e se houver um benefício, é provável que seja estabilidade em vez de throughput. diante de solicitações patologicamente longas que se acumulam e não deixam processos sobressalentes disponíveis.

Se você tiver várias bases de código com pools de processos separados, talvez você queira um grande número de processos, mas provavelmente não deseja mais de 3 a 5 processos por pool.

Você deseja muitas conexões de trabalho do nginx que manipulam arquivos estáticos. É improvável que haja qualquer melhoria além de 4096, e somente em circunstâncias incomuns você veria uma diferença entre 1000 e 4000. (A menos que você esteja servindo principalmente arquivos estáticos - é um cenário bem diferente, mas já que você está falando sobre processos PHP neste caixa eu não imagino que é o caso aqui).

Eu suspeito que seu tempo limite seja muito longo. Se não houver nada acontecendo, desligue a conexão e passe para a próxima.

    
por 05.06.2013 / 14:35
2

1) Memória - A primeira coisa que eu vejo é por que seus scripts precisam de 50MB de memória se tudo o que eles estão fazendo é uma pesquisa simples - suponho que você não tenha retornado vários megabytes de dados por usuário , se você estiver atendendo centenas de solicitações por segundo.

Há um bug na biblioteca de conectores do MySQL que faz o PHP alocar o tamanho máximo possível para qualquer TEXTO ou BLOB, em vez de apenas a quantidade real de memória necessária. Isso pode ser corrigido movendo-se para a biblioteca MySQLND, sem necessidade de alteração de código.

2) Sua configuração de pm.max_requests = 10000 provavelmente não é uma ótima escolha. Se cada solicitação levar 2 segundos, você está instruindo o gerente de processo a reiniciar cada processo após 20.000 segundos ou quase 6 horas. Isso parece muito tempo, e seria tempo suficiente para qualquer vazamento de memória para derrubar o processo. Colocá-lo de volta para 500 ainda seria apenas uma reinicialização a cada 15 minutos, o que não teria efeito sobre o desempenho, mas provavelmente seria mais estável.

3) Como Michael disse, mesmo que você seja capaz de permitir tantos processos quantos os usuários conectam, você ainda precisa descobrir onde o gargalo realmente está. Mesmo que você tenha várias centenas de processos do PHP de uma só vez, se eles estão apenas esperando que o SQL Server fique disponível, eles sempre ficarão na fila para esperar e, eventualmente, começar a expirar.

A menos que você possa remover o gargalo, será necessário implementar um mecanismo de limitação de taxa para permitir apenas quantas consultas a sua configuração de servidor puder manipular ou uma degradação elegante para rejeitar solicitações que seu servidor não consiga atualmente manusear.

    
por 07.06.2013 / 16:31
1

Se tudo mais falhar ... acho que você pode lidar com isso no código. Você pode criar um "sistema de tickets" para permitir um determinado número de pesquisas simultaneamente e dar aos usuários um tempo de espera aproximado. Algo como "sua pesquisa começará em N segundos".

    
por 11.11.2013 / 13:01
0

Ainda não posso comentar (não é suficiente), então vou postar uma resposta: Seria bom ter seus registros nginx também.

Sobre o seu pool.d / www config: Se você colocar seu pm em estático, a maioria de suas variáveis não terá nenhum efeito, são max_children que afetarão principalmente sua configuração. ( link ) Tente talvez com um PM "ondemand".

Você não deve começar com um pm.start_servers tão alto. Você deve diminuir também seus min_spare_servers.

Sobre sua configuração do nginx: link "max_clients = worker_processes * worker_connections"

Seu valor "worker_rlimit_nofile" parece incorreto para mim.

Veja o link para usar todos os seus núcleos também.

    
por 05.06.2013 / 10:02

Tags