так как через несколько часов наш сервер зависает каждый раз, когда вы выполняете 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 или ресурса не требуется использовать сеансы, тогда проще всего просто удалить сеанс из него.
В противном случае вам лучше всего выпить кофе и сделать следующее: –
В вашей функции обработчика сеанса 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; }
В вашем 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()
больше не убивают мой скрипт.