php session_write_close warnings

1

Todos os nossos erros são registrados no NewRelic, e sempre vimos alguns avisos de session_write_close no log de erros. No entanto, a taxa de erro é aumentada e agora está inundando nosso log de 24 horas.

Nosso servidor é muito populado e muitos usuários estão conectados ao mesmo tempo. A maioria desses usuários não vê esses session_write_close avisos. Alguns fazem, o que torna quase impossível encontrar a causa e consertá-la.

Esta é a mensagem de erro completa:

Error message
E_WARNING: session_write_close(): Failed to write session data (files).    
Please verify that the current setting of session.save_path is correct        
(/opt/php55/var/lib/php/session-nginx)

Por isso, verifiquei quantos arquivos estão nesse diretório 9431 e quais eram os direitos -rw------- 1 nginx nginx .

Não vejo nada de errado com minha configuração, direitos de arquivo etc.

Estamos sem opções. O que posso fazer para resolver esse problema? Atualmente afetando < 1% de nossos usuários, só queremos manter nossa taxa o mais baixa possível.

Aqui está uma lista da minha configuração do php.ini.

Directive   Local Value Master Value
session.auto_start  Off Off
session.cache_expire    180 180
session.cache_limiter   nocache nocache
session.cookie_domain   no value    no value
session.cookie_httponly Off Off
session.cookie_lifetime 0   0
session.cookie_path /   /
session.cookie_secure   Off Off
session.entropy_file    /dev/urandom    /dev/urandom
session.entropy_length  32  32
session.gc_divisor  1000    1000
session.gc_maxlifetime  1440    1440
session.gc_probability  1   1
session.hash_bits_per_character 5   5
session.hash_function   0   0
session.name    PHPSESSID   PHPSESSID
session.referer_check   no value    no value
session.save_handler    files   files
session.save_path   /opt/php55/var/lib/php/session-nginx    /opt/php55/var/lib/php/session-nginx
session.serialize_handler   php php
session.upload_progress.cleanup On  On
session.upload_progress.enabled On  On
session.upload_progress.freq    1%  1%
session.upload_progress.min_freq    1   1
session.upload_progress.name    PHP_SESSION_UPLOAD_PROGRESS PHP_SESSION_UPLOAD_PROGRESS
session.upload_progress.prefix  upload_progress_    upload_progress_
session.use_cookies On  On
session.use_only_cookies    On  On
session.use_strict_mode Off Off
session.use_trans_sid   0   0

Algumas estatísticas do servidor: CentOS 6.6 PHP 5.5.28 Nginx 1.6.2 Qualquer ajuda é bem vinda!

    
por Jordi Kroon 14.10.2015 / 09:55

3 respostas

1

Com um servidor altamente carregado, eu usaria memcached (talvez até redis ?) para armazenamento de sessão. Então, se eu estivesse em sua situação, eu provavelmente configuraria isso para o seu próprio bem e, em seguida, verificaria se o problema tinha simplesmente desaparecido.

Eu também não usaria a coleta de lixo da sessão do php, que suspende a coleta de lixo dos trabalhos de solicitação da web. Eu configurei meu próprio trabalho para lidar com isso, seja em execução no cron ou em algum sistema de enfileiramento de tarefas.

Você já tem algum tipo de sistema de limpeza de sessão fora da coleta de lixo da sessão do php?

A taxa na qual isso está ocorrendo é de 0,1% do tempo, o que estaria alinhado com a configuração session.gc_divisor ?

Os seus processos php estão sendo executados como o usuário nginx? É php, em vez de nginx, que faz a limpeza com base nas configurações de session.gc_* . Se o php está rodando como nginx, isso é bom em termos de acesso aos arquivos da sessão php, mas provavelmente ruim em termos de compartilhamento de um id de usuário com o servidor nginx.

Você pode precisar da permissão de execução nesse diretório de sessão para que sua coleta de lixo possa ver o que está lá para limpar.

Também ficaria preocupado se você não estivesse definindo session.save_path para algo específico para seu aplicativo. Isso significa que, se você tiver vários aplicativos compartilhando o mesmo diretório de sessão, quando a coleta de lixo for executada, o aplicativo com a expiração mais curta vencerá, limpando as sessões do outro aplicativo.

    
por 21.10.2015 / 03:54
0
A observação óbvia que fiz da sua pergunta é que você tem muito afunilamento ao tentar salvar arquivos em / opt / php55 / var / lib / php / session-nginx. Portanto, sua solução é facilitar o gargalo, primeiro diagnosticando o que especificamente está dando errado.
Assumindo que é corrida, para gravar em disco, e os erros são um sinal de desistir, eu esperaria erros dmesg mostrando problemas de gravação em disco. Se for esse o caso, você pode gravar na memória ou em outras soluções que resultem em um 'disco' mais rápido.
mc0e menciona o memcached em vez de usar save_handle = files, essa é uma boa opção. Uma alternativa ao memcached, pode ser o uso de tmpfs, que essencialmente coloca a sessão na memória da mesma forma (por isso, tem tempos de gravação rápidos), mas não precisa de um novo aplicativo. Também gostaria de perguntar qual é o tipo de sistema de arquivos em / opt / php55 / var / lib / php / session-nginx? Você não precisa de todo o diário complexo de ext3 / 4 para o que é basicamente uma operação do tipo mktmp. Você pode querer criar uma pasta em / tmp e criar um link simbólico para garantir menos sobrecarga na criação de arquivos.
Qual é a configuração do hardware? Se for um único disco sem cache, você deverá ver problemas no dmesg se estiver no limite de seu desempenho. Eu usei controladores AMCC Raid com Raid-1 em todos os meus servidores. Se for Raid-1 (espelho), será rápido de ler, mas a velocidade de gravação dependerá de quão bem o ataque é implementado (eu sei que o AMCC pode espalhar gravações em discos no Raid-1, mas nem todas as implementações do RAID-1 faça isso, eu sei que o software raid não funciona). Meu antigo patrão jurou por Raid-5 por esse motivo, e enquanto for um ataque real de hardware (o RAID-5 pode ser caro na CPU, se não for o caso), isso acelerará drasticamente o rendimento do seu disco. Outra opção é um disco de estado sólido, mas, na verdade, se você estiver seguindo esse caminho, sugiro usar memcached ou tmpfs, já que mais memória é sempre um bom plano (sobre qualquer outro novo hardware).

A solução mais simples, porém, será criar / tmp / session-nginx e symlink ou montar / opt / php55 / var / lib / php / session-nginx para / tmp / session-nginx /

    
por 23.10.2015 / 14:22
0

Parte da questão é sobre a dificuldade de rastrear esses tipos de erros, então eu sugiro que feche explicitamente a sessão em seu código dentro de um bloco try / catch. Lidar com a exceção, durma e tente novamente.

A outra parte da questão descreve um erro de gravação que parece ser aleatório por natureza. Isso não é o que eu espero de permissões incorretas. Eu suspeito que você tenha muitos arquivos abertos.

Existem algumas configurações que eu faria para ver o que acontece:

  1. aumenta o limite de arquivos abertos você pode ter algum limite inferior definido em alguma parte do seu sistema operacional. Por exemplo, meu notebook suporta centenas de milhares de arquivos abertos, mas apenas 4000 do mesmo usuário.

  2. reduza o maxrequestperchilds para 1000 isso fará com que cada servidor http reiniciar depois de servir 1000 clientes.

  3. reduza os MaxClients e increase ListenBacklog . Isso é muito, muito contra-intuitivo, mas se você definir MaxClients / Servers muito altos, muitos processos irão lutar por recursos em seu servidor e causar bottleneks. Isso depende muito dos tipos de bottleneks que você tem. O meu é o servidor de banco de dados.

por 23.10.2015 / 21:46

Tags