Назад | Перейти на главную страницу

предупреждения php session_write_close

Все наши ошибки регистрируются в NewRelic, и мы всегда видели несколько предупреждений session_write_close в журнале ошибок. Однако частота ошибок увеличилась, и теперь наш 24-часовой журнал переполняется.

Наш сервер густонаселен, и многие пользователи входят в систему одновременно. Большинство этих пользователей не видят эти session_write_close предупреждения. Некоторые делают это, что делает практически невозможным найти причину и исправить ее.

Это полное сообщение об ошибке:

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)

Итак, я проверил, сколько файлов в этом каталоге 9431 и какие права были -rw------- 1 nginx nginx.

Я не вижу ничего плохого в моей конфигурации, правах файла и т. Д.

У нас нет вариантов. Что я могу сделать, чтобы решить эту проблему? В настоящее время затрагивая <1% наших пользователей, мы просто хотим, чтобы наша ставка была как можно ниже.

Вот список моей конфигурации 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

Некоторая статистика сервера: CentOS 6.6 PHP 5.5.28 Nginx 1.6.2 Любая помощь приветствуется!

С сильно загруженным сервером я бы использовал memcached (может быть даже redis?) для хранения сеанса. Так что, если бы я был в вашей ситуации, я бы, вероятно, просто настроил это ради себя, а затем посмотрел, исчезла ли проблема просто случайно.

Я также не стал бы использовать сборку мусора сеанса php, которая вешает сборку мусора на задания веб-запросов. Я бы настроил свое собственное задание, чтобы справиться с этим, либо из cron, либо из какой-либо системы очереди заданий.

У вас уже есть какая-либо система очистки сеанса за пределами сборки мусора сеанса php?

Скорость, с которой это происходит в 0,1% случаев, соответствует вашему session.gc_divisor установка?

Ваши процессы php работают от имени пользователя nginx? Это php, а не nginx, который выполняет очистку на основе session.gc_* настройки. Если php работает как nginx, это хорошо с точки зрения доступа к файлам сеанса php, но, вероятно, плохо с точки зрения совместного использования идентификатора пользователя с сервером nginx.

Вам может потребоваться разрешение на выполнение в этом каталоге сеанса, чтобы ваша сборка мусора могла видеть, что нужно очистить.

Я также был бы обеспокоен, если вы не устанавливаете session.save_path к чему-то конкретному для вашего приложения. Это будет означать, что если у вас есть несколько приложений, совместно использующих один и тот же каталог сеанса, то при запуске сборки мусора побеждает приложение с самым коротким сроком действия, очищая сеансы другого приложения.

Очевидное наблюдение, которое я сделал из вашего вопроса, заключается в том, что у вас слишком много узких мест при попытке сохранить файлы в / opt / php55 / var / lib / php / session-nginx. Итак, ваше решение - уменьшить узкое место, сначала диагностируя, что именно идет не так.
Предполагая, что запись на диск идет в гонке, а ошибки являются признаком отказа, я бы ожидал, что ошибки dmesg будут показывать проблемы с записью на диск. Если это так, вы можете записывать в память или другие решения, которые представляют собой более быстрый «диск».
mc0e упоминает memcached вместо использования save_handle = files, это хороший вариант. Альтернативой memcached может быть tmpfs, который по сути помещает сеанс в память точно так же (поэтому имеет быстрое время записи), но не требует нового приложения.
Я бы также спросил, какая файловая система находится в / opt / php55 / var / lib / php / session-nginx? Вам не нужно все сложное журналирование ext3 / 4 для операций типа mktmp. Возможно, вы захотите создать папку в / tmp и создать символическую ссылку на нее, чтобы уменьшить накладные расходы при создании файлов.
Какая настройка оборудования? Если это один диск без кеширования, вы должны увидеть проблемы в dmesg, если вы достигнете предела его производительности. Я использовал контроллеры AMCC Raid с Raid-1 на всех своих серверах. Если это Raid-1 (зеркало), чтение будет быстрым, но скорость записи будет зависеть от того, насколько хорошо реализован рейд (я знаю, что AMCC может распределять записи по дискам в Raid-1, но не во всех реализациях RAID-1 сделайте это, я знаю, что программный рейд не работает). Мой старый босс поклялся Raid-5 по этой причине, и если это настоящий аппаратный рейд (RAID-5 может быть дорогостоящим для процессора, если это не так), это значительно увеличит пропускную способность вашего диска. Другой вариант - твердотельный диск, но на самом деле, если вы идете по этому пути, я бы посоветовал использовать memcached или tmpfs, поскольку больше памяти - всегда хороший план (по сравнению с любым другим новым оборудованием).

Однако самым простым решением будет создание / tmp / session-nginx и символическая ссылка или монтирование / opt / php55 / var / lib / php / session-nginx в / tmp / session-nginx /

Частично вопрос заключается в том, что такого рода ошибки сложно отслеживать, поэтому я могу предложить явно закрыть сеанс в вашем коде в блоке try / catch. Обработайте исключение, спите и попробуйте еще раз.

Другая часть вопроса описывает ошибку записи, которая кажется случайной по своей природе. Это не то, чего я ожидаю от неправильных разрешений. Я подозреваю, что у вас слишком много открытых файлов.

Есть несколько конфигураций, которые я бы настроил, чтобы увидеть, что произойдет:

  1. увеличить лимит открытых файлов у вас может быть установлен какой-то нижний предел для какой-то части вашей ОС. Например, мой ноутбук поддерживает сотни тысяч открытых файлов, но только 4000 от одного и того же пользователя.

  2. уменьшите maxrequestperchilds до 1000 это заставит перезапустить каждый http-сервер после обслуживания 1000 клиентов.

  3. уменьшить MaxClients и увеличить ListenBacklog. Это очень, очень нелогично, но если вы установите слишком большое значение MaxClients / Servers, многие процессы будут бороться за ресурсы на вашем сервере и вызывать узкие места. Это сильно зависит от того, какие у вас узкие места. Моя - это серверы баз данных.