2009-09-16 15 views
78

Если PHP Engine уже находится в середине выполнения скрипта на сервере, что произойдет с другими одновременными запросами браузера на тот же скрипт?Одновременные запросы к скрипту PHP

  • Будут ли очереди поставлены в очередь?
  • Будут ли они игнорироваться?
  • Будет ли каждый запрос иметь свой собственный сценарий экземпляр?
  • Любая другая возможность?
+1

Также проверьте этот ответ: http://konrness.com/php5/how-to-prevent-blocking-php-requests/ – trante

ответ

128

сервер, в зависимости от конфигурации, в общем случае может служить сотни запросов в то же время - при использовании Apache, параметр конфигурации MaxClients является одна поговорка:

MaxClients устанавливает предел на количество одновременных запросов, которые будут обслуживаться.
Любые попытки подключения к MaxClients предел обычно будет в очереди, до номера на основе ListenBacklog директива.
После того, как ребенок процесс освобождается в конце , запрос будет отправлен по запросу .


Тот факт, что две клиенты запрашивают та же страница не является проблемой.

Итак:

будут поставлены в очередь запросы?

Нет; за исключением случаев:

  • есть некоторые замок где-то - что может произойти, например, если два запросы поступают от одного клиента, и вы используете сессии на основе файлов в PHP: в то время как сценарий выполняется, сеанс «заблокирован», что означает, что сервер/клиент должен будет дождаться завершения первого запроса (и файл разблокирован), чтобы иметь возможность использовать этот файл для открытия сеанса для второго пользователь.
  • запросы поступают от одного и того же клиента и того же браузера; большинство браузеров будут останавливать запросы в этом случае, даже если на этом сервере ничего не происходит.
  • В настоящее время активных процессов более MaxClients - см. Цитату из руководства Apache как раз перед этим.


Будут ли они быть проигнорированы?

No: это будет означать, что только один пользователь может использовать веб-сайт одновременно; это было бы неплохо, не так ли?

Если бы это было так, я не смог бы опубликовать этот ответ, если вы, когда нажимаете F5 в тот же момент, чтобы посмотреть, кто-то ответил!
(Ну, SO не в PHP, но принципы остаются теми же)


Любая другая возможность?

Да ^^


редактировать после редактировал OP и комментарий:

Будет каждый запрос имеет свой собственный экземпляр сценария ?

Там нет такого понятия, как «экземпляра сценария»: просто положить, что происходит, когда запрос на скрипт выполнен является:

  • Вебсервер вилки другой процесс, чтобы обрабатывать запрос (часто по соображениям производительности эти вилки сделаны заранее, но это ничего не меняет)
  • процесс читает скрипт PHP с диска
    • несколько процессов могут сделать это в то же самое время: нет блокировки на чтение файла
    • файл загружается в память; в отдельном блоке памяти для каждого процесса
  • файл PHP в памяти «скомпилирован» в опкоды - до сих пор в памяти
  • этих опкоды выполняются - до сих пор из блока памяти, который принадлежит процесс ответа на ваш запрос


Действительно, вы можете иметь два пользователя, отправив запрос на тот же PHP скрипт (или в различных PHP скриптов, которые все содержат тот же PHP-файл); это определенно не проблема, или ни один из сайтов, на которых я когда-либо работал, не сработает!

+0

Если несколько одновременных запросов обращаются к одному и тому же файлу php, каков будет результат. будут ли остальные запросы сохранены в ожидании или каждый запрос будет иметь свой собственный экземпляр скрипта? –

+3

Нет такой вещи, как «экземпляр сценария»: каждый запрос обрабатывается отдельным процессом (или потоком) ;; сценарии считываются из памяти/диска, но один и тот же файл может быть прочитан из многих процессов одновременно без проблем (по крайней мере, на «современных» операционных системах, то есть как на Windows, так и на Linux) –

+0

Это отличный ответ , где можно узнать больше о том, как работает PHP? Любая хорошая книга для этого? –

2

Если вы используете очень нестандартную настройку, ваш веб-сервер (Apache, IIS, nginx и т. Д.) Будет иметь несколько процессов, которые запускают PHP отдельно для каждого запроса, поступающего на сервер. Одновременные запросы будут обслуживаться одновременно.

17

Если 2 клиента одновременно называют сервер, сервер, скорее всего, сможет ответить на оба клиента почти одновременно. Клиенты здесь я определяю их на уровне браузера.

Смысл сказать, что на том же компьютере, если вы используете 2 браузера для одновременного загрузки одного и того же веб-сайта/страницы, оба должны быть загружены одновременно.

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

Посмотрите на этот пример. Эти 2 файла загружаются из того же сеанса, что и тот же самый браузер.

 scripta.php requested     scripta.php served 
------+---+---------------------------------+------------------------> 
      scripta.php started 

       scriptb.php requested   scriptb.php started 
---------------+-------------------------------+-----------------+---> 
                   scriptb.php served. 

Обратите внимание, что scriptb.php запускается только после того, как scripta.php будет обслуживаться. это происходит потому, что, когда scripta.php запущен, файл сеанса заблокирован для других скриптов, так что scripta.php может записать файл сеанса. Когда scripta.php завершается, файл сеанса разблокируется, и, таким образом, другие скрипты могут его использовать. Таким образом scriptb.php будет ждать, пока файл сеанса будет освобожден, тогда он заблокирует файл сеанса и будет использовать его.

Этот процесс будет повторяться для предотвращения записи нескольких сценариев в один и тот же файл сеанса, что приведет к задержкам. Таким образом, рекомендуется звонить session_write_close(), когда вы больше не используете сеанс, особенно на веб-сайте, используя многие фреймы или AJAX.

+0

'session_write_close()' правильно, молодец! – TechNyquist

2

Просто наткнулся на это сам. В основном вам необходимо позвонить session_write_close(), чтобы предотвратить блокировку одного пользователя. Удостоверьтесь, что после того, как вы звоните session_write_close(), вы не пытаетесь и не изменяете никаких переменных сеанса. Как только вы его назовете, обрабатывайте сеансы как только для чтения с тех пор.

Смежные вопросы