2010-12-02 6 views
25

, так как через несколько часов наш сервер зависает каждый раз, когда вы выполняете session_start.session_start висит

Для тестирования я создал скрипт, который выглядит следующим образом:

<?php 
session_start(); 
?> 

Вызов из консоли зависаний и даже не может быть остановлен с Ctrl-C, только убить -9 работ. То же самое для вызова через Apache. /var/lib/php/session/ остается пустым, но разрешения абсолютно прекрасны, www может писать, а также имеет разрешения на чтение для всех родительских папок.

По словам администраторов, на сервере никаких изменений не было, и для сеансов не было зарегистрировано никакого специального кода. Сервер CentOS 4 или 5, и вчера все работало отлично. Мы перезагрузили сервер и обновили PHP, но ничего не изменилось.

У меня кончились идеи, любые предложения?

UPDATE

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

+0

Проверьте журналы системных ошибок - достаточно места? Ваши лог-файлы не переполнены? У вас не заканчивается inodes? Есть ли ограничение на количество файлов в/tmp/session или где вы храните свои файлы? – Piskvor 2010-12-02 09:00:32

+0

Лог-файлы не отображают ошибок, а хранилище находится в NFS. Другой сервер, получающий доступ к одной и той же NFS, работает для проекта. Количество файлов сеансов не ограничено. – dbemerlin 2010-12-02 09:23:37

+0

Связь между сервером A и NSF сомнительна. Проверьте соединение снова. – ajreal 2010-12-02 09:42:27

ответ

22

Есть много причин, вот некоторые из них:

A. Файл сессии может быть открыт исключительно. Когда блокировка файла не выпущена должным образом по какой-либо причине, это приводит к тому, что session_start() бесконечно зависает при любых будущих сценариях сценария. Временное решение: использовать session_set_save_handler() и убедитесь, что функция записи использует fopen($file, 'w') instead of fopen($file, 'x')

B. Никогда не используйте следующее в файле php.ini (файл Entropie в «/dev/random»), это приведет к тому, session_start() повесить:

<?php 
ini_set("session.entropy_file", "/dev/random"); 
ini_set("session.entropy_length", "512"); 
?> 

C. session_start() нужен каталог для записи.

Вы можете получить Apache plus PHP, работающий в обычной учетной записи пользователя. Конечно, Apache, конечно, должен слушать другой порт, чем 80 (например, 8080).

Будьте уверены, чтобы сделать следующие вещи: - создать временный каталог PREFIX/tmp - поместить php.ini в PREFIX/lib - редактировать php.ini и установить session.save_path в каталог только что созданного

В противном случае, ваши скрипты будут казаться to 'hang' на session_start().

+1

После перезагрузки не должно быть никаких блокировок, и `lsof` не показывал других запущенных скриптов PHP. Мы не изменили файл или длину энтропии. Путь к сеансу существует и записывается, поэтому C тоже не похоже. Мы перенесли проект на другой узел, который имеет идентичную конфигурацию, и он снова работает там. Спасибо за ответ, но это, похоже, не проблема. – dbemerlin 2010-12-02 09:22:04

3

У меня была странная проблема с этим.

Я использую CentOS 5.5x64, PHP 5.2.10-1. Чистый ANSI-файл в корне не содержит ничего, кроме session_start(). Сессия записывалась на диск и ошибок не возникало. Он просто висел.

Я попробовал весь предложенное Thariama, и проверил PHP компилировать настройки и т.д.

Моего Фикс:

yum reinstall php; /etc/init.d/httpd restart 

Надеется, что это поможет кому-то.

Для всех, кто жалуется на то, что 30 секунд простоя неприемлемы, это было необъяснимой проблемой для новой, чистой установки ОС, а не для запуска производственной машины. Это решение НЕ должно использоваться в производственной среде.

5

Если это помогает:

В моем сценарии, session_start() висит в то же время я использовал XDebug отладчик в PhpStorm, в среде IDE на Windows. Я обнаружил, что была явная причина: всякий раз, когда я убивал сеанс отладки из PHPStorm, в следующий раз, когда я попытался запустить сеанс отладки, session_start() зависает.

Решение, если это ваш сценарий, заключается в том, чтобы перезапустить Apache каждый раз, когда вы убиваете сессию XDebug в своей среде IDE.

2

Проблема: -

Iv испытал (и фиксировано) проблемы, когда сеансы на основе файлов зависание запроса, и сеансы базы данных на основе рассинхронизироваться, храня из данных Дата сеанса (например, хранение каждой сессии сохранить в неправильном порядке).

Это вызвано любым последующим запросом, который загружает сеанс (одновременные запросы), такие как ajax, видео встраивание, где видеофайл доставляется через php-скрипт, файл динамических ресурсов (например, скрипт или css), поставляемый с помощью php-скрипта и т. Д. .

В файловом сеансе блокировка файлов предотвращает запись сеанса, что приводит к взаимоблокировке между потоками одновременного запроса.

В сеансе, основанный на базе данных, последний запросный поток, который будет завершен, станет самым последним сохранением, так что, например, сценарий доставки видео будет завершен после запроса страницы и перезапишет обновленный сеанс старыми данными сеанса.

Исправление: -

Если Аякс или ресурс сценария доставки оленьей кожи необходимо использовать сессии, то проще просто удалить использование сеанса от него.

В противном случае вы бы лучше сделать себе кофе и сделать следующее: -

  1. Запись или использовать обработчик сеанса (если он уже не делает), как и на http://www.php.net//manual/en/class.sessionhandler.php (много других примеров, доступных через поиск Google) ,
  2. в сеансе функции обработчика записи() перед именем код ...

    // processes may declare their session as read only ... 
        if(!empty($_SESSION['no_session_write'])) { 
          unset($_SESSION['no_session_write']); 
          return true; 
        } 
    
  3. В вашем АЯКС или ресурсов доставки PHP скрипт добавить код (после начала сессии) ...

    $_SESSION['no_session_write'] = true; 
    

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

ПРИМЕЧАНИЕ. Если ваш сценарий загрузки ajax или ресурса действительно нужно записывать/сохранять данные, вам необходимо сделать это где-то, кроме сеанса, например базы данных.

0

Чтобы добавить другой ответ в микс для тех, кто собирается бананы, у меня был session_start(), умирающий только в отдельных случаях и скриптах. Причина, по которой моя сессия умирала, была, в конечном счете, потому, что я хранили лот данных в них после особо интенсивного сценария, и в конечном счете вызов session_start() исчерпывал настройку 'memory_limit' в php.ini.

После увеличения 'memory_limit' эти session_start() звонки больше не убивают мой скрипт.