session_start зависает

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

В целях тестирования я создал скрипт, который выглядит так:

<?php session_start(); ?> 

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

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

У меня кончились идеи, какие-то предложения?

ОБНОВИТЬ

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

Для этого есть много причин, вот несколько из них:

A. Файл сеанса можно открыть исключительно. Когда блокировка файла не выпущена должным образом по какой-либо причине, это приводит к тому, что session_start() бесконечно зависает при любых будущих сценариях сценария. Обход проблемы: используйте session_set_save_handler() и убедитесь, что функция write использует 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 в только что созданную директорию

В противном случае ваши скрипты будут «зависать» на session_start() .

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

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

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

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

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

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

Мой фикс:

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

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

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

Проблема : –

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

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

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

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

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

Если ваш сценарий для создания ajax или ресурса не требуется использовать сеансы, тогда проще всего просто удалить сеанс из него.

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

  1. Напишите или используйте обработчик сеанса (если он еще не выполняется) по http://www.php.net//manual/en/class.sessionhandler.php (многие другие примеры доступны через поиск Google).
  2. В вашей функции обработчика сеанса write () добавьте код …

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

      $_SESSION['no_session_write'] = true; 

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

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

Для меня проблема, похоже, возникла из SeLinux. Необходимая команда была chcon -R -t httpd_sys_content_t [www directory], чтобы предоставить доступ к правильному каталогу. См. https://askubuntu.com/questions/451922/apache-access-denied-because-search-permissions-are-missing

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

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