Подтвердить что ты не робот

Полностью понять PDO ATTR_PERSISTENT

Вопрос:

Каковы правила/логика управления постоянным подключением при использовании PDO?


Окружающая среда:

Веб-сервер

  • Windows 7 x64
  • Двухъядерный процессор с 16 ГБ оперативной памяти
  • Apache 2.2.17
  • PHP 5.3.5
  • Подключение по строке DSN с IP-адресом, портом, именем службы и т.д.
  • Нет ODBC для подключения к DB (пытались создать его на 2 часа, спасибо Oracle!)

Сервер БД

  • Oracle 10g в Linux
  • Многоядерный с 4 ГБ оперативной памяти
  • Имя пользователя, специально созданное для моего веб-приложения (да, это подделка)
    • пользователь: webuser

Мое понимание/наблюдения:

Непрерывные соединения

<?php

// Open a new connection
// Session created in Oracle
$dbh = new PDO('DSN', 'webuser', 'password');

// webuser is active in v$session with a SID=1

$dbh = NULL;

// webuser removed from v$session

// Manually calling $dbh = NULL; will remove the session from v$session
// OR
// Wait for script EOL so a kill-session command is sent to Oracle?

?>
  • Script надежно занимает ~.09 секунд для выполнения с накладными ресурсами фрейма и т.д.

Постоянные соединения

<?php

// Open a new connection and make it persistent
// Session created in Oracle
// Is Apache maintaining some sort of keep-alive with Oracle here?
// because I thought php.exe is only alive for the duration of the script
$dbh = new PDO('DSN', 'webuser', 'password', array(PDO::ATTR_PERSISTENT => TRUE));

// webuser is active in v$session with a SID=1

$dbh = NULL;

// webuser is still active in v$session with a SID=1

$dbh = new PDO('DSN', 'webuser', 'password', array(PDO::ATTR_PERSISTENT => TRUE));

// webuser is still active in v$session with a SID=1

// Manually calling $dbh = NULL; does not kill session
// OR
// Script EOL does not kill session
// ^^ this is good, just as expected

?>
  • Script занимает ~.12 секунд для выполнения при первом посещении с использованием служебных данных структуры и т.д.
  • Выполняется подсеквенция. ~.04

Проблема:

Я посещаю страницу, а webuser получает SID=1

Мой коллега посещает страницу и webuser получает дополнительный SID=2 < - rinse, repeat и increment SID для новых компьютеров, посещающих эту страницу

Не следует ли повторять использование нового посетителя SID=1?


Приветствуются все ответы, предложения, запросы на альтернативное тестирование, ссылки на материалы для чтения.

У меня есть RTFM'ed какое-то время, и Googling только создавал скудные блоги Advantages of Persistent vs. Non-persistent.

4b9b3361

Ответ 1

Точка зрения апачей

Apache имеет один родительский процесс. Этот процесс создает дочерние процессы, которые будут обрабатывать любые запросы, поступающие на веб-сервер. Начальное количество дочерних процессов, запущенных при запуске веб-сервера, настраивается директивой StartServers в конфигурации apache. Число увеличивается по мере необходимости с увеличением количества запросов, поражающих веб-сервер, до достижения ServerLimit.

PHP и постоянные соединения

Если PHP (запущенный как mod_php, поскольку CGI все ресурсы освобождены в конце выполнения script), теперь говорят, чтобы установить постоянное соединение с базой данных для запроса, это соединение сохраняется даже после script отделки. Соединение, которое теперь выполняется, представляет собой соединение между дочерним процессом apache, с которым был обработан запрос, и сервером базы данных и может быть повторно использован любым запросом, который обрабатывается этим точным дочерним процессом.

Если по какой-либо причине (не спрашивайте меня, почему именно) дочерний процесс занят дольше, чем фактический запрос, и приходит другой запрос, родительский процесс apache перенаправляет этот запрос на (новый) дочерний процесс, который может до этого времени не установил соединение с базой данных. Если это необходимо во время выполнения script, он вызывает SID, как вы это заметили. Теперь есть два соединения для двух разных дочерних процессов apache.

Имейте в виду, что...

Важно знать, что это также может вызвать массу проблем. Если существует бесконечный цикл или прерванная транзакция или какая-либо другая может быть даже непредсказуемой ошибкой во время выполнения script, соединение блокируется и не может быть повторно использовано. Также может случиться, что все доступные соединения базы данных используются, но есть еще один дочерний процесс сервера Apache, пытающийся получить доступ к базе данных. Этот процесс блокируется до тех пор, пока соединение не будет освобождено базой данных или apache (тайм-аут или добровольно по окончании). Дополнительная информация по этой теме на этой странице: http://www.php.net/manual/en/features.persistent-connections.php

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

Edit:

Я только что закончил читать статью @MonkeyZeus, упомянутую в этом комментарии. Он описывает процесс, который я обобщил выше, и предоставляет полезную информацию о том, как оптимизировать ваш сервер Apache для лучшей работы вместе с постоянными соединениями. Однако он может использоваться с бэкэндами базы данных oracle. Вы должны посмотреть: http://www.oracle.com/technetwork/articles/coggeshall-persist-084844.html

Ответ 2

PDO как-то смешно. Даже тот же пользователь/посетитель может создать второй или даже третий экземпляр. То же самое произошло со мной на моей локальной машине, проверяя производительность моих запросов db.

Это не о чем беспокоиться, потому что эти экземпляры рано или поздно истекут, точный тайм-аут зависит от конфигурации вашего сервера.

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