php-fpm + sockets persistentes = 502 gateway inválido

1

Coloque seus óculos de leitura - isso será muito longo.

Primeiro, o que estou fazendo. Estou construindo uma interface web-app para alguns dispositivos tcp particularmente lentos. Abrir um soquete para eles leva 200ms e um ciclo fwrite / fread leva outros 300ms. Para reduzir a necessidade de ambas as ações em cada solicitação, estou abrindo um soquete tcp persistente que reduz o tempo de resposta pelos 200ms mencionados anteriormente. Eu esperava que o PHP-FPM compartilhasse as conexões persistentes entre pedidos de clientes diferentes (e de fato funciona!), Mas há alguns problemas que eu não consegui resolver depois de 2 dias de internet, lendo logs e modificando configurações. Eu reduzi um pouco isso.

Configuração:

  • Servidor Ubuntu 13.04 x64 (totalmente atualizado) no Linode
  • PHP 5.5.0-6 ~ raring + 1 (fpm-fcgi)
  • nginx / 1.5.2

Configuração relevante:

nginx

  • worker_processes 4;

php-fpm / pool.d

  • pm = dinâmico
  • pm.max_children = 2
  • pm.start_servers = 2
  • pm.min_spare_servers = 2

Vamos do grosso ao detalhe do que acontece. Depois de um novo começo, eu tenho 4x processos nginx e 2x processos php5-fpm esperando para atender pedidos. Então eu envio pedidos a cada dois segundos para o script. O primeiro leva um tempo para abrir a conexão do soquete e retorna com os dados em cerca de 500ms, o segundo retorna dados em 300ms (yay é reutilizar o soquete), o terceiro também tem sucesso em cerca de 300ms, o quarto pedido = 502 Bad Gateway , mesmo com o 5º. O sexto pedido mais uma vez retorna dados, exceto que agora demorou 500ms novamente. O processo se repete por vários ciclos, após o que a cada 4 solicitações resultam em 2x 502 Gateways ruins e 2x respostas de dados de 500 ms.

Se eu dobrar todos os valores do conjunto de fpm e tiver 4x processos php-fpm em execução, os ciclos se instalam com 4x respostas bem-sucedidas de 500ms seguidas por 4x erros de Gateway Incorreto. Se eu não usar soquetes persistentes, esse problema desaparece, mas cada solicitação é de 500 ms. O que eu suspeito que está acontecendo é que o soquete persistente mantém cada processo php-fpm de inativo e amarra, então o próximo é escolhido até que nenhum seja deixado e, quando errarem, talvez sejam reiniciados e se tornem disponíveis na próxima rodada. robin loop ut o socket morre com o processo. Ainda não verifiquei o 'slowlog', mas o log de erros do nginx mostra muito isso:

* 188 recv () falhou (104: Conexão redefinida por peer) durante a leitura do cabeçalho de resposta do upstream, cliente: ...

Todas as sugestões na internet sobre como consertar o gateway ruim nginx / php-fpm / 502 estão relacionadas à configuração incorreta de alta carga ou fcgi_pass. Este não é o caso aqui. Aumentando os buffers / tamanhos, mudando os timeouts, trocando o socket unix pelo socket tcp pelo fcgi_pass, aumentando os limites de conexão no sistema ... nada disso se aplica aqui.

Eu tive algum outro sucesso em configurar o pm = ondemand ao invés de dinâmico, mas assim que o processo inicial do fpm foi eliminado depois de ficar ocioso, o soquete persistente desapareceu para todos os spawns subseqüentes do php-fpm. Para o script php, estou usando stream_socket_client () com um sinalizador STREAM_CLIENT_PERSISTENT. Um loop while / stream_select () para detectar dados de soquete e fread ($ sock, 4096) para capturar os dados. Eu não chamo fclose () obviamente.

Se alguém tiver algumas perguntas adicionais ou conselhos sobre como obter um soquete persistente sem amarrar os processos do php-fpm além da conclusão da solicitação, ou talvez algumas outras coisas para tentar, agradeço.

alguns links úteis:

Erro Nginx + php-fpm - recv ()

Nginx + php-fpm" 504 Tempo limite do gateway "erro com quase zero de carga (em um servidor de teste)

Nginx + PHP-FPM "erro 104 Conexão redefinida pelo par" causa postagens duplicadas ocasionais

link

link

link

link

link

link

    
por leeoniya 11.10.2013 / 19:04

1 resposta

1

Eu relatei esse problema na lista de discussão. acabou sendo um bug no php que agora está resolvido no git, deve estar na próxima versão do php, w00t!

se alguém estiver interessado: link

    
por 21.10.2013 / 23:44