2009-09-16 15 views
78

Jeśli silnik PHP jest już w trakcie wykonywania skryptu na serwerze, co stałoby się z innymi jednoczesnymi żądaniami przeglądarki do tego samego skryptu?Jednoczesne żądania skryptu PHP

  • Czy wnioski zostaną umieszczone w kolejce?
  • Czy zostaną one zignorowane?
  • Czy każde żądanie ma swój własny skrypt: instancja ?
  • Jakakolwiek inna możliwość?
+1

Sprawdź również tę odpowiedź: http://konrness.com/php5/how-to-prevent-blocking-php-requests/ – trante

Odpowiedz

128

serwerze, w zależności od konfiguracji, może generalnie służyć setki wniosków jednocześnie - w przypadku korzystania z serwera Apache, opcja Konfiguracja MaxClients jest jeden mówiąc:

Dyrektywa MaxClients ustala limit dla liczby równoczesnych żądań, które będą obsługiwane. Każda próba połączenia przez ponad limitem MaxClients będzie zwykle ustawiona w kolejce do liczby w oparciu o dyrektywę ListenBacklog .
Po zwolnieniu procesu podrzędnego pod koniec , połączenie zostanie przekazane do serwisu .


Fakt, że dwóch klientów żąda tej samej strony, nie stanowi problemu.

Więc:

będzie wnioski w kolejce?

Nie; z wyjątkiem gdy:

  • jest jakaś blokadagdzieś - co może się zdarzyć, na przykład, jeśli dwa wnioski pochodzą z tego samego klienta, a używasz sesje plików oparte na PHP: podczas gdy skrypt jest wykonywany, sesja jest "zablokowana", co oznacza, że ​​serwer/klient będzie musiał poczekać, aż zakończy się pierwsze żądanie (i odblokowany plik), aby móc użyć tego pliku do otwarcia sesji dla drugiego użytkownik.
  • żądania pochodzą od tego samego klienta ORAZ tej samej przeglądarki; większość przeglądarek będzie umieszczać w kolejce żądania w tym przypadku, nawet jeśli nie ma nic po stronie serwera produkującego to zachowanie.
  • Obecnie aktywnych jest więcej niż MaxClients - patrz cytat z podręcznika Apache tuż przed.


będą one ignorowane?

Nie: oznaczałoby to, że tylko jeden użytkownik może korzystać z witryny internetowej w tym samym czasie; to nie byłoby całkiem miłe, prawda?

Gdyby tak było, nie mógłbym opublikować tej odpowiedzi, jeśli uderzysz w F5 w tym samym momencie, aby sprawdzić, czy ktoś odpowie!
(dobrze, więc nie jest w PHP, ale zasady są takie same)


Każda inna możliwość?

Tak ^^


edycja po edycji OP i komentarz:

Czy każde żądanie mieć własny skrypt instancji?

Nie ma czegoś takiego jak „przykład skryptu”: umieścić po prostu, co się dzieje, gdy żądanie do skryptu składa się:

  • serwera WWW widelce inny proces do obsługi request (często z powodów związanych z wydajnością, te widełki są wykonywane z wyprzedzeniem, ale to nic nie zmienia)
  • proces odczytuje skrypt PHP z dysku
    • kilka procesów może to zrobić w tym samym czasie: nie ma zamek w aktach czytania
    • plik zostanie załadowany do pamięci; w odrębny blok pamięci dla każdego procesu
  • pliku PHP pamięci jest „zestawiane” do rozkazy - jeszcze w pamięci
  • te rozkazy są wykonywane - jeszcze z bloku pamięci należącej do proces odpowiadając na żądanie


Naprawdę, można mieć dwóch użytkowników wysyłając wniosek do tego samego skryptu PHP (lub do różnych skryptów PHP, że wszystkie zawierają ten sam plik PHP); to na pewno nie jest problem, albo żadna strona, na której pracowałem, nie zadziała!

+0

Jeśli wiele równoczesnych żądań uzyskuje dostęp do tego samego pliku php, jaki byłby wynik. czy inne żądania będą w toku, czy też każde żądanie będzie miało własną instancję skryptu? –

+3

Nie ma czegoś takiego jak "instancja skryptu": każde żądanie przetwarzane jest przez odrębny proces (lub wątek); skrypty są odczytywane z pamięci/dysku, ale ten sam plik można odczytać z wielu procesów jednocześnie bez problemu (przynajmniej w "nowoczesnych" systemach operacyjnych - tj. w systemach Windows i Linux) –

+0

To jest doskonała odpowiedź , gdzie mogę dowiedzieć się więcej o tym, jak działa PHP? Dobra książka do tego? –

2

Jeśli nie używasz bardzo niestandardowej konfiguracji, twój serwer WWW (Apache, IIS, nginx, itp.) Będzie miał wiele procesów, które uruchamiają PHP oddzielnie dla każdego żądania, które wchodzi na serwer. Jednoczesne żądania będą obsługiwane jednocześnie.

17

Jeśli dwóch klientów dzwoni do serwera w tym samym czasie, serwer najprawdopodobniej będzie w stanie odpowiedzieć obu klientom niemal jednocześnie. Klienci tutaj definiuję je na poziomie przeglądarki.

To znaczy, że na tej samej maszynie, jeśli używasz dwóch przeglądarek do załadowania tej samej witryny/strony w tym samym czasie, oba powinny być załadowane w tym samym czasie.

Jednak ponieważ mówimy o PHP, musisz wziąć specjalne uwagi na temat sesji. Jeśli strony korzystają z sesji, serwer obsługuje tylko jedną stronę naraz. Wynika to z tego, że plik sesji zostanie zablokowany, dopóki skrypt nie zostanie zamknięty.

Spójrz na ten przykład. Dwa pliki są ładowane z tej samej sesji, co ta sama przeglądarka, tego samego użytkownika.

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

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

Należy zauważyć, że skrypt scriptb.php jest uruchamiany dopiero po wyświetleniu pliku scripta.php. dzieje się tak, ponieważ po uruchomieniu scripta.php plik sesji jest zablokowany na inne skrypty, dzięki czemu scripta.php może zapisywać do pliku sesji. Gdy skrypt scripta.php zostanie ukończony, plik sesji zostanie odblokowany, a zatem inne skrypty będą mogły z niego korzystać. Dlatego skrypt scriptb.php będzie czekał, aż plik sesji zostanie zwolniony, a następnie zablokuje plik sesji i użyje go.

Ten proces będzie powtarzany, aby zapobiec wielokrotnemu zapisywaniu skryptów w tym samym pliku sesji, powodując opóźnienia. Dlatego zaleca się wywołanie session_write_close(), gdy nie używasz już sesji, szczególnie na stronie internetowej używającej wielu elementów iframe lub AJAX.

+0

'session_write_close()' dobrze, dobrze zrobione człowieku! – TechNyquist

2

Po prostu wpadłem na to sam. Zasadniczo musisz zadzwonić pod numer session_write_close(), aby zapobiec blokowaniu pojedynczego użytkownika. Upewnij się, że po wywołaniu session_write_close() nie próbuj modyfikować żadnych zmiennych sesji. Po wywołaniu traktuj sesje jako odtworzone tylko do odczytu.