avisos session_write_close do php

avisos session_write_close do php

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

Nosso servidor é altamente populoso e muitos usuários estão logados ao mesmo tempo. A maioria desses usuários não vê esses session_write_closeavisos. Alguns o fazem, o que torna quase impossível encontrar a causa e corrigi-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)

Então fiz uma verificação, veja quantos arquivos tem naquele diretório 9431e 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? Afetando atualmente <1% dos nossos usuários, queremos apenas 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!

Responder1

Com um servidor altamente carregado, eu usaria memcached(talvez até redis?) Para armazenamento de sessão. Então, se eu estivesse na sua situação, provavelmente configuraria isso por si só e veria se o problema simplesmente desapareceu por acaso.

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 executando no cron ou em algum sistema de enfileiramento de trabalhos.

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

A taxa na qual isso ocorre é de 0,1% do tempo, o que estaria de acordo com sua session.gc_divisorconfiguração?

Seus processos php estão sendo executados como usuário nginx? É o php, e não o nginx, que faz a limpeza com base nas session.gc_*configurações. Se o php estiver rodando como nginx, isso é bom em termos de acesso aos arquivos de sessão do 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 há para limpar.

Eu também ficaria preocupado se você não estivesse configurando session.save_pathalgo específico para seu aplicativo. Isso significaria 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.

Responder2

A observação óbvia que fiz a partir da sua pergunta é que você tem muitos gargalos ao tentar salvar arquivos em /opt/php55/var/lib/php/session-nginx. Portanto, sua solução é aliviar o gargalo, primeiro diagnosticando o que especificamente está errado.
Supondo que seja uma corrida para gravar no disco e os erros sejam um sinal de desistência, esperaria erros de dmesg mostrando problemas de gravação no disco. Se for esse o caso, você pode gravar na memória ou outras soluções que resultem em um 'disco' mais rápido.
mc0e menciona memcached em vez de usar save_handle=files, é 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 (portanto, tem tempos de gravação rápidos), mas não precisa de um aplicativo novo.
Eu também faria a pergunta: que tipo de sistema de arquivos está em /opt/php55/var/lib/php/session-nginx? Você não precisa de todo o diário complexo do ext3/4 para o que é basicamente uma operação do tipo mktmp. Você pode querer criar uma pasta em /tmp e vinculá-la 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 atingindo o limite de desempenho. 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 for implementado (eu sei que o AMCC pode espalhar gravações entre discos no Raid-1, mas nem todas as implementações de RAID-1 faça isso, eu sei que o ataque de software não faz). Meu antigo chefe jurou pelo Raid-5 por esse motivo, e desde que seja um ataque de hardware real (o RAID-5 pode ser caro na CPU se não for), isso acelerará drasticamente o rendimento do disco. Outra opção é um disco de estado sólido, mas, na verdade, se você estiver seguindo esse caminho, sugiro usar memcached ou tmpfs, pois mais memória é sempre um bom plano (em relação a qualquer outro hardware novo).

A solução mais simples, porém, será criar /tmp/session-nginx e link simbólico ou montar /opt/php55/var/lib/php/session-nginx em /tmp/session-nginx/

Responder3

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

A outra parte da pergunta descreve um erro de gravação que parece ser de natureza aleatória. Não é isso que espero de permissões incorretas. Eu suspeito que você tem muitos arquivos abertos.

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

  1. aumentar o limite de arquivos abertosvocê 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 4.000 do mesmo usuário.

  2. reduza o maxrequestperchilds para 1000isso fará com que cada servidor http seja reiniciado após atender 1.000 clientes.

  3. reduzir MaxClientseaumentar ListenBacklog. Isso é muito, muito contra-intuitivo, mas se você definir MaxClients/Servers muito alto, muitos processos lutarão por recursos em seu servidor e causarão gargalos. Isso depende muito dos tipos de gargalos que você possui. O meu são os servidores de banco de dados.

informação relacionada